KRITSADA icon

nrf24L01 Examples

KRITSADA | PRO | 11/14/19 05:59:53 AM UTC | 0 ⭐ | 816 👁️ | Never ⏰ | []
Arduino |

10.5 KB

|

None

|

0 👍

/

0 👎

 /*
 This program will transmit all data received from the h/w serial pins out to the nRF radio
 and sent out all the data received from the nRF to SoftSerial monitor
 
 For this code, I m using a GPS module Skylab SKM53 running at 9600bps
 
 Max nRF payload size = 30
 1st byte header :-
 7     : fragment/no fragment
 4 - 6 : number of fragments
 3     : unused
 0 - 2 : fragment sequence number
 
 Max buffer is 90 bytes
 
 SoftSerial pins RX 5 ,TX 6 ( for debugging )
 nRF pins CE 8, CSN, 9 MOSI 11, MIS0 12, SCK 13
 
 Date : 27/07/2013
 Version : 4
 
 delay of 20 per radio.write works
 
 Release Notes : Working but the satellite signals will dropped 
 when viewed on Min GPS
 
 
 Written by Stanley Seow
 [email protected]
 
 TODO :-
 
 - rewrite codes to use serialEvent() 
 - better handling of sender/receiver detection
 - reduce/rewrite the usage of memcpy()
 
*/
 
#include <SoftwareSerial.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
 
 
#define DATABUFFERSIZE 90
char dataBuffer[DATABUFFERSIZE];
 
byte dataBufferIndex = 0;
char startChar = '$';
char endChar = '\r';
 
// RX, TX
SoftwareSerial Serial2(5,6);
 
// Set up nRF24L01 radio on SPI pin for CE, CSN
RF24 radio(8,9);
 
const uint64_t pipes[2] = { 0xDEDEDEDEE7ULL, 0xDEDEDEDEE9ULL };
 
// Defines for radio buffers
char RXPayload[33] = "";
char RXPayload2[33] = "";
char RXPayload3[33] = "";
 
char STR1[33],STR2[33],STR3[33] = "";
uint8_t flag0, flagA0, flagA1, flagB0, flagB1, flagB2 = 0;
 
int Sender, storeString = 0;
 
void setup(void)
{
//  Serial.begin(115200);
  Serial.begin(9600);
  Serial2.begin(9600);
  
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);  
  
  printf_begin();
  radio.begin();
 
  // Default radio setings
  radio.enableDynamicPayloads();
  radio.setDataRate(RF24_1MBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(80);
  // delay 1ms, 3 retries
  // 0 - 250us, 15 - 4000us
  radio.setRetries(15,15);
  // Enable AutoAck, send 2nd / 3rd fragment only after 1st/2nd fragment is ACK
  radio.setAutoAck(1);
 
  //check for which side is the sender ( receive data via h/w serial RX )
  // Uses hardware serial for GPS
  if ( Serial.available() > 0 ) {
     if ( Serial.read() ) { Sender = true; }
  }
   
  if ( Sender ) { 
    Serial2.println("Sender mode.. ");
    radio.openWritingPipe(pipes[0]); 
    radio.openReadingPipe(1,pipes[1]);
  } else {
    // this side is the receiver connected to Serial Monitor  
    Serial2.println("Receiver mode.. ");
    Serial.end();
    Serial.begin(57600);
    radio.openWritingPipe(pipes[1]); 
    radio.openReadingPipe(1,pipes[0]);  
    
    // Only print radio details on the receiver side
    radio.startListening();  
    radio.printDetails(); 
  }
 
  delay(500); 
 
}
 
