• 0
CharlesS

A gift: Working sensor script for MPU-6050/GY-521

Question

Note To Staff
There is no need for help here; I just wanted to share this with others, since it was useful to me. As far as I'm concerned (have power to say?), this code, text, graphics, and attachments are all public domain (preferably with attribution). If there is a specific area or protocol for these sorts of things, I haven't seen it. This post and contents could be stickied, moved, and otherwise used as the powers that be see fit. If there is something wrong, something that needs changed, or something the needs clarified, feel free.
/Note To Staff

Hello all. I have a small gift for anyone that wants it.:D

The following is working javascript for GY-521 breakout boards, which holds the venerable InvenSense MPU-6050 6 axis IMU chips.

// -UNOFFICIAL SCRIPT- -AS IS- -NOT ENDORSED BY DIGILENT- -USE AT OWN RISK-
// Author: Charles Scoville
//
// GY-521 breakout board: InvenSense MPU-6050 i2C Gryo + accelerometer
// Set clock = 400kHz: Rate up to 400Hz (more may work): Itterations ~1k

const adr = 0x68; // 0x69 is an alternate address.

function initialize(){
    if(Clear()!=true) return "I2C bus error. Check the pull-ups.";
    if(Write(adr)!=true) return "Device NAK";
    //if(Read(adr, 0x75, 1) != 0x68) return "Device ID mismatch"; *FIXME* Read() bug? Does NOT actually return 0x68
    if(Write(adr, 0x6B, 0x03)!=0) return "Communication error";  // REG: PWR_MGMT_1 (Z gyro as clock source)
    if(Write(adr, 0x23, 0x78)!=0) return "Communication error";  // REG: FIFO_EN (FIFO only for Gyros and accelerometer)
    if(Write(adr, 0x6A, 0x45)!=0) return "Communication error";  // REG: USER_CTRL (Reset FIFO and signal paths for all sensors)
    if(!FileWriteLine("~/Desktop/default.csv", ["temp", "ACCEL_XOUT", "ACCEL_YOUT", "ACCEL_ZOUT", "GYRO_XOUT", "GYRO_YOUT", "GYRO_ZOUT"])) return "File write failed - init";
    return true;
}

function loop(){
    var rg = Read(adr, 0x3B, 14); // DATA

    var xa = ((rg[0]<<24) | (rg[1]<<16)) /256/256;
    var ya = ((rg[2]<<24) | (rg[3]<<16)) /256/256;
    var za = ((rg[4]<<24) | (rg[5]<<16)) /256/256;

    // NOTE: REG 0x23 must be written as 0xF8 for temp to be buffered
    var tmp = ((rg[6]<<24) | (rg[7]<<16)) /256/256/340 + 36.53; //temp (deg C)
    //tmp = tmp * 1.8 + 32; //temp (deg F)
    
    var xg = ((rg[8]<<24) | (rg[9]<<16)) /256/256;
    var yg = ((rg[10]<<24) | (rg[11]<<16)) /256/256;
    var zg = ((rg[12]<<24) | (rg[13]<<16)) /256/256;

    if(!FileAppendLine("~/Desktop/default.csv", [tmp, xa, ya, za, xg, yg, zg])) return "File write failed - loop";
    return true;
}

function finish(){
    return "done";
}


This script is to be used in the "protocol>i2c>sensor" section of the WaveForms application. I have only run this on the Electronics Explorer, I have no idea if it even applies to anything else. The results when run (with a GY-521 attached, of course!) are a CSV file on your desktop, just as with the PMOD gyro or accelerator example code it was based on.

For this data capture to make much sense, you will most likely want to graph the columns in the resulting file. I did so for the accelerometer and gyrometer as independent groups, as that provides the most informative and expected form for the data.

The following are some graphs of a couple of my more interesting captures, as examples. They were made with LibreOffice 6.0 directly from the CSV files. The ods files are also attached. (Embedded malware is thoroughly unlikely, but you still open at your own risk.)

This one was just me picking it up and turning it all around. It's a nice shot because it's pretty obvious when I picked it up, and what exactly I did.
5a9c1a1505bc7_MPU-6050_AccelGyro-graph1.thumb.png.bc988d30b9a7f66aec32ee15ecdaed69.png

This one was of me lifting the board up onto one corner, rapidly twisting it back and forth, then just setting it down. This one clearly has more samples too.
5a9c1a679cbad_MPU-6050_AccelGyro-graph2.thumb.png.b22fe7dfc352cbd8895dea68dcdfe807.png


Anyway, thanks for reading. I hope this post has value to you.

 

MPU-6050 readout1.ods

MPU-6050 readout2.ods

Edited by CharlesS

Share this post


Link to post
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Hi @CharlesS

Thank you for sharing this.

The I2C Read function returns an array. In your code you should add indexing for ID verification, like this:
if(Read(adr, 0x75, 1)[0] != 0x68) return "Device ID mismatch";

Share this post


Link to post
Share on other sites
  • 0
Quote

The I2C Read function returns an array. In your code you should add indexing for ID verification, like this:
if(Read(adr, 0x75, 1)[0] != 0x68) return "Device ID mismatch";

Oh! So that's the issue. Good to know. Guess I'm too accustomed to plain ol' regular C, where functions only return one value.

Incidentally, my incorrect scheme was derived directly from the example script built into WaveForms. e.g. look at the "Pmod GYRO - L3G4200D" sensor script under "protocol>i2C" (Using WaveForms Version: 3.7.5 64-bit)

On a tangential note, It would be really cool if there was a comprehensive guide for the javascript API. The inbuilt help is... well... "lacking" to say the least.

Anyway, thanks for looking at this and thanks for the catch. I'll try and fix the posted script sometime soon.

Share this post


Link to post
Share on other sites
  • 0

Hi @CharlesS

No offense, but the I2C/Read function is in the help, default comments, insert in the custom tab and examples.

Read( address, count of bytes ): Returns the read bytes array from the specified address.
Read( address, [sub address byte1, byte2...], count of bytes ): Returns the read bytes array from the specified deice address and sub-address using repeated start.

image.png.c96a7b95d8022b009f6a2c18ddf48806.png

// Pmod CDC1 - AD7156

const address = 0x48;

if(Clear()!=true) return "I2C bus error. Check the pull-ups.";
if(Write(address)!=true) return "Device NAK";

for(var i = 0; i < 100 && wait(0.1); i++){
    // Read(I2C address, sub address, count of bytes)
    var status = Read(address, 0, 2);
    if(status[0] & 0x08) return "Button 1 touched";
    if(status[0] & 0x20) return "Button 2 touched";
}
return "No button pressed";

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now