nRF24 + w5100 + maniacbug's mesh. One seemingly small issue..

I posted this over at stackoverflow also but thought someone here might have come across this combination. I'm this close to this all working..

Here is the setup. Arduino #1 has a w5100 ethernet shield running a webserver accepting GET strings. It then parses out the data and sends it wirelessly to the other nodes using nRF24l10 transceivers. I'm using maniacbug's RF24 and RF24Network libraries. Also due to having the ethernet shield and the wireless I had to use a modified RF24 for the base that supports soft SPI.

Arduino #2 is just the nRF24L10.

What is working. Sending GET's to Arduino #1 works. It parses the information. It then calls the send routine and that says it's ok.

On arduino #2 I get a "Received:" printout but no message. I'm not sure what is wrong. The code is taken right from maniacbug's tx and rx example. Except I had to convert my sendString to a char to send.

I'm wondering if it's one of the following things but I'm not quite sure how to debug.

That the addition of the RF24Network library broke the softSPI. I've been very careful to remove one libray and add the other when I compile. Though if this were the case I'd never see the "Received:" would i?

It doesn't like my conversion from string to char?

Here is the code.

Base Station: Base Station - Pastebin.com Receiver : Receiver - Pastebin.com

Here is the modified RF24+ softspi library. GitHub - shnae/rf24_plus_softSPI: This is a modified version of maniacbug's rf24 library. It allows you to use rf24 over softSPI while using another SPI peripheral (specifically, I use it for working alongside Ethernet Shields with w5100 chip) if that helps.

Here is the maniacbug library. GitHub - maniacbug/RF24Network: Network Layer for nRF24L01(+) Radios

I don't think just adding the nrf24network library breaks that but since it calls SPI.begin() it might. That's beyond my skillset..

Here is the code.

You mean "there is the code". Well, I, and a lot of other people, don't do rubbish bin.

Use Reply (not this stupid Quick Reply field), and there is an option, below the text field, to attach your code here.

Sorry about that. Just assumed pastebin was the standard.

Here is the base station code:

#include <DigitalIO.h>
#include <DigitalPin.h>
#include <I2cConstants.h>
#include <PinIO.h>
#include <SoftI2cMaster.h>
#include <SoftSPI.h>

#include <SPI.h>
#include <Ethernet.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
#include <RF24Network.h>

RF24 radio(6, 7);

boolean reading = 0;
String myStr, dataString, red, green, blue;
int nodeOne, nodeTwo, nodeThree, nodeFour, power, rgbColor, fRed, fGreen, fBlue, dataInt;

// Network uses that radio
RF24Network network(radio);

// Address of our node
const uint16_t this_node = 1;

// Address of the other node
const uint16_t other_node = 0;

// How often to send 'hello world to the other unit
const unsigned long interval = 2000; //ms

// When did we last send?
unsigned long last_sent;

byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 };
IPAddress ip(192,168,30,80);
EthernetServer server(80);

void setup(void) {

Serial.begin(9600);
printf_begin();
radio.begin();
SPI.begin();
network.begin(/channel/ 90, /node address/ this_node);

Ethernet.begin(mac, ip);
server.begin();

//radio.printDetails();

}

//=============================================================================================

void loop() {

checkForClient();

}

//=============================================================================================

void checkForClient() {

EthernetClient client = server.available();

if (client) {

//http request ends with a blank line
boolean currentLineIsBlank = true;
boolean sentHeader = false;
myStr = "";
while (client.connected()) {
if (client.available()) {

char c = client.read();

if(reading && c == ' ') reading = false;
if(c == '?'); reading = true; //found the ?, begin reading the info

if(reading){
Serial.print(c);
if (c!='?') { //if c is not teh ? the keep reading
myStr += c; //and add this character to the string
}

}

if (c == '\n' && currentLineIsBlank) break;

if (c == '\n') {
currentLineIsBlank = true;
} else if (c != '\r') {
currentLineIsBlank = false;
}
}
}

parseHttp (myStr);

delay(100); //give browser time

client.stop(); //close the connection

Serial.println("Sending Data Now:");
broadcastData(dataString);
}

delay(2000);
}

//======================================================================================================

