Avatar for TheLogan

TheLogan

Member since May 2022 • Last active Nov 2022
  • 4 conversations
  • 41 comments

Most recent activity

  • in Electronics
    Avatar for 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

  • in Electronics
    Avatar for TheLogan

    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 :)

  • in Electronics
    Avatar for TheLogan

    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 :)

  • in Electronics
    Avatar for 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.

    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

  • in Electronics
    Avatar for TheLogan

    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

  • in Electronics
    Avatar for TheLogan

    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_CTR­L_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.

  • in Electronics
    Avatar for TheLogan

    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_CTR­L_REG2, 0x40)// reset
    
        setTimeout(() => {
          this.begin2();
        }, 500);
      }
    
      begin2() {
        this.writeRegister8(0x0E, 0b01); // enable 4G range
        this.writeRegister8(this.MMA8451_REG_CTR­L_REG2, 0x02); // High res
    
        // DRDY on INT1
        this.writeRegister8(this.MMA8451_REG_CTR­L_REG4, 0x01);
        this.writeRegister8(this.MMA8451_REG_CTR­L_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_CTR­L_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);
      }
    }
    
  • in Electronics
    Avatar for TheLogan

    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])
    
  • in Electronics
    Avatar for TheLogan

    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 :)

Actions