Learn Using a Gyroscope/Accelerometer module over i2C with RNBO on the RPi

Getting Started

Welcome to RNBO

Quickstart

RNBO Basics

Key Differences

Why We Made RNBO

Coding Resources

Fundamentals

Audio IO

Messages to rnbo~

Using Parameters

MIDI in RNBO

Messages and Ports

Polyphony and Voice Control

Audio Files in RNBO

Using Buffers

Using the FFT

Export Targets

Export Targets Overview

VST/AudioUnit
Max External Target
Raspberry Pi Target
The Web Export Target
The C++ Source Code Target

Code Export

Working with JavaScript
Working with C++

Special Topics

Sample Accurate Patching
Scala and Custom Tuning

RNBO and Max for Live

RNBO Raspberry Pi OSCQuery Runner

Metadata

Export Description

Raspberry Pi GPIO

Working with Photoresistors (LDRs) on the Raspberry Pi with RNBO

Adding Potentiometers to your Raspberry Pi with RNBO

Light up some LEDs with RNBO on the Raspberry Pi

Using a Gyroscope/Accelerometer module over i2C with RNBO on the RPi

Updating the RNBO Package

Using a Gyroscope/Accelerometer module over I2C with RNBO on the RPi

In this article we'll use an MPU-6050 module with the i2c protocol and get it talking to some parameters in our RNBO patcher on the Raspberry Pi.

An Inertial Measurement Unit (IMU) is a common module to use with microcontrollers for measuring tilt and rotation. They're small and are perfect for use in wearable technology and robotics projects. The MPU-6050 module is a common and inexpensive IMU that uses the I2C protocol to communicate.

NOTE: This article is intended as a guide to help you extend the use of the RPi. Though the information here is accurate and correct, when working with electronics there is always the risk of damaging your device or components. While the voltage in the RPi is low enough not to pose any threat to your physical safety, the device itself could be damaged. Cycling 74 cannot be held responsible for any damages resulting from attempts to complete the following project. We also cannot provide technical support for RPi beyond basic setup of the image and loading RNBO patchers. Please proceed with caution and at your own risk.
Before attempting this tutorial, make sure you’re already familiar with the basics of exporting your RNBO patchers to the RPi and that your audio interface is working correctly with it.

Things you'll need:

  • An MPU6050 module
  • Hook up wires

We'll start by exporting the following patcher to the Raspberry Pi target:​

ssh in, or connect up a keyboard and monitor. To make things simple we'll utilise a Python module that performs all of the communication and processing. Install it using the following terminal commands:

$ sudo apt install python3-pip python3-smbus 
$ pip install mpu6050-raspberrypi

You'll likely already have python3-smbus already, but it doesn't hurt to check. We'll also need  an OSC module for communicating with the runner via OSC. You can use any OSC library you like, this example will use pyliblo3.

$ sudo apt install liblo-dev
$ pip install pyliblo3

Now we'll need to enable i2c on the RPi. sudo raspi-config will bring up the config menu. Select "Interfacing Options" and then "i2c". Enable it, then when prompted select "No" for rebooting your RPi. We're going to power off the RPi and connect up our module. Exit the config menu without rebooting then at the terminal:

$ sudo poweroff

It's a good idea to only make connections to the RPi when powered off. Wait about 10 seconds then remove the power cable. These inline power switches can be pretty handy.

Connecting the module

Now connect up the MPU6050 like so:

  1. 3.3v (red) from the RPi connects to the VCC on the module
  2. GND (black)  from the RPi connects to the GND on the module
  3. SCL (yellow) from the RPi to the SCL on the module
  4. SDA (orange) from the RPi to the SDA on the module

With this all connected up, power on the RPi. Once it's booted, we can check if the module is connected and available using this terminal command:

$ i2cdetect -y 1

You should see the following, which shows the module's address in hexadecimal (0x68).

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

If your module isn't showing up, you can try these two commands to disable then reenable the I2C driver without rebooting:

$ sudo rmmod i2c_dev
$ sudo modprobe i2c_dev

Let's create a python script to run that will communicate with the RNBO runner and the module. Run this command to open up the `nano` editor and paste in the following script.

$ nano RNBO_MPU6050.py
from mpu6050 import mpu6050
from time import sleep
import liblo as OSC
import sys

# send all messages to port 1234 on the local machine
try:
    target = OSC.Address(1234)
except OSC.AddressError as err:
    print(err)    
    sys.exit()# start the transport via OSC

sensor = mpu6050(0x68)

try:
    while True:
    	accel_data = sensor.get_accel_data()
        gyro_data = sensor.get_gyro_data()
        temp = sensor.get_temp()
        
        OSC.send(target, "/rnbo/inst/0/params/harmonicity/normalized", abs(accel_data["x"]) / 9.80665)
        OSC.send(target, "/rnbo/inst/0/params/mod_index/normalized", abs(accel_data["y"] / 9.80665)
        OSC.send(target, "/rnbo/inst/0/params/cutoff/normalized", abs(accel_data["z"] / 9.80665)print("Accelerometer data")print("x", accel_data["x"], "y", accel_data["y"], "z", accel_data["z"])print("Gyroscope data")print("x", gyro_data["x"], "y", gyro_data["y"], "z", gyro_data["z"])print("Temp:", temp, " Celcius")
        sleep(0.1)
        print("\033c", end="") #wipe screen

except KeyboardInterrupt:
    print("Exiting cleanly...")

In this example script we're only using values from the Accelerometer data to read the tilt angle of the module and assign them to the parameters. We're dividing the absolute value of each reading by 9.80665 (the approximate, average acceleration of gravity in metres per second, squared) to get a normalized value between 0 ... 1 to use with each parameter. This means the parameter will be at the minimum value when the sensor is placed flat - and move to the end of the parameter range when the  sensor is tilted in either direction.

Instead of abs() you could divide the sensor value by 9.80665, add 1 then divide by 2 to map the entire tilt range to the parameter range, if you want to control the sound by tilting the module all the way around.

Running the script

To run the python script:

$ python RNBO_MPU6050.py

You should see the sensor values on the screen. The patcher needs a MIDI note to trigger a sound, you can use the Raspberry Pi Web Interface to trigger a MIDI note from your browser if you don't have a MIDI controller connected. Don't forget to adjust the gain in the parameter menu first!

Materials in this article

  • SimpleFM_Mod.maxpat