B4R Library RF24 - nRF24L01 radio modules

SS-2016-05-17_13.21.18.jpg


This library wraps RF24 open source project: http://tmrh20.github.io/RF24/ (GPL license).

With this library it is simple to transmit or receive small packets between two or more Arduinos using nRF24L01+ radio modules.

Wiring:

VkpaI.jpg



1 - Ground
2 - 3.3 volt.
3 - CE pin. Any available pin (7 in the next example)
4 - CSN pin. Any available pin (8 in the next example)
5 - SCK pin. Uno - 13, Mega - 52 (other boards: https://www.arduino.cc/en/reference/SPI)
6 - MOSI pin. Uno - 11, Mega - 51
7 - MISO pin. Uno - 12, Mega - 50
8 - Not connected



Code:

- Initialize the RF24 object and set the CE and CSN pins.
- Set the reading and writing addresses.
- Handle the NewData event.

The maximum packet size is 32 bytes. The length of the array passed in the NewData event will always be 32. It will be padded with zeroes after the actual data.

Example of connecting an Uno and Mega. The Uno sends its current millis value every second. The Mega sends the button state.

B4X:
'UNO
Sub Process_Globals
   Public Serial1 As Serial
   Private rf24 As RF24
   Private raf As RandomAccessFile
   Private timer1 As Timer
   Private led As Pin
   Private const MEGA = 1, UNO = 2 As Byte
   Private buffer(4) As Byte
End Sub

Private Sub AppStart
   Serial1.Initialize(115200)
   Log("AppStart")
   rf24.Initialize(7, 8, "rf24_NewData")
   rf24.OpenReadingPipe(UNO)
   rf24.OpenWritingPipe(MEGA)
   timer1.Initialize("timer1_Tick", 1000)
   timer1.Enabled = True
   led.Initialize(2, led.MODE_OUTPUT) 'connect led to pin #2
   raf.Initialize(buffer, True)
End Sub

Sub rf24_NewData (Data() As Byte)
   led.DigitalWrite(Data(0) = 1)
End Sub

Sub Timer1_Tick
   raf.WriteULong32(Millis, 0)
   rf24.Write(buffer)
End Sub

B4X:
'MEGA
Sub Process_Globals
   Public Serial1 As Serial
   Private rf24 As RF24
   Private btn As Pin
   Private const MEGA = 1, UNO = 2 As Byte
   Private raf As RandomAccessFile
End Sub

Private Sub AppStart
   Serial1.Initialize(115200)
   Log("AppStart")
   rf24.Initialize(7, 8, "rf24_NewData")
   rf24.OpenReadingPipe(MEGA)
   rf24.OpenWritingPipe(UNO)
   btn.Initialize(2, btn.MODE_INPUT_PULLUP) 'button connected to pin #2.
   btn.AddListener("btn_StateChanged")
End Sub

Sub btn_StateChanged (State As Boolean)
   Dim b As Byte
   If Not(State) Then b = 1 Else b = 0
   Log("Write result: ", rf24.Write(Array As Byte(b)))
End Sub

Sub rf24_NewData (Data() As Byte)
   raf.Initialize(Data, True)
   Log("UNO Millis: ", raf.ReadULong32(raf.CurrentPosition))
End Sub
 

Attachments

  • rRF24.zip
    34.9 KB · Views: 998
Last edited:

rwblinn

Well-Known Member
Licensed User
Longtime User
In the attachment post #1 there is no xml file for the library.

Have created using b4rh2xml tool. Find attached.
 

Attachments

  • rRF24.xml
    2.2 KB · Views: 834
Last edited:

George Anifantakis

Member
Licensed User
Longtime User
Hi,
Is there any example to stream audio using for example tv out audio signal as input to this module and use an android phone to receive the audio. Actually create a wireless headset using the android mobile.
 

Beja

Expert
Licensed User
Longtime User
Hi Erel,
Thanks for this very important library and tutorial.
The connections are not so clear to me, so would you please add illustrative diagram or schematics, like the one in the button tutorial?
Thanks in advance.
 

Beja

Expert
Licensed User
Longtime User
Another quick question.
I have Uno so should I buy a Mega or another Uno is ok.. my app wouldn't need more power or memory than Uno.
If I wanted to use more than 2 UNOs in a network then how can I address individual UNO? is there a mac or IP address?

Thanks in advance.
 

Cableguy

Expert
Licensed User
Longtime User
I don't think there's an IP or Mac address on these boards... they are simple radios... so I would hard code an identifier to each "node" (uno + rf combo) and in each broadcasted message include the destination identifier
 

rwblinn

Well-Known Member
Licensed User
Longtime User
Addition to @Cableguy suggestion, a possible example attached of communication between two "RF24 Arduinos", one called client, the other gateway.
And below an outline how this could be extended to handle more - in the example the gateway is handling communication.

In the example each Arduino has an ID defined in the globals:
B4X:
Private const GATEWAY = 1, CLIENT = 2 As Byte
The client opens the pipes as:
B4X:
rf24.OpenReadingPipe(CLIENT)
rf24.OpenWritingPipe(GATEWAY)
EXTEND OPTION:
If there is more then one client, add to globals CLIENT2 = 3 etc. and open the pipes accordingly depending communication. Same applies for the gateway below.

The gateway opens the pipes as:
B4X:
rf24.OpenReadingPipe(GATEWAY)
rf24.OpenWritingPipe(CLIENT)
The client sends data to the gateway as array of bytes using randomaccessfile and rf24.
B4X:
Dim b() As Byte = Array As Byte(temperature, humidity)
raf.WriteBytes(b, 0, b.Length, 0)
rf24.Write(buffer)
EXTEND OPTION:
If there is more then one client, the array as byte could be extended like Array As Byte(id, temperature, humidity), where id is unique defined in the globals.
Like
B4X:
Dim b() As Byte = Array As Byte(ID, temperature, humidity)
The gateway receives the data:
B4X:
Sub rf24_NewData (Data() As Byte)
  raf.Initialize(Data, True)
   'Read the array of bytes. length is 2 as containing temp and hum
   Dim b() As Byte = raf.ReadBytes2(2, raf.CurrentPosition)
   'b(0) is temp, b(1) = hum
...
EXTEND OPTION:
If there is more then one client, then the array b(0) could be the unique id as mentioned previous and then take action accordingly.
B4X:
Sub rf24_NewData (Data() As Byte)
  raf.Initialize(Data, True)
   'Read the array of bytes. length is 3 as containing id, temp and hum
   Dim b() As Byte = raf.ReadBytes2(3, raf.CurrentPosition)
   'b(0) is id, b(1) is temp, b(2) = hum
...
 

Attachments

  • rf24experiment1.zip
    3 KB · Views: 577

Beja

Expert
Licensed User
Longtime User
Very smart solution.. thanks Cableguy and rwblinn
 

rbghongade

Active Member
Licensed User
Longtime User
Dear friends,
I tried to use Erel's example with rwblinn's modification with temperature and humidity as type doubles.
Here is the transmitter code(partial)
B4X:
Sub Timer1_Tick
    temperature=25+Rnd(20,50)/100
    humidity=35+Rnd(10,90)/100
    Dim data(2) As Double
    data(0)=temperature
    data(1)=humidity
    Dim b() As Byte = bc.DoublestoBytes(data)
    raf.WriteBytes(b, 0, b.Length, 0)
    rf24.Write(buffer)
End Sub

and receiver code (partial)
B4X:
Sub rf24_NewData (Data() As Byte)
   
  raf.Initialize(Data, True)
  
   Dim b(8) As Byte = raf.ReadBytes2(8, raf.CurrentPosition)
   Dim rData() As Double
   rData=bc.DoublesFromBytes(b)
   Log(rData(0)," ",rData(1))
  
End Sub

I am getting the temperature properly but humidity value is 0!
I think I am messing around with conversions. Kindly suggest the remedy!
Receiver Log:
B4X:
AppStart
25.2700 0
25.2600 0
25.4800 0
25.4300 0
25.4700 0

Regards,
 

rbghongade

Active Member
Licensed User
Longtime User
Solved :
I was using a buffer(4) as byte to transmit and it simply was not big enough!
Thanks Erel.
However I wish there was provision to set the PA level and Data Rates in the library!
 
Top