void parseHttp (String str) {

//pull out node1

String strNodeOne = str.substring(10,11);
Serial.print("STRNodeOne: ");
Serial.println(strNodeOne);

//pull out node2
String strNodeTwo = str.substring(17,18);
Serial.print("STRNodeTwo: ");
Serial.println(strNodeTwo);

//pull out node3
String strNodeThree = str.substring(26,27);
Serial.print("STRNodeThree: ");
Serial.println(strNodeThree);

//pull out node4
String strNodeFour = str.substring(34,35);
Serial.print("STRNodeFour: ");
Serial.println(strNodeFour);

//pull out power

String strPower = str.substring(42,43);
Serial.print("STRPower: ");
Serial.println(strPower);

//finally pull out color. it will always be xxxxxxxxx rgb
String strColor = str.substring(50, 59);
Serial.print("STRcolor:");
Serial.println(strColor);

red = strColor.substring(0,3);
blue = strColor.substring(3, 6);
green = strColor.substring(6,9);

dataString = strNodeOne + strNodeTwo + strNodeThree + strNodeFour + strPower + strColor;

}
void broadcastData(String sendString){

Serial.print("Here is sendString: ");
Serial.println(sendString);

// Pump the network regularly
network.update();

unsigned long now = millis();
if ( now - last_sent > interval )
{
last_sent = now;

printf("Sending...\r\n");
size_t len = sendString.length();
char buf[len+1]; // +1 for the trailing zero terminator
sendString.toCharArray(buf, len);
RF24NetworkHeader header(other_node);
bool ok = network.write(header,buf,strlen(buf));
if (ok)
printf("\tok.\r\n");
else
{
printf("\tfailed.\r\n");
delay(250); // extra delay on fail to keep light on longer
}
}

}


Here is the receiver code:

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <printf.h>

// nRF24L01(+) radio attached to SPI and pins 8 & 9
RF24 radio(9,10);

// Network uses that radio
RF24Network network(radio);

// Address of our node
const uint16_t this_node = 0;

// Address of the other node
const uint16_t other_node = 1;

void setup(void)
{
Serial.begin(9600);
printf_begin();
SPI.begin();
radio.begin();
network.begin(/channel/ 90, /node address/ this_node);
}

void loop(void)
{
// Pump the network regularly
network.update();

// Is there anything ready for us?
while ( network.available() )
{
// If so, grab it and print it out
RF24NetworkHeader header;
static char message[32];
network.read(header,message,sizeof(message));
Serial.print("Received: ");
Serial.println(message);
}
}

// Pump the network regularly
  network.update();

How does this happen regularly? It happens only once per client request. Hardly "regularly" in my book.

Personally, I'd ditch all that crap with Strings. Since the data is fixed length (or you couldn't extract data without doing any searching), char arrays are far more appropriate.

network.read(header,message,sizeof(message));

I don't know what this function does, but header is simply instantiated. There is no initialization done. Does there need to be?

PaulS:

// Pump the network regularly

network.update();



How does this happen regularly? It happens only once per client request. Hardly "regularly" in my book.

Personally, I'd ditch all that crap with Strings. Since the data is fixed length (or you couldn't extract data without doing any searching), char arrays are far more appropriate.



network.read(header,message,sizeof(message));



I don't know what this function does, but header is simply instantiated. There is no initialization done. Does there need to be?

Good point about the network update. I moved that to loop.

As for the header. I took that directly from the rx example of maniacbug.

It seems that did it almost. I cant believe it was that. Except it seems to be one character shy.

I get Received: 1010125500025
I should get : 10101255000255

Print the array between markers on both ends. Print the length on both ends.

Serial.print(">");
Serial.print(buf);
Serial.println("<");

Are you sending what you think you are?

PaulS:
Are you sending what you think you are?

Apparently I am not. But I don't understand why I'm not.

Here is the full sendString that I print from within void broadcastData(String sendString)

sendString: 10101255000255

Length comes back as 14 before and after..

Buffer shows exactly what is being received, the string but minus the last digit.

So bear with me here. Is it not adding that +1 to len?

I changed it to

len = len + 1;
char buf[len];

Now its happy. So it was that buf[len + 1], not sure why but that was it.

After all that it's closer than it was before. Data is being sent though very sporadically. ( I'm going home at lunch to reset the radios since i've been uploading to them all morning.

I also set them to 250KBPS instead of 1MPBS.

Thanks to PaulS for the help. I think the sending side is ok. Correct length and the buf is correct.

On the receiver side though. I get a lot of "Received:" but no data. Sometimes I get all the digits, sometimes only a few. Here is an example.

Received:
Received:
Received: 0
Received:
Received:
Received: 1
Received:
Received:
Received:
Received:
Received:
Received: 1002

I copied and pasted from the serial mon window. Not sure what the junk characters are. It's like it gets something since the digits are in the right place. I've attached a screenshot of the receive, since you can see there that it holds the right place.

My gut says its a timing thing.

Here is the updated code.

Base Station:

#include <DigitalIO.h>
#include <DigitalPin.h>
#include <I2cConstants.h>
#include <PinIO.h>
#include <SoftI2cMaster.h>
#include <SoftSPI.h>

#include <SPI.h>
#include <Ethernet.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
#include <RF24Network.h>

RF24 radio(6, 7);

boolean reading = 0;
String myStr, dataString;
int nodeOne, nodeTwo, nodeThree, nodeFour, power, rgbColor, fRed, fGreen, fBlue, dataInt;

// Network uses that radio
RF24Network network(radio);

// Address of our node
const uint16_t this_node = 1;

// Address of the other node
const uint16_t other_node = 0;

// How often to send 'hello world to the other unit
const unsigned long interval = 2000; //ms

// When did we last send?
unsigned long last_sent;

byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 };
IPAddress ip(192,168,30,80);
EthernetServer server(80);

void setup(void) {
  
  Serial.begin(9600);
  printf_begin();
  radio.begin();
  SPI.begin();
  network.begin(/*channel*/ 90, /*node address*/ this_node);
  
  Ethernet.begin(mac, ip);
  server.begin();

}

//=============================================================================================

void loop() {
  
   network.update();
   checkForClient();
  
 
}

//=============================================================================================

void checkForClient() {
 
 EthernetClient client = server.available();
 
 if (client) {
  
   //http request  ends  with a blank line
   boolean currentLineIsBlank = true;
   boolean sentHeader = false;
   myStr = "";
   while (client.connected()) {
     if (client.available()) {
       
       char c = client.read();
       
       if(reading && c == ' ') reading = false;
       if(c == '?'); reading = true; //found the ?, begin reading the info
       
       if(reading){
         Serial.print(c);
         if (c!='?') {   //if c is not teh ? the keep reading
           myStr += c;   //and add this character to the string
         }
         
       }
       
       if (c == '\n' && currentLineIsBlank) break;
       
       if (c == '\n')  {
         currentLineIsBlank = true;
       } else if (c != '\r') {
         currentLineIsBlank = false;
       }
     }
   }

   parseHttp (myStr);
   
   delay(100); //give browser time
  
   client.stop(); //close the connection
   
   broadcastData(dataString);
 }

 delay(500);
}

//======================================================================================================

void parseHttp (String str) {
  
  //pull out node1

  String strNodeOne = str.substring(10,11);
  
    //pull out node2
  String strNodeTwo = str.substring(17,18);
  
  //pull out node3
  String strNodeThree = str.substring(26,27);
  
    //pull out node4
  String strNodeFour = str.substring(34,35);
  
  //pull out power

  String strPower = str.substring(42,43);
  
  //finally pull out color.  it will always be xxxxxxxxx rgb
  String strColor = str.substring(50, 59);
  //red = strColor.substring(0,3);
  //blue = strColor.substring(3, 6);
  //green = strColor.substring(6,9);

  
  dataString =  strNodeOne + strNodeTwo + strNodeThree + strNodeFour + strPower + strColor;

  
}
void broadcastData(String sendString){
 
    //Serial.print("Here is sendString:  ");
    //Serial.println(sendString);
  
   // Pump the network regularly
  //network.update();
  
  unsigned long now = millis();
  if ( now - last_sent > interval  )
  {
    last_sent = now;

    printf("Sending...\r\n");
    size_t len = sendString.length();
    len = len + 1;
    //Serial.print("Length:  ");
    //Serial.println(len);
    char buf[len]; // +1 for the trailing zero terminator

    sendString.toCharArray(buf, len);
      //Serial.print(">");
      //Serial.print(buf);
      //Serial.println("<");
      //Serial.print(len);
    RF24NetworkHeader header(other_node);
    bool ok = network.write(header,buf,strlen(buf));
    if (ok)
      printf("\tok.\r\n");
    else
    {
      printf("\tfailed.\r\n");
      
    }
 
  }
  
}

And the receiver:

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <printf.h>


// nRF24L01(+) radio attached to SPI and pins 8 & 9
RF24 radio(9,10);

// Network uses that radio
RF24Network network(radio);

// Address of our node
const uint16_t this_node = 0;

// Address of the other node
const uint16_t other_node = 1;

void setup(void)
{
  Serial.begin(9600);
  printf_begin();
  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 90, /*node address*/ this_node);
}

void loop(void)
{
  // Pump the network regularly
  network.update();

  // Is there anything ready for us?
  while ( network.available() )
  {
    // If so, grab it and print it out
    RF24NetworkHeader header;
    static char message[32];
    network.read(header,message,sizeof(message));
    Serial.print("Received: ");
    Serial.println(message);
  }
}

received.PNG

Hard reset on both radios. Sending/receiving 100% now.

Thanks again PaulS!