B4R Question nRF24L01 multi client problem

Michael Sergio

Member
Licensed User
Longtime User
Hi. I have 2 nano with nRF24L01 radios and one Mega with nRF24L01
Mega - server
Nano -clients
SERVER SIDE Code example:
B4X:
Process Globals
'Other Code
 Private rf24 As RF24xt ' i`m using RF24xt(v1.02) library
Private const SERVER = 1, CLIENTradio= 2 As ULong
Private receivedXtimesRFID As Int=0
'...
End Sub
Private Sub AppStart
'other code
    Serial1.Initialize(115200)
    rf24.Initialize(7, 8, "rf24_NewData")
    rf24.SetChannel(76)
    rf24.SetGroupID(0xAB)
    rf24.SetDataRate(1)
    rf24.UseAutoAck(False)
    rf24.UseCRC(False)
    rf24.SetPower(3)
    rf24.Sleep(False)
    rf24.OpenReadingPipe(SERVER)
    rf24.OpenWritingPipe(CLIENTradio)
'other code
End Sub
Sub SendtoCliend(ClientId as Uint,Number1 as Uint,Number2 as Uint,Typez as Uint) 'triggers when i send mqtt data from b4j app
'Example:
'ClientId=2
'Number1=1120
'Number2=0
'Typez=1
receivedXtimesRFID=0
Dim b() As Byte = bc.UIntsToBytes(Array As UInt(ClientId, Number1,Number2,Typez))

                For i=0 To 2      'i`m sending without ack so i send it multiple times to be sure
                    rf24.Write(b)
                    Delay(300)
               
                Next
                    rf24.ResetRx
End Sub

'receiving the data
Sub rf24_NewData (Data() As Byte) '
If receivedXtimesRFID=0 Then
    receivedXtimesRFID=1
    If Data.Length >= 8 Then
        Dim numbers() As UInt = bc.UIntsFromBytes(bc.SubString2(Data, 0, 8))
        Dim Number1 As UInt=numbers(1)
        Dim Number2 As UInt=numbers(2)
        Log(numbers(3))
        If Number1 > 0 Then
            SendSelect(Array(Clientz,numbers(0), "confirm",numbers(1))) 'mqtt sending to b4j app
        Else
            SendSelect(Array(Clientz,numbers(0), "confirm",numbers(2))) 'mqtt
        End If
    Else
        Log("Missing data")
    End If
Else
        Log("Data already received")
End If
End Sub

Client One side CODE:
B4X:
Process Globals
'Other Code
 Private rf24 As RF24xt ' i`m using RF24xt(v1.02) library
Private const SERVER = 1, CLIENTradio= 2 As ULong
Private receivedXtimesRFID As Int=0
Private ClientId as Uint = 1 'first client
'...
End Sub
Private Sub AppStart
'other code
    Serial1.Initialize(115200)
    rf24.Initialize(9, 10, "rf24_NewData")
    rf24.SetChannel(76)
    rf24.SetGroupID(0xAB)
    rf24.SetDataRate(1)
    rf24.UseAutoAck(False)
    rf24.UseCRC(False)
    rf24.SetPower(3)
    rf24.Sleep(False)
    rf24.OpenReadingPipe(CLIENTradio)
    rf24.OpenWritingPipe(SERVER)
'other code
End Sub

Sub rf24_NewData (Data() As Byte)

    If Data.Length >= 8 Then
       
        Dim numbers() As UInt = bc.UIntsFromBytes(bc.SubString2(Data, 0, 8))
        Dim ClientIdSent As UInt=numbers(0)
        Dim FirstStrk As UInt =numbers(1)
        Dim SecondStrk As UInt =numbers(2)
        Dim Typez As UInt=numbers(3)
    If ClientIdSent = ClientId Then
            If receivedXtimesRFID=  0 Then
                    receivedXtimesRFID = 1
            Else
                Log("data already received")
                Return
            End If
                    If Typez=1 Then
                       'my routine1
                                CallSubPlus("Gotest",500,0)     
                    Else If Typez = 2 Then
                       'my routine2                   
                    End If
    End If
    End If  
End Sub

Sub SendResponseRadio(Tag As Byte)' triggers after myroutine1 or myroutine2 is done
 
'Example:
'ClientId=1
'Number1=1120
'Number2=0
'Typez=0
Dim b() As Byte = bc.UIntsToBytes(Array As UInt(ClientId, Number1,Number2,Typez))
    Dim numbers() As UInt = bc.UIntsFromBytes(bc.SubString2(b, 0, 8))
    For i=0 To 1
    If rf24.Write(b)=True Then  
            Log("ok sent rfid ",numbers(0),numbers(1),numbers(2))
    Else
            i=0
    End If
    Delay(150)
    Next
    rf24.ResetRx
    receivedXtimesRFID = 0 'because i ignore all responses if i already have a command from radio until the current command is done and i`ve sent the client`s response
End Sub

Client Two code is the same as Client one..just ClientId is different (ClientID =2)

What is/should do:

The server sends a radio message to clients. The message is for a specific client ( first Uint as seen in code).
The client is responsible for filtering the message. If the command is for that client, then activates the routine1 or 2, then sends a response to server.

THE PROBLEM:
Everything is working great, until the client sends his response to the server.
Example:
Server to Client 1
Client 1 received the msg, does the routine, sends back the response.
SERVER receved the client 1 response...and also Client 2 received the response, but EVERY UINT IS DOUBLED ..How?
Example:
server -> 112001 'where 1= clientId ,120=Number1, 0=Number2, 1=Typez
client1 <-112001
client2 <-112001 'IGNORES the msg..is not for him
client1 routines
client1 ->112000
server <- 112000
client2 <-224000 'THIS SHOULDN'T`T HAPPEN

Now i have a problem
since the client2 id is '2' so he thinks that there is a valid message for him from the server and ignores every commands from now on from the server, since 'receivedXtimesRFID =1' .

I resolved my specific problem by changing the code in the clients:
B4X:
'instead of:
If receivedXtimesRFID=  0 Then
                    receivedXtimesRFID = 1
            Else
                Log("data already received")
                Return
            End If
'i changed it to:
If receivedXtimesRFID=  0 Then
                If Not (Typez=0) Then
                    receivedXtimesRFID = 1
                End If
 
            Else
                Log("data already received")
                Return
            End If
since the Typez is only > 0 when the server sends it, so the client can ignore the double message from the other client.
But its still bothering me, because of the unnecessary data the clients receive , and I may have more than 2 clients for this project ( up until 8).

The question is..i did something wrong, or is something else?
 
Last edited:

Michael Sergio

Member
Licensed User
Longtime User
Thank you for your reply.
So, i tested it with just the rf24 code still 1 server and 2 clients. I tried sending only once, or multiple times...the same result as before.
Also, i tried changing on the rf24 init part the power rate, Datarate, channel, still i had the same result.
Then I switched to Erel`s default rRF24 library . and it worked..no more double messages, its working.
I`m sad because i liked Starchild`s library and the extra options it provides ( like the useful SetPower, and rxreset to clear the radio buffer )
Can i know somehow the default DataRate and SetPower of the Erel`s original rRF24 library?
 
Upvote 0
Top