Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- 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
- stanleyseow@gmail.com
- 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()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement