B4R Code Snippet Read a Nunchuk using I2C with B4R an ESP8266

KiloBravo

Member
Licensed User
Nothing spectacular the code just reads and logs the joystick x & y axis, the 2 buttons (Z&C), the 3 axis accelerometer data, as well as the calibration data. It works on the OEMs and Knock Offs if you lower the clock speed as indicated. I just ported some Arduino Code to B4R from the website listed in the code. It might save you a few minutes if you ever need to use a Nunchuk. It worked for me. The Websites have all the gory details. I listed a few in the comments, so hopefully you could tell what I was doing and why.

B4X:
'https://www.xarg.org/2016/12/using-a-wii-nunchuk-with-arduino/ **** ported the code from this site 'by Robert Eisele to B4r.
'https://github.com/infusion/Fritzing/tree/master/Nunchuk  <<< Also used his repository on GitHub.

' I2C Bus Esp8266
'
' D1 is GPI05 SCL  
' D2 is GPI04 SDA
'
' SPI Bus
' D5 GPI014 SCK
' D6 GPI012 MISO
' D7 GPI013 MOSI
' D8 GPI015 Chp Select SS

Sub Process_Globals
    Public Serial1 As Serial
    Public Master As WireMaster
    Public bc As ByteConverter
    Public NUNCHUK_ADDRESS As Byte = 0x52
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Master.Initialize
    Log(CRLF)
    RunNative("SetWireClock", 100000) '100khz ***OEM Nunchuk worked with 400Khz. 
'The Knock Off only worked at 100Khz
    Log(CRLF)
'***************************************************************
    Init
    Read_Ident
    Read_Cali
    Read_Data
    Log("All Done... Exiting...", CRLF)
'***************************************************************

End Sub

Private Sub Init
    'The new way To initialize the extension is by writing 0x55 To 0x(4)A400F0, Then writing 0x00 To 0x(4)A400FB.
    'This Sequence turns off Data Encryption on the Wii Nunchuk
    Master.WriteTo2(NUNCHUK_ADDRESS, True, Array As Byte(0xF0, 0x55))
    Master.WriteTo2(NUNCHUK_ADDRESS, True, Array As Byte(0xFB, 0x00))
End Sub

Private Sub Read_Ident
'    Read the device ident from extension register:
'    START, 0xFA, STOP
'    READ 6 byte
    Master.WriteTo2(NUNCHUK_ADDRESS, True, Array As Byte(0xFA))
    Dim c() As Byte = Master.RequestFrom(NUNCHUK_ADDRESS, 6)
    Log("Device Ident: ", bc.HexFromBytes(c), CRLF)
'*****************************************************************
End Sub

Private Sub Read_Data
'    Read measurements from the device:
'    START, 0x00, STOP
'    READ 6 byte
    Master.WriteTo2(NUNCHUK_ADDRESS, True, Array As Byte(0x00))
    Dim data() As Byte = Master.RequestFrom(NUNCHUK_ADDRESS, 6)
    Log("Device Position Data: ", bc.HexFromBytes(data),CRLF)
'******************************************************************
    Dim Z_butt As Byte = Bit.Get(data(5),0)
    If Z_butt = 0 Then
        Log("Z Button Pressed: ", Z_butt ,CRLF)
    Else
        Log("Z Button Released: ", Z_butt , CRLF)
    End If
'**************************************************************
    Dim C_butt As Byte = Bit.Get(data(5),1)
    If C_butt = 0 Then
        Log("C Button Pressed: ", C_butt , CRLF)
    Else
        Log("C Button Released: ", C_butt , CRLF)
    End If
'***************************************************************
    Log("y-Axis: ", data(1), CRLF)
    Log("x-Axis: ", data(0), CRLF)
    '***************************************************************
'    * Retrieves the raw X-value of the accelerometer
    Log("Top 8 Bits of ACC X:", data(2), CRLF)
    Log("Bottom 2 Bits of ACC X:", data(5), CRLF)
    Log("Conversion of Bits to Uint", CRLF)
'    Return ((uint16_t) nunchuk_data[2] << 2) | ((nunchuk_data[5] >> 2) & 3);
    Dim X_acc_raw As Int = Bit.Or(Bit.ShiftLeft(data(2),2),Bit.And(Bit.ShiftRight(data(5),2),3))
    Log("Raw ACC X:", X_acc_raw, CRLF)
            
    
    Log("Top 8 Bits of ACC Y:", data(3), CRLF)
    Log("Bottom 2 Bits of ACC Y:", data(5), CRLF)
    Log("Conversion of Bits to Uint", CRLF)
    Dim Y_acc_raw As Int = Bit.Or(Bit.ShiftLeft(data(3),2),Bit.And(Bit.ShiftRight(data(5),4),3))
    Log("Raw ACC Y:", Y_acc_raw, CRLF)

    
    Log("Top 8 Bits of ACC Z:", data(4), CRLF)
    Log("Bottom 2 Bits of ACC Z:", data(5), CRLF)
    Log("Conversion of Bits to Uint", CRLF)
    Dim Z_acc_raw As Int = Bit.Or(Bit.ShiftLeft(data(4),2),Bit.And(Bit.ShiftRight(data(5),6),3))
    Log("Raw ACC Z:", Z_acc_raw, CRLF)

