Fundamentals
Export Targets
Code Export
Patcher UI
Special Topics
RNBO Raspberry Pi OSCQuery Runner
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:
3.3v
(red) from the RPi connects to theVCC
on the moduleGND
(black) from the RPi connects to theGND
on the moduleSCL
(yellow) from the RPi to theSCL
on the moduleSDA
(orange) from the RPi to theSDA
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