B4R Question ESP8266 (NodeMcu) and I2C for MPU-6050

peacemaker

Expert
Licensed User
HI, All

Dummy first questions, pardon in advance: searching forum second day and cannot find any way to use the subject.
If no ready lib for MPU-6050 at ESP8266 (this one is only for Arduino PCBs, as i can understand)- how to use generic I2C code to work with MPU-6050 ? Any example ?
 

Erel

Administrator
Staff member
Licensed User
Two relevant links:
Code that you need to port: https://www.electronicwings.com/nodemcu/mpu6050-interfacing-with-nodemcu

Another option is to use inline C with the code. It does require some C knowledge.
 

peacemaker

Expert
Licensed User
THANKS MUCH ! Ohh, how hard is to search the forum ... :( - it's my fault to search somehow crooked
 
Last edited:

peacemaker

Expert
Licensed User
Semi-finally, the working example is assembled:
B4X:
'Used https://www.b4x.com/android/forum/threads/inertial-measurements-mpu-6050-and-magnetometer-hmc5883l.65917/post-417358
'Used https://www.electronicwings.com/nodemcu/mpu6050-interfacing-with-nodemcu
'Used https://www.mschoeffler.de/2017/10/05/tutorial-how-to-use-the-gy-521-module-mpu-6050-breakout-board-with-the-arduino-uno/

'v.0.1

' I2C Bus Esp8266:
' D1 is GPI05 to MPU6050 SCL
' D2 is GPI04 to MPU6050 SDA


Sub Process_Globals
    Public Serial1 As Serial
    Public MPU6050SlaveAddress As Byte = 0x68    'I2C address of the MPU-6050. If AD0 pin is set to HIGH, the I2C address will be 0x69.

    Private wire As WireMaster
    Private raf As RandomAccessFile
    Private AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ As Float
    Private tmr As Timer
  
    Public const MPU6050_REGISTER_SMPLRT_DIV   =  0x19 As Byte
    Public const MPU6050_REGISTER_USER_CTRL    =  0x6A As Byte
    Public const MPU6050_REGISTER_PWR_MGMT_1   =  0x6B As Byte
    Public const MPU6050_REGISTER_PWR_MGMT_2   =  0x6C As Byte
    Public const MPU6050_REGISTER_CONFIG       =  0x1A As Byte
    Public const MPU6050_REGISTER_GYRO_CONFIG  =  0x1B As Byte
    Public const MPU6050_REGISTER_ACCEL_CONFIG =  0x1C As Byte
    Public const MPU6050_REGISTER_FIFO_EN      =  0x23 As Byte
    Public const MPU6050_REGISTER_INT_ENABLE   =  0x38 As Byte
    Public const MPU6050_REGISTER_ACCEL_XOUT_H =  0x3B As Byte
    Public const MPU6050_REGISTER_SIGNAL_PATH_RESET  = 0x68 As Byte
  
    Public const AccelScaleFactor = 16384 As UInt   'sensitivity scale factor respective To full scale setting provided in datasheet
    Public const GyroScaleFactor = 131 As UInt
End Sub

Public Sub AppStart
    Serial1.Initialize(115200)
    wire.Initialize
    Setup_MPU6050
    tmr.Initialize("tmr_tick", 3000)
    tmr.Enabled = True
End Sub

Sub Setup_MPU6050
    wire.WriteTo(MPU6050SlaveAddress, Array As Byte(MPU6050_REGISTER_SMPLRT_DIV, 0x07))
    wire.WriteTo(MPU6050SlaveAddress, Array As Byte(MPU6050_REGISTER_PWR_MGMT_1, 0x01))
    wire.WriteTo(MPU6050SlaveAddress, Array As Byte(MPU6050_REGISTER_PWR_MGMT_2, 0x00))
    wire.WriteTo(MPU6050SlaveAddress, Array As Byte(MPU6050_REGISTER_CONFIG, 0x00))
    wire.WriteTo(MPU6050SlaveAddress, Array As Byte(MPU6050_REGISTER_GYRO_CONFIG, 0x00))    'set +/-250 degree/second full scale
    wire.WriteTo(MPU6050SlaveAddress, Array As Byte(MPU6050_REGISTER_ACCEL_CONFIG, 0x00))    'set +/- 2g full scale
    wire.WriteTo(MPU6050SlaveAddress, Array As Byte(MPU6050_REGISTER_FIFO_EN, 0x00))
    wire.WriteTo(MPU6050SlaveAddress, Array As Byte(MPU6050_REGISTER_INT_ENABLE, 0x01))        'needed ?
    wire.WriteTo(MPU6050SlaveAddress, Array As Byte(MPU6050_REGISTER_SIGNAL_PATH_RESET, 0x00))
    wire.WriteTo(MPU6050SlaveAddress, Array As Byte(MPU6050_REGISTER_USER_CTRL, 0x00))
End Sub

Sub tmr_tick
    wire.WriteTo(MPU6050SlaveAddress, Array As Byte(MPU6050_REGISTER_ACCEL_XOUT_H))
    Dim b() As Byte = wire.RequestFrom(MPU6050SlaveAddress, 14)    '14 bytes data range
    If b.Length = 14 Then
        raf.Initialize(b,False)
        AcX  = raf.ReadInt16(raf.CurrentPosition) / AccelScaleFactor    'reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
        AcY  = raf.ReadInt16(raf.CurrentPosition) / AccelScaleFactor    'reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
        AcZ  = raf.ReadInt16(raf.CurrentPosition) / AccelScaleFactor    'reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
        Tmp  = raf.ReadInt16(raf.CurrentPosition) / 340.00 + 36.53        'reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
        GyX  = raf.ReadInt16(raf.CurrentPosition) / GyroScaleFactor        'reading registers: 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
        GyY  = raf.ReadInt16(raf.CurrentPosition) / GyroScaleFactor        'reading registers: 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
        GyZ  = raf.ReadInt16(raf.CurrentPosition) / GyroScaleFactor        'reading registers: 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)
      
        Log("acx: ", AcX , ", acy: ", AcY ," ,acz: ", AcZ,", Tmp: ",NumberFormat(Tmp,1,1) , ", GyX: ", GyX , ", GyY: ", GyY ," ,GyZz: ", GyZ)
    Else
        Log("Missing sensors data...")
    End If
End Sub
It needs to think about Setup registers.
But strange that Y-axle data is not changed (always is the max value of 2g), X, Z and temperature look OK.
B4X:
acx: 0.2239, acy: 1.9999 ,acz: -0.8865, Tmp: 29.3, GyX: -1.2824, GyY: 5.8168 ,GyZz: -0.7557
acx: 0.2246, acy: 1.9999 ,acz: -0.8853, Tmp: 29.3, GyX: -1.4580, GyY: 5.8931 ,GyZz: -0.7634
acx: 0.2432, acy: 1.9999 ,acz: -0.8831, Tmp: 29.3, GyX: -1.3053, GyY: 6.1527 ,GyZz: -0.1145
acx: 0.2341, acy: 1.9999 ,acz: -0.8696, Tmp: 29.3, GyX: -1.7939, GyY: 5.7939 ,GyZz: -0.8702
acx: 0.2229, acy: 1.9999 ,acz: -0.8684, Tmp: 29.3, GyX: -1.0382, GyY: 6.2290 ,GyZz: -0.6336
acx: 0.2236, acy: 1.9999 ,acz: -0.8872, Tmp: 29.3, GyX: -1.8168, GyY: 6.2443 ,GyZz: -0.7786
acx: 0.2400, acy: 1.9999 ,acz: -0.8901, Tmp: 29.3, GyX: -1.6794, GyY: 3.9160 ,GyZz: -1.1679
acx: 0.2249, acy: 1.9999 ,acz: -0.8772, Tmp: 29.3, GyX: -1.0763, GyY: 6.0153 ,GyZz: -0.4427
acx: 0.2412, acy: 1.9999 ,acz: -0.8799, Tmp: 29.3, GyX: -1.3740, GyY: 6.0687 ,GyZz: -0.6031
acx: 0.2190, acy: 1.9999 ,acz: -0.8809, Tmp: 29.3, GyX: -1.4275, GyY: 5.4122 ,GyZz: -0.8321
acx: 0.2207, acy: 1.9999 ,acz: -0.8789, Tmp: 29.3, GyX: -2.3282, GyY: 6.0458 ,GyZz: -0.6336
acx: 0.2268, acy: 1.9999 ,acz: -0.8794, Tmp: 29.3, GyX: -1.5191, GyY: 5.7328 ,GyZz: -0.6794
acx: 0.2246, acy: 1.9999 ,acz: -0.8750, Tmp: 29.3, GyX: -1.6183, GyY: 6.0992 ,GyZz: -0.3053
acx: 0.2646, acy: 1.9999 ,acz: -0.8706, Tmp: 29.3, GyX: 1.4351, GyY: 6.9313 ,GyZz: -0.0076
acx: 0.2129, acy: 1.9999 ,acz: -0.8848, Tmp: 29.3, GyX: -1.6565, GyY: 6.2672 ,GyZz: -0.8550
acx: 0.2346, acy: 1.9999 ,acz: -0.8430, Tmp: 29.3, GyX: -0.4809, GyY: 5.7176 ,GyZz: -1.1069
acx: 0.2380, acy: 1.9999 ,acz: -0.8767, Tmp: 29.3, GyX: -2.0305, GyY: 6.0534 ,GyZz: -0.8779
acx: 0.2339, acy: 1.9999 ,acz: -0.8652, Tmp: 29.2, GyX: -2.5725, GyY: 6.0076 ,GyZz: -0.6794
acx: 0.2202, acy: 1.9999 ,acz: -0.8833, Tmp: 29.3, GyX: -3.2824, GyY: 6.1527 ,GyZz: -0.8092
acx: 0.2283, acy: 1.9999 ,acz: -0.8701, Tmp: 29.3, GyX: -2.1450, GyY: 6.5573 ,GyZz: -0.3053
acx: 0.2410, acy: 1.9999 ,acz: -0.8760, Tmp: 29.3, GyX: -1.3359, GyY: 5.8015 ,GyZz: -0.4504
acx: 0.2195, acy: 1.9999 ,acz: -0.8774, Tmp: 29.3, GyX: -0.7710, GyY: 5.8397 ,GyZz: -0.8168
acx: 0.2307, acy: 1.9999 ,acz: -0.8950, Tmp: 29.3, GyX: -0.0153, GyY: 4.7328 ,GyZz: -1.6336
acx: 0.2043, acy: 1.9999 ,acz: -0.8801, Tmp: 29.3, GyX: -1.5038, GyY: 5.8550 ,GyZz: -0.5878
acx: 0.2053, acy: 1.9999 ,acz: -0.8799, Tmp: 29.3, GyX: -1.2061, GyY: 5.7863 ,GyZz: -0.9008
acx: 0.2278, acy: 1.9999 ,acz: -0.8772, Tmp: 29.3, GyX: -1, GyY: 5.5649 ,GyZz: -0.9847
acx: 0.2310, acy: 1.9999 ,acz: -0.8733, Tmp: 29.3, GyX: -1.3664, GyY: 6.1145 ,GyZz: -0.5267
acx: 0.2214, acy: 1.9999 ,acz: -0.8796, Tmp: 29.2, GyX: -1.1603, GyY: 6.0611 ,GyZz: -0.8015
Anyone seen such "partially defective" data from MPU6050 ?
 
Last edited:

peacemaker

Expert
Licensed User
But strange that Y-axle data is not changed (always is the max value of 2g), X, Z and temperature look OK.
Note: that MPU6050 chipset can be defective: one of my 3 pcs always returns AcY=1.9999 g, but all other parameters are "live", and 2 others NodeMcu PCBs are fully OK.
 
Top