B4R Tutorial Connecting two Arduinos with rWire library

Erel

Administrator
Staff member
Licensed User


The rWire supports communication with other I2C/TWI devices.

One device acts as the master and the other devices act as slaves.
Each slave has a unique address between 8 to 127.

You can see the relevant pins here: https://www.arduino.cc/en/Reference/Wire

The master can send data to any slave. The slaves prepare data for the master.

In this example we connect two Arduinos. The master will read the state of the the button which is connected to the slave board.

You can run two instances of B4R. One for the slave and one for the master.

This is the slave code:
B4X:
Sub Process_Globals
   Public Serial1 As Serial
   Private slave As WireSlave
   Private btn As Pin
   Private const SLAVE_ADDRESS As Byte = 8
End Sub

Private Sub AppStart
   Serial1.Initialize(115200)
   Log("AppStart")
   slave.Initialize(SLAVE_ADDRESS, "Slave_NewData")
   btn.Initialize(btn.A0, btn.MODE_INPUT_PULLUP)
   btn.AddListener("Btn_StateChanged")
End Sub

Sub Btn_StateChanged (State As Boolean)
   Dim b(1) As Byte
   'It will be False when button is down
   If State Then b(0) = 0 Else b(0) = 1
   slave.SetDataForMaster(b) '<-- it will only be read when the master calls RequestFrom
End Sub

Sub Slave_NewData (Data() As Byte)
   Log("Received from master: ", Data)
End Sub
The master code:
B4X:
Sub Process_Globals
   Public Serial1 As Serial
   Private timer1 As Timer
   Private master As WireMaster
   Private const SLAVE_ADDRESS As Byte = 8
   Private led13 As Pin
End Sub

Private Sub AppStart
   Serial1.Initialize(115200)
   Log("AppStart")
   master.Initialize
   led13.Initialize(13, led13.MODE_OUTPUT)
   led13.DigitalWrite(True)
   timer1.Initialize("Timer1_Tick", 10)
   timer1.Enabled = True
End Sub

Sub Timer1_Tick
   master.WriteTo(SLAVE_ADDRESS, NumberFormat(Millis, 0, 0).GetBytes)
   Dim b() As Byte = master.RequestFrom(SLAVE_ADDRESS, 1)
   If b.Length = 1 Then
     Dim state As Boolean
     If b(0) = 0 Then state = False Else state = True
     led13.DigitalWrite(state)
   End If
End Sub
 

janderkan

Active Member
Licensed User
In the Master code you have

B4X:
Dim b() As Byte = master.RequestFrom(SLAVE_ADDRESS, 1)
   If b.Length = 1 Then
but if you request 1 byte, 1 byte is always received so no need to test the length.
Is this an error or is there a way to set

B4X:
slave.SetDataForMaster(NULL) '<-- it will only be read when the master calls RequestFrom
 

janderkan

Active Member
Licensed User
There is no harm in testing the returned array length.
Problem is:
If you request 4 bytes, 4 bytes are returned. Even if only 1 byte are sent.
So the length of the returned bytes are always the same as the requested length.
 

janderkan

Active Member
Licensed User
I don't see any problem here.
Documentation say:
This will return the data prepared by the slave with the call to SetDataForMaster.
Note that the returned array length might be smaller than the requested length.

Problem is that it always return the requested length, even if the prepared data are smaller.

If you prepare 1 byte (0x20) and you request 4 bytes, function returns 4 bytes (0x20,0xff,0xff,0xff)
 
Top