Most recent activity
-
I am not sure how I would go about graphing it, I am running it on a pico via VS Code.
However, I tried printing out a continuous stream of x,y and z values, and I can see a bump in the correct direction when I move the sensor around.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.
I found a few implementations of the code in JS but for raspberry pi etc, and I can't see how they handle filtering out the gravity, but I'll keep on digging, I'll also look at how Espruino handles other accelerometers, thank you :) -
Ok, I can get a few things consistently from the sensor including the orientation, but I found this section:
Many applications use the accelerometer’s static acceleration readings (i.e., tilt) which measure the change in acceleration
due to gravity only. These functions benefit from acceleration data being filtered with a low-pass filter where high frequency data is
considered noise.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
Thanks for your help both of you :) -
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.
I2C1.writeTo({ address: 0x1D, stop: false }, 0x0D);I2C1.readFrom(0x1D, 1);
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
-
Lol ... so working on that theory, I changed the logIt function to look like this
logIt() { this.i2c.writeTo(this.MMA8451_ADDR, this.MMA8451_REG_OUT_X_MSB); let buffer = this.i2c.readFrom(this.MMA8451_ADDR, 7); let x = buffer[1]; x <<= 8; x |= buffer[2]; x >>= 2; let y = buffer[3]; y <<= 8; y |= buffer[4]; y >>= 2; let z = buffer[5]; z <<= 8; z |= buffer[6]; z >>= 2; const divider = 2048; let x_g = x / divider; let y_g = y / divider; let z_g = z / divider; console.log('x_g', x_g, 'y_g', y_g, 'z_g', z_g); console.log('buffer', buffer); }
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
-
I've noticed something.
Other implementations of read take a registry variable, and then write to that registry first and then read the first byte from the device, but after a lot of testing it seems that the first byte here is always either 0 or 255
The device sets that byte from 0 to 255 when this is called:// Activate at max rate, low noise mode this.writeRegister8(this.MMA8451_REG_CTRL_REG1, 0x01 | 0x04);
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.
-
I have rewritten my code and cleaned it up a bit, but it still gives the same values as in my previous post
export default class MMA8451 { // @ts-ignore i2c: I2C = new I2C(); MMA8451_ADDR = 0x1D; MMA8451_REG_OUT_X_MSB = 0x01 //!< Read-only device output register MMA8451_REG_PL_CFG = 0x11 //!< Portrait/landscape configuration register MMA8451_REG_CTRL_REG1 = 0x2A //!< CTRL_REG1 system control 1 register MMA8451_REG_CTRL_REG2 = 0x2B //!< CTRL_REG2 system control 2 register MMA8451_REG_CTRL_REG4 = 0x2D //!< CTRL_REG4 system control 4 register MMA8451_REG_CTRL_REG5 = 0x2E //!< CTRL_REG5 system control 5 register writeRegister8(reg: number, value: number) { this.i2c.writeTo(this.MMA8451_ADDR, [reg, value]); } readRegister8(reg: number) { this.i2c.writeTo(this.MMA8451_ADDR, reg); return this.i2c.readFrom(this.MMA8451_ADDR, 1)[0]; } begin() { // @ts-ignore this.i2c.setup({ scl: B6, sda: B7 }); this.writeRegister8(this.MMA8451_REG_CTRL_REG2, 0x40)// reset setTimeout(() => { this.begin2(); }, 500); } begin2() { this.writeRegister8(0x0E, 0b01); // enable 4G range this.writeRegister8(this.MMA8451_REG_CTRL_REG2, 0x02); // High res // DRDY on INT1 this.writeRegister8(this.MMA8451_REG_CTRL_REG4, 0x01); this.writeRegister8(this.MMA8451_REG_CTRL_REG5, 0x01); // Turn on orientation config this.writeRegister8(this.MMA8451_REG_PL_CFG, 0x40); // Activate at max rate, low noise mode this.writeRegister8(this.MMA8451_REG_CTRL_REG1, 0x01 | 0x04); } logIt() { this.i2c.writeTo(this.MMA8451_ADDR, this.MMA8451_REG_OUT_X_MSB); let buffer = this.i2c.readFrom(this.MMA8451_ADDR, 6); let x = buffer[0]; x <<= 8; x |= buffer[1]; x >>= 2; let y = buffer[2]; y <<= 8; y |= buffer[3]; y >>= 2; let z = buffer[4]; z <<= 8; z |= buffer[5]; z >>= 2; const divider = 2048; let x_g = x / divider; let y_g = y / divider; let z_g = z / divider; console.log('x_g', x_g, 'y_g', y_g, 'z_g', z_g); console.log('buffer', buffer); } }
-
Perhaps you are not aware of this, but in C/C++, arrays do not know their own size(an 'array' variable is actually just the memory address of the first entry) so the size must always be supplied separately.
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
this.i2c.writeTo(this.MMA8451_ADDR, this.MMA8451_REG_OUT_X_MSB); let buffer = this.i2c.readFrom(this.MMA8451_ADDR, 6);
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.
x_g 7.9755859375 y_g 2.25146484375 z_g 5.50146484375 buffer new Uint8Array([255, 59, 72, 13, 176, 12]) x_g 7.9755859375 y_g 0.50146484375 z_g 4.75146484375 buffer new Uint8Array([255, 59, 16, 13, 152, 12]) x_g 7.9755859375 y_g 4.75146484375 z_g 3.75146484375 buffer new Uint8Array([255, 59, 152, 14, 120, 12]) x_g 7.9755859375 y_g 1.00146484375 z_g 6.25146484375 buffer new Uint8Array([255, 59, 32, 13, 200, 12])
-
Thank you for your reply :)
After reading and thinking I tried rewriting all of my read and write calls, though I am still quite confused over exactly what the "writeRegister" function actually does.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.
From then on it's automagically inserted in the write function called by writeRegister8?I am assuming that
uint8_t buffer[2] = {reg, value}
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
i2c_dev.write(buffer,2)
in js would be akin to
this.i2c.writeTo(0x1D, [reg, val])
Is that correct? Not certain what to do with the 2 though.
I tried changing my read/write calls to look like the following
this.i2c.writeTo(this.MMA8451_ADDR, [this.MMA8451_REG_CTRL_REG2, 0x02]);
I am still quite confused about how to do this then:
i2c_dev->write_then_read(buffer, 1, buffer, 6);
I attempted to write it like this
let buffer = new Uint8Array([this.MMA8451_REG_OUT_X_MSB, 0, 0, 0, 0, 0]); this.i2c.writeTo(this.MMA8451_ADDR, [buffer, 1]); let val2 = this.i2c.readFrom(this.MMA8451_ADDR, 6);
But I'm pretty sure that's wrong, I am getting changing values at least, but they seem random xD
I just had the chip laying on my desk and ran "logIt" a few times in row, and got these values.x_g 7.97021484375 y_g 6.5048828125 z_g 7.001953125
val2 new Uint8Array([255, 15, 208, 41, 224, 17])x_g 7.97607421875 y_g 4.25146484375 z_g 2
val2 new Uint8Array([255, 61, 136, 12, 64, 3])x_g 7.97607421875 y_g 7.7509765625 z_g 6
val2 new Uint8Array([255, 60, 248, 11, 192, 3])x_g 7.97607421875 y_g 4.0009765625 z_g 3.5
val2 new Uint8Array([255, 63, 128, 11, 112, 3])x_g 7.97607421875 y_g 4.7509765625 z_g 3.00048828125
val2 new Uint8Array([255, 62, 152, 11, 96, 4])x_g 7.97607421875 y_g 1.00146484375 z_g 4.5
val2 new Uint8Array([255, 63, 32, 12, 144, 3])x_g 7.97607421875 y_g 5.5009765625 z_g 4.75
val2 new Uint8Array([255, 62, 176, 9, 152, 3])x_g 7.97607421875 y_g 6.2509765625 z_g 0.5
val2 new Uint8Array([255, 63, 200, 11, 16, 3])x_g 7.9765625 y_g 6.7509765625 z_g 0
val2 new Uint8Array([255, 64, 216, 11, 0, 3])x_g 7.97607421875 y_g 7.2509765625 z_g 7.00048828125
val2 new Uint8Array([255, 61, 232, 8, 224, 4])x_g 7.97607421875 y_g 4.5009765625 z_g 7.00048828125
val2 new Uint8Array([255, 62, 144, 9, 224, 4])x_g 7.97607421875 y_g 0.5009765625 z_g 1.75048828125
val2 new Uint8Array([255, 63, 16, 9, 56, 4])x_g 7.97607421875 y_g 5.00048828125 z_g 6.75048828125
val2 new Uint8Array([255, 62, 160, 7, 216, 4])x_g 7.97607421875 y_g 0.0009765625 z_g 2.50048828125
val2 new Uint8Array([255, 63, 0, 8, 80, 5])x_g 7.97607421875 y_g 3.5009765625 z_g 0.75048828125
val2 new Uint8Array([255, 63, 112, 9, 24, 4])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 :)
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