End Sub

Private Sub Read_Cali
    '***************************************************************
'    Read actual calibration data from the device:
'    START, 0x20, STOP
    ''    READ 16byte
    Master.WriteTo2(NUNCHUK_ADDRESS, True, Array As Byte(0x20))
    Dim cali() As Byte = Master.RequestFrom(NUNCHUK_ADDRESS, 16)
    Log("Device Calibration Data: ", bc.HexFromBytes(cali),  CRLF)
    '***************************************************************
    Log("X-Axis Max: ", cali(8), CRLF)
    Log("X-Axis Min: ", cali(9), CRLF)
    Log("X-Axis Cntr: ", cali(10),  CRLF)
    '***************************************************************
    Log("Y-Axis Max: ", cali(11), CRLF)
    Log("Y-Axis Min: ", cali(12), CRLF)
    Log("Y-Axis Cntr: ", cali(13),  CRLF)
    '***************************************************************
'    Log("Top 8 Bits of Cali_Acc0G X:", cali(0), CRLF)
'    Log("Bottom 2 Bits of Cali_Acc0G X:", cali(3), CRLF)
    Log("Conversion of Bits to Uint X Acc 0G: ", CRLF)
    Dim X_cali_Acc0G_raw As Int = Bit.Or(Bit.ShiftLeft(cali(0),2),Bit.And(Bit.ShiftRight(cali(3),2),3))
    Log("Raw Cali Acc0G X: ", X_cali_Acc0G_raw, CRLF)           
    '*********************************************************************************
'    Log("Top 8 Bits of Cali_Acc0G Y:", cali(1), CRLF)
'    Log("Bottom 2 Bits of Cali_Acc0G Y:", cali(3), CRLF)
    Log("Conversion of Bits to Uint Acc 0G: ", CRLF)
    Dim Y_cali_Acc0G_raw As Int = Bit.Or(Bit.ShiftLeft(cali(1),2),Bit.And(Bit.ShiftRight(cali(3),4),3))
    Log("Raw Cali Acc0G Y:", Y_cali_Acc0G_raw, CRLF)
    '**********************************************************************************
'    Log("Top 8 Bits of Cali_Acc0G Z:", cali(2), CRLF)
'    Log("Bottom 2 Bits of Cali_Acc0G Z:", cali(3), CRLF)
    Log("Conversion of Bits to Uint Acc 0G: ", CRLF)
    Dim Z_cali_Acc0G_raw As Int = Bit.Or(Bit.ShiftLeft(cali(2),2),Bit.And(Bit.ShiftRight(cali(3),6),3))
    Log("Raw Cali Acc0G Z:", Z_cali_Acc0G_raw, CRLF)
    '**********************************************************************************

'    Log("Top 8 Bits of Cali_Acc1G X:", cali(4), CRLF)
'    Log("Bottom 2 Bits of Cali_Acc1G X:", cali(7), CRLF)
    Log("Conversion of Bits to Uint Acc 0G: ", CRLF)
    Dim X_cali_Acc1G_raw As Int = Bit.Or(Bit.ShiftLeft(cali(4),2),Bit.And(Bit.ShiftRight(cali(7),2),3))
    Log("Raw Cali Acc1G X(711):", X_cali_Acc1G_raw, CRLF)
    '**********************************************************************************
'    Log("Top 8 Bits of Cali_Acc1G Y:", cali(5), CRLF)
'    Log("Bottom 2 Bits of Cali_Acc1G Y:", cali(7), CRLF)
    Log("Conversion of Bits to Uint Acc 0G: ", CRLF)
    Dim Y_cali_Acc1G_raw As Int = Bit.Or(Bit.ShiftLeft(cali(5),2),Bit.And(Bit.ShiftRight(cali(7),4),3))
    Log("Raw Cali Acc1G Y(735):", Y_cali_Acc1G_raw, CRLF)
    '**********************************************************************************
'    Log("Top 8 Bits of Cali_Acc1G Z:", cali(6), CRLF)
'    Log("Bottom 2 Bits of Cali_Acc1G Z:", cali(7), CRLF)
    Log("Conversion of Bits to Uint Acc 0G: ", CRLF)
    Dim Z_cali_Acc1G_raw As Int = Bit.Or(Bit.ShiftLeft(cali(6),2),Bit.And(Bit.ShiftRight(cali(7),6),3))
    Log("Raw Cali Acc1G Z(732):", Z_cali_Acc1G_raw, CRLF)
    '**********************************************************************************
End Sub

#if C
void SetWireClock(B4R::Object* o) {
   Wire.setClock (o->toULong());
}
#end if
 
Top