void loop(void) {
 
  if ( !Sender ) {  
 
      nRF_Receive();
  } else { 
      nRF_Sender();
  }
} // End of loop()
 
 
void nRF_Sender() {
  
  char dataBuffer2[DATABUFFERSIZE]="";
 
  if (getSerialString() ) {
 
   // Serial2.println(dataBuffer);  
    
    // Make a copy of dataBuffer array
    memcpy(&dataBuffer2, &dataBuffer,strlen(dataBuffer));
 
    fragmentPackets(dataBuffer2,strlen(dataBuffer2) );
    sendPackets(STR1,STR2,STR3);
    
 }  
}
 
 
boolean getSerialString(){
    static byte dataBufferIndex = 0;
    while(Serial.available()>0){
        char incomingbyte = Serial.read();
        if(incomingbyte==startChar){
            dataBufferIndex = 0;  //Initialize our dataBufferIndex variable
            storeString = true;
        }
        if(storeString){
            //Let's check our index here, and abort if we're outside our buffer size
            //We use our define here so our buffer size can be easily modified
            if(dataBufferIndex==DATABUFFERSIZE){
                //Oops, our index is pointing to an array element outside our buffer.
                dataBufferIndex = 0;
                break;
            }
            if(incomingbyte==endChar){
                dataBuffer[dataBufferIndex] = 0; //null terminate the C string
                //Our data string is complete.  return true
                return true;
            }
            else{
                dataBuffer[dataBufferIndex++] = incomingbyte;
                dataBuffer[dataBufferIndex] = 0; //null terminate the C string
            }
        }
        else{     
        }
    }
    // Did not get a valid string, so return false
    return false;
}
 
 
void fragmentPackets(char Buffer2[DATABUFFERSIZE],int len) {
// Two headers with 30 bytes payload
// 1st byte
//      7 bit - fragment, 1 or 0
// 6 to 4 bit - number of fragment, 111, 7 max fragment
//      3 bit - none
// 0 to 2 bit - fragment number, starting with 0 to 7, 000 to 111
//
// 2nd byte, reserved
 
 
   STR1[0], STR2[0], STR3[0] = 0;
   
   if ( len < 31 ) {
     STR1[0] = B00010000;    // No fragmentation, 1 segment
     STR1[1] = 0xff;         // Reversed header   
     STR1[2] = 0;            // null terminate string
     strcat(STR1,Buffer2);  
   } else if ( len < 61 ) {
        STR1[0] = 0xA0; // fragmentation, 1010 0000, fragment bit, 2 fragments, fragment no. 0
        STR1[1] = 0xff; // Reverse header           
        STR1[2] = 0;     // null terminate string
        strncat(STR1, Buffer2,30);
  
        STR2[0] = 0xA1; // fragmentation, 1010 0001, fragment bit, 2 fragments, fragment no. 1
        STR2[1] = 0xff; // Reverse header            
        STR2[2] = 0;     // null terminate string, 32 bytes + 2 extra bytes
        strcat(STR2, &Buffer2[30]);    // Copy the balance of pointer address 30 and above
        
   } else if ( len < 91 )  {   
        STR1[0] = 0xB0; // fragmentation, 1011 0000, fragment bit, 3 fragments, fragment no. 0
        STR1[1] = 0xff; // Reverse header           
        STR1[2] = 0;     // null terminate string  
        strncat(STR1, Buffer2,30);    // Copy the 1st 30 bytes to STR1
        
        STR2[0] = 0xB1; // fragmentation, 1011 0001, fragment bit, 3 fragments, fragment no. 1
        STR2[1] = 0xff; // Reverse header   
        STR2[2] = 0;     // null terminate string
        strncat(STR2, &Buffer2[30],30);  // Copy the next 30 bytes to STR2
 
        STR3[0] = 0xB2; // fragmentation, 1011 0011, fragment bit, 3 fragments, fragment no. 2
        STR3[1] = 0xff; // Reverse header         
        STR3[2] = 0;     // null terminate string      
        strcat(STR3, &Buffer2[60]);        
        
      } else {
      // payload > 90 bytes, discard or add more fragments   
      Serial2.print("Input serial string more than 90 bytes");
   } // end if
 
}  // end fragmentPackets 
 
 
void sendPackets(char TMP1[33], char TMP2[33], char TMP3[33]) {
 
  // Mask the 1st Byte, bits 5 & 6 and shift 4 places to right
  // Return 0, 2 or 3 fragments
  int status = (STR1[0] & B00110000)>>4; 
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
    
  radio.stopListening();
  
  switch (status) {
    case 1:
          radio.write( TMP1,strlen(TMP1));
          // fine tune the correct delay values based on radio.setRetries()
          delay(20);    
          break;
    case 2:
          radio.write(TMP1,strlen(TMP1));   
          delay(20);
          radio.write( TMP2,strlen(TMP2));   
 
          // fine tune the correct delay values based on radio.setRetries()
          delay(20);    
          break;
    case 3:
          radio.write(TMP1,strlen(TMP1));
          delay(20);
          radio.write(TMP2,strlen(TMP2));   
          delay(20);
          radio.write(TMP3,strlen(TMP3));
 
          // fine tune the correct delay values based on radio.setRetries()
          delay(20);
          break;
    } // switch/case  end
    
    radio.startListening();
  
} // nrf_Send end
 
 
 
