Daniel Sam
03/14/2023, 3:32 AM#include<Wire.h>
const int MPU = 0x68;
float AccX, AccY, AccZ;
void setup() {
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(MPU);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Wire.beginTransmission(MPU);
Wire.write(0x1C);
Wire.write(0b00011000); //scale factor +/-16g
Wire.endTransmission();
}
loop(){
Wire.beginTransmission(MPU);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU, 14, true); // Solicita os dados ao sensor
AccX = Wire.read() << 8 | Wire.read(); //0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AccY = Wire.read() << 8 | Wire.read(); //0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AccZ = Wire.read() << 8 | Wire.read(); //0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Serial.print(AccX / 2048);
Serial.print(" ");
Serial.print(AccY / 2048);
Serial.print(" ");
Serial.println(AccZ / 2048);
}
i have already started making the porting to toit, and i am stuck in this:
import gpio
import i2c
MPU9250_ADDRESS := 0x68
ACCEL_CONFIG_REG := 0x1C
main:
bus := i2c.Bus
--sda=gpio.Pin 21
--scl=gpio.Pin 22
device := bus.device MPU9250_ADDRESS
can any one help me to finish this code in toit?floitsch
03/14/2023, 3:22 PMbus :=
and device :=
). This will make the syntax highlighter happier.
The --sda=
can then be intended by 4.
Small warning: I haven't tested any of the code I posted here. Let me know if something doesn't seem correct or doesn't work.
The first thing the code does is to set the 0x1C register.
If you look at the register map (which, for some reason, is not in the data sheet) you can see that 0x1C is the ACCEL_CONFIG register (as you correctly stated with your constant): https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf
(Side-note: for constants, like MPU9250_ADDRESS
and ACCEL_CONFIG_REG
, prefer ::=
instead of :=
. That just means that the variables are final and can't be changed).
It sets the value 0b00011000
. According to the register map, this means that AFS_SEL is set to 0b11. On page 15 (Register 28), it explains that this means that the accelerometer reads values in the whole 16g range. This means that it might be a bit less precise, but can handle stronger accelerations. You could change it to 0b00000000
for more precise measurements. In that case you will need to change the constant to go from raw value to acceleration value later in the code, though.
To write to an i2c register you would use the following code:
registers := device.registers
registers.write_u8 ACCEL_CONFIG_REG 0b00011000
floitsch
03/14/2023, 3:22 PMACCEL_XOUT_H ::= 0x3B
ACCEL_XOUT_L ::= 0x3C
ACCEL_YOUT_H ::= 0x3D
ACCEL_YOUT_L ::= 0x3E
ACCEL_ZOUT_H ::= 0x3F
ACCEL_ZOUT_L ::= 0x40
// Read 6 bytes in one go:
accel_data := registers.read_bytes ACCEL_XOUT_H 6
accel_x := accel_data[0] << 8 | accel_data[1]
accel_y := accel_data[2] << 8 | accel_data[3]
accel_z := accel_data[4] << 8 | accel_data[5]
or
// Read each value independently:
accel_x := registers.read_i16_be ACCEL_XOUT_H_
accel_y := registers.read_i16_be ACCEL_YOUT_H_
accel_z := registers.read_i16_be ACCEL_ZOUT_H_
Note that we use read_i16_be
which basically means: "read an integer with 16 bits, in big-endian format". And "big-endian" means that the big part (that is, most significant, or high part) is first.
If you look at the description of these registers (page 29) you can see that the obtained value's meaning depends ot the AFS_SEL that we set in the configuration. With the highest precision (when setting the config-register to 0), the value must be divided by 16384. With the lowest accuracy (but highest range), it must be divided by 2048 (as you do in your code).
You can then start a loop:
while true:
accel_x := registers.read_i16_be ACCEL_XOUT_H_
accel_y := registers.read_i16_be ACCEL_YOUT_H_
accel_z := registers.read_i16_be ACCEL_ZOUT_H_
print "x: $(accel_x / 2048)"
print "y: $(accel_y / 2048)"
print "z: $(accel_z / 2048)"
sleep --ms=1_000
floitsch
03/14/2023, 3:23 PMfloitsch
03/14/2023, 3:23 PMfloitsch
03/14/2023, 3:23 PMI2C_ADDRESS
seems to be the same.floitsch
03/14/2023, 3:24 PMDaniel Sam
03/14/2023, 3:42 PMDaniel Sam
03/17/2023, 1:41 PMconstructor dev/serial.Device:
reg_ = dev.registers
tries := 5
while whoami != 0x71: // Here was the change, on MPU6886 was expected 0x19, but on MPU6050 is 0x71
tries--
print whoami
if tries == 0: throw "INVALID_CHIP"
sleep --ms=1
floitsch
03/17/2023, 1:42 PMmpu6xxx
package that knows about these differences.Daniel Sam
03/17/2023, 1:46 PMfloitsch
03/17/2023, 2:06 PMfloitsch
03/17/2023, 2:10 PMfloitsch
03/17/2023, 2:14 PMfloitsch
03/17/2023, 2:27 PMDaniel Sam
03/17/2023, 3:09 PMDaniel Sam
03/17/2023, 3:10 PMfloitsch
03/17/2023, 4:27 PMDaniel Sam
03/17/2023, 5:12 PM