How to use an I2C chip? (Adafruit MMA8451) #1897
Replies: 13 comments
-
Posted at 2022-10-08 by user149798 I would advise you to review the Espruino documentation on the I2C.writeTo function:
and also what the Adafruit writeRegister8 function does, namely pack the two arguments together and send them both to the device.
In short, your existing code appears to read and write from a variety of random device addresses, none of which have any corresponding I2C bus device apart from 29(0x1D). |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-08 by TheLogan Thank you for your reply :) What I am guessing so far, is that the _sensorID is set via "getSensor", which is called at some point, though as far as I can see it's not called in the code nor in the examples from Adafruit. I am assuming that
creates a new "Uint8Array" of length 2, and adds the reg on position 0 and the value on position 1? Then from what I can read
in js would be akin to
Is that correct? Not certain what to do with the 2 though. I tried changing my read/write calls to look like the following
I am still quite confused about how to do this then:
I attempted to write it like this
But I'm pretty sure that's wrong, I am getting changing values at least, but they seem random xD x_g 7.97021484375 y_g 6.5048828125 z_g 7.001953125 x_g 7.97607421875 y_g 4.25146484375 z_g 2 x_g 7.97607421875 y_g 7.7509765625 z_g 6 x_g 7.97607421875 y_g 4.0009765625 z_g 3.5 x_g 7.97607421875 y_g 4.7509765625 z_g 3.00048828125 x_g 7.97607421875 y_g 1.00146484375 z_g 4.5 x_g 7.97607421875 y_g 5.5009765625 z_g 4.75 x_g 7.97607421875 y_g 6.2509765625 z_g 0.5 x_g 7.9765625 y_g 6.7509765625 z_g 0 x_g 7.97607421875 y_g 7.2509765625 z_g 7.00048828125 x_g 7.97607421875 y_g 4.5009765625 z_g 7.00048828125 x_g 7.97607421875 y_g 0.5009765625 z_g 1.75048828125 x_g 7.97607421875 y_g 5.00048828125 z_g 6.75048828125 x_g 7.97607421875 y_g 0.0009765625 z_g 2.50048828125 x_g 7.97607421875 y_g 3.5009765625 z_g 0.75048828125 As you can see, despite laying on my desk, X is 7.976 all throughout while Y and Z are fluctuating, so I'm pretty sure I'm still doing something wrong, but I feel as though I'm closer at least :) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-08 by user149798 It's rather confusing, but as I understand it a 'device', and the i2c object in Arduino represents a single sensor(or whatever) that is connected to the i2c bus . Meanwhile, the 'device'/i2c object in Espruino is the i2c port on the Espruino board(it might have several). This means all calls to read and write on Arduino are automatically prefixed with the address, wheras on Espruino you have to supply the address in every function call. I would advise you to look at the function documentation and try to understand what is being done, instead of trying to translate every function argument from language 1 to language 2. If you review the function arguments of Your code sends the entire buffer plus a byte of value of '1' to the device, then reads 6 bytes into 'val2'. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-08 by TheLogan
I had no idea no. I've done C# and js/ts, but not much C or C++. What you write makes me think that I should do something like this
Where I then only send the value the "write_then_read" function sends, and then read 6 bytes from the same address, however the data I get out still seems wrong, here are 4 readings and again it's just lying on the table not moving.
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-08 by TheLogan I have rewritten my code and cleaned it up a bit, but it still gives the same values as in my previous post
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-10 by TheLogan I've noticed something.
After work I'll go back and look at the datasheet, but I am wondering if perhaps it just always sends the data in the array back in the same order, no matter what is sent to it. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-10 by TheLogan Lol ... so working on that theory, I changed the logIt function to look like this
Essentially I'm just ignoring the first byte of data and grabbing 1 extra, and now the data at least seems relatively stable, though I think it's the tilt of the sensor, but for some reason in a range between 0 and 8 o_0, but it really doesn't fit with how I've understood I2C to work. From what I understand you send a write, telling what you want from the device, when you call read the first data you get back is the data you requested. I am rather confused ... xD |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-10 by @gfwilliams The write...read pattern seems right. If you check out the libraries for some of the existing modules you'll see it's done in that way (http://www.espruino.com/I2C#using-i2c then you can usually go to a page a find a link to the module there). For instance in http://www.espruino.com/modules/VL53L0X.js there are two functions
What you might be missing is some chips only read properly if you do an I2C write and read without something called a "stop" between. You can force that my changing the address var to an object as in: http://www.espruino.com/Reference#l_I2C_writeTo In your case maybe:
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-10 by TheLogan Ah, thank you, I am still not getting the accelleration (.. I think), but I just had a breakthrough, by setting stop:false, I just ran the following piece of code.
What this is supposed to do is return the device's ID, 0x1A, and I got 26 back, which indeed is 0x1A, I feel like I am really close to cracking this, thank you :D |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-10 by TheLogan Ok, I can get a few things consistently from the sensor including the orientation, but I found this section:
In the documentation, I wonder if I'm getting "static acceleration" data rather than actual acceleration data, I'll have to dig more tomorrow, my brain at this point is mushy .. xD |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-12 by @gfwilliams
It could be... It might help to graph the data somehow when it's moving to see if it makes sense. Normally from an accelerometer you'd expect to have the value including gravity, so when you lie it flat on a surface one axis should be 1g and the others 0g (ish). Looks like you're not doing any checks for the sign of the value either, so it'd likely negative values will just show up as large positive numbers. It might be worth looking at some of Espruino's other accelerometer modules to see how that gets handled usually. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-12 by TheLogan I am not sure how I would go about graphing it, I am running it on a pico via VS Code. And as you wrote it is showing one value as 1 and the other 2 as zero, so it seems to be the acceleration + gravity. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-12 by TheLogan Just want to post that I finally got something that works, while filtering out the gravity, I am not sure what I did, but I'll clean up my code tomorrow and figure it out xD |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-10-07 by TheLogan
I've never written stuff for I2C or other protocols, but I have an MMA8451 chip on a breakout board from Adafruit. To my knowledge, there isn't an Espruino library for it, so I've looked at the one provided for Arduino by Adafruit and tried to write one in Espruino, but I'm not getting the expected results and I am rather confused about what I am even doing .. xD
So quickly a few links:
This is the Adafruit guide that I used to hook it up
https://learn.adafruit.com/adafruit-mma8451-accelerometer-breakout/overview
This is the datasheet
https://cdn-shop.adafruit.com/datasheets/MMA8451Q-1.pdf
This is the header file for the Adafruit library
https://github.com/adafruit/Adafruit_MMA8451_Library/blob/master/Adafruit_MMA8451.h
And this is the actual code for the library
https://github.com/adafruit/Adafruit_MMA8451_Library/blob/master/Adafruit_MMA8451.cpp
Also, I am not proficient in C++, so I've been googling and guessing my way through trying to convert it.
This is my code, it's in typescript but gets transpiled into JS that the board understands :)
So one thing I am noticing right off the bat is that I never actually use the address of the chip (0x1D), but the Adafruit code also only uses two places, which aren't called in the code xD
If I run "runSensor" then I get 48 lines printed out that all look like this:
index 28 new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255])
Except for one that looks like this:
index 29 new Uint8Array([0, 41, 252, 163, 200, 152, 160, 0, 41, 252, 163, 200, 152, 160, 0, 41])
But that line doesn't change no matter how much I move the sensor around
And if I run "logIt"
I get the following data:
x_g 0.03125 y_g 0 z_g 0
val1 undefined
val2 new Uint8Array([255, 255, 255, 255, 255, 255])
buffer new Uint8Array([1, 0, 0, 0, 0, 0])
Again it's identical no matter how much I move the sensor around.
If I unplug the sensor, then line 29 in the array becomes an array of 255 like the others, however, the "logIt" still pumps out the same data.
Can anyone help me with this? :)
Beta Was this translation helpful? Give feedback.
All reactions