// Receive payload from nRF at remote end
 
void nRF_Receive(){
 
  uint8_t len=0, Header = 0, recvPacket = 0;
  
 // Call startlistening everytime here
    
  RXPayload[0] = 0;
  
  if ( radio.available() > 0 ) {
    len = radio.getDynamicPayloadSize();
    radio.read( &RXPayload, len );
    RXPayload[len] = 0; // Terminate RxPayload string with 0 
 
    // Extract header bits for comparision
    Header = RXPayload[0] & 0xff; 
    
//Serial.print("RXPayload:");
//Serial.print(Header,HEX);
//Serial.print(" ");
//Serial.println(RXPayload);
 
    switch ( Header ) {
  
    case 0x10: 
     // No fragment, strip off first 2 header bytes
        memcpy(&STR1,&RXPayload[2],len-2 );  
        STR1[len-2]=0;
        flag0 = 1;
//Serial.print("flag0:");
//Serial.println(STR1);
        break;
        
    case 0xA0:    
     // Fragment packets, with 2 fragments, 1st fragment
        memcpy(&STR1, &RXPayload[2],30);
        STR1[30]=0;
        flagA0 = 1;
//Serial.print("flagA0:");
//Serial.println(STR1);        
        break;
        
    case 0xA1:
      // Fragment packets, with 2 fragments, last fragment
        memcpy(&STR2, &RXPayload[2],len-2);
        STR2[len-2]=0;
        flagA1 = 1;
//Serial.print("flagA1:");
//Serial.println(STR2);   
        break;   
  
    case 0xB0:
      // Fragment packets, with 3 fragments, 1st fragment
        memcpy(&STR1, &RXPayload[2],30);
        STR1[30]=0;
        flagB0 = 1;
//Serial.print("flagB0:");
//Serial.println(STR1);           
        break;
        
    case 0xB1:
      // Fragment packets, with 3 fragments, 2nd fragment
        memcpy(&STR2, &RXPayload[2],30);
        STR2[30]=0;
        flagB1 = 1;
//Serial.print("flagB1:");
//Serial.println(STR2);           
        break;  
 
    case 0xB2:
      // Fragment packets, with 3 fragments, last fragment
        memcpy(&STR3, &RXPayload[2],len-2);
        STR3[len-2]=0;
        flagB2 = 1;
//Serial.print("flagB2:");
//Serial.println(STR3);           
        break;  
    default:
        Serial.println("Invalid Headers");
    
    } // end of switch    
        
        
    // Merge payload to Serial Monitor
    
    if ( flag0 ) {
         sprintf(dataBuffer,"%s",STR1);
         flag0 = 0;
    } else if ( flagA0 && flagA1 ) {
         sprintf(dataBuffer,"%s%s",STR1,STR2);
         flagA0, flagA1 = 0;
    } else if ( flagB0 && flagB1 && flagB2 ) {
         sprintf(dataBuffer,"%s%s%s",STR1,STR2,STR3);
         flagB0, flagB1, flagB2 = 0;
    } 
    
    if ( (dataBuffer[0] == '$') ) {
     Serial.println(dataBuffer);
     // Reset all buffers and flags
     dataBuffer[0] = 0;
     STR1[0] = 0; STR2[0] = 0; STR3[0] = 0;
    }
  
  } // endif radio.available()  
}

Comments