Situational awareness in terms of positional information is a nice way of interaction with an electronic consumer product.
The GY-521 is a breakout board for the MPU6050 chip. The latter one consists of a three axis gyroscope and a three axis accelerometer. That’s why it’s often referred to as six axis MEMS motion tracking device.
It’s a dirt cheap piece of hardware offering enough functionality for our purpose. It has got a bigger sister, namely the MPU9250 which adds a three axis magnetometer to the pack. This IC comes optionally with a BMP280 barometer making it a ten DOF sensor board. The alternatives probably have a similar form factor and pin configuration making them interchangeable with the MPU6050 that I use for my setup. I don’t have one at home to try which makes it a potential collateral shopping item the next time I order something.
Speaking of pin configuration, the MPU6050 uses I²C and offers some additional handy features. It comes with an integrated 3.3V regulator accepting a power source supplying a voltage between 3V and 5V. The SCL and SDA pins are the most important ones. Connect them to your I²C bus (data and clock) and you’re good to go. The breakout board also gives you the option to choose the I²C address of the device (0x68 or 0x69 chosen by pulling AD0 to high or low). That means you may hook up two of the devices onto the same bus and just choose different addresses. XDA and XCL are auxiliary I²C pins offering a master mode where you could hook up other sensors to the device. The chip can be configured so that it informs you about free fall events or if a motion exceeds a user given threshold. I connected the corresponding INT pin to a free RPi GPIO pin, although I haven’t tried out these features yet. If you want to find out about them, checkout one of the many tutorials you find online.
Given all the information, the only important pins right now are power and I²C (SDA, SCL). Afterwards it’s just a question of protocol. If you really wanna find out, how I²C works with all of its ‘interesting’ history, take the red pill and start by checking out wiki. Or just take the blue pill, hook up many sensors to one bus, use all the given tools and libraries to speak to them bidirectionally without knowing everything under the hood. I personally recommend the purple pill (get things done while still understanding the concepts and implementations to a certain degree).
In order to get the device working on our Raspberry Pi we need to make sure, that the I²C interface is activated.
pi@raspberrypi $ sudo raspi-config
Choose 5 Interfacing Options, then P5 I2C and select Yes to enable the I²C interface.
Reboot the Pi, install i2c-tools and then list all devices talking on the I²C bus. The gyroscope and accelerometer should be listed as device 0x68. According to the register map it can be asked for its own ID by reading register 0x75.
pi@raspberrypi $ sudo reboot now pi@raspberrypi $ sudo apt-get install i2c-tools pi@raspberrypi $ sudo i2cdetect -y 1 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: -- -- -- -- -- -- -- -- pi@raspberrypi $ sudo i2cget -y 1 0x68 0x75 0x68
We seem to have a working connection to the MPU6050 device via I²C. The next thing we wanna do is to listen and process some sensor values. We therefore install the python bindings for smbus and execute the example program. While running the script, move around Marta. Tilting the box a little bit should give you new readings.
pi@raspberrypi $ sudo apt-get install python-smbus pi@raspberrypi $ python /home/pi/mmm/marta/MPU.py 20:03:53.683 | MPU | enter to start, enter to quit 20:03:55.295 | MPU | rot=-0.175398726642, -1.89209085984 20:03:55.801 | MPU | rot=-0.164991339361, -1.98567070316 20:03:56.306 | MPU | rot=-0.23347755203, -2.05030141628 20:03:56.812 | MPU | rot=-11.4903480114, 5.60234908967 20:03:57.318 | MPU | rot=-14.4501047576, 36.8208827559 20:03:57.823 | MPU | rot=28.614476234, 21.4476474138 20:03:58.328 | MPU | rot=45.6248632617, 0.443719531172 20:03:58.833 | MPU | rot=9.10083269617, -44.6344144833 20:03:59.339 | MPU | rot=-40.3245705396, -41.515035158 20:03:59.844 | MPU | rot=-49.0160325842, -21.1636250787 20:04:00.349 | MPU | rot=-36.8401914285, 2.01833432572 20:04:00.854 | MPU | rot=-13.5310287022, 23.5829160855 20:04:01.359 | MPU | rot=-59.1037519865, 26.5635126665 20:04:01.865 | MPU | rot=-66.0528671151, -1.09285385472 20:04:02.370 | MPU | rot=-46.4044311996, -5.77738670624 20:04:02.876 | MPU | rot=-22.2043785881, 7.47819291561 20:04:03.381 | MPU | rot=-2.65516396929, 15.8173929606 20:04:03.886 | MPU | rot=0.683751072326, 1.04105583081 20:04:04.392 | MPU | rot=3.5658195963, -2.38033468395 20:04:04.897 | MPU | rot=1.02350285886, -1.04360968148 20:04:05.311 | MPU | MPU terminating... 20:04:05.317 | MPU | waiting for mpu thread. 20:04:05.320 | MPU | terminated while reading average rotation 20:04:05.326 | MPU | return value None -> stop 20:04:05.333 | MPU | ok, finished.