View difference between Paste ID: QKcFUn1R and mmMxgdCx
SHOW: | | - or go back to the newest paste.
1
 /*
2
 This program will transmit all data received from the h/w serial pins out to the nRF radio
3
 and sent out all the data received from the nRF to SoftSerial monitor
4
5
 For this code, I m using a GPS module Skylab SKM53 running at 9600bps
6
 
7
 Max nRF payload size = 30
8
 1st byte header :-
9
 7     : fragment/no fragment
10
 4 - 6 : number of fragments
11
 3     : unused
12
 0 - 2 : fragment sequence number
13
 
14
 Max buffer is 90 bytes
15
16
 SoftSerial pins RX 5 ,TX 6 ( for debugging )
17
 nRF pins CE 8, CSN, 9 MOSI 11, MIS0 12, SCK 13
18
 
19
 Date : 27/07/2013
20
 Version : 4
21
 
22
 delay of 20 per radio.write works
23
 
24
 Release Notes : Working but the satellite signals will dropped 
25
 when viewed on Min GPS
26
 
27
28
 Written by Stanley Seow
29
 [email protected]
30
 
31
 TODO :-
32
 
33
 - rewrite codes to use serialEvent() 
34
 - better handling of sender/receiver detection
35
 - reduce/rewrite the usage of memcpy()
36
 
37
*/
38
39
#include <SoftwareSerial.h>
40
#include <SPI.h>
41
#include "nRF24L01.h"
42
#include "RF24.h"
43
#include "printf.h"
44
45
46
#define DATABUFFERSIZE 90
47
char dataBuffer[DATABUFFERSIZE];
48
49
byte dataBufferIndex = 0;
50
char startChar = '$';
51
char endChar = '\r';
52
53
// RX, TX
54
SoftwareSerial Serial2(5,6);
55
56
// Set up nRF24L01 radio on SPI pin for CE, CSN
57
RF24 radio(8,9);
58
59
const uint64_t pipes[2] = { 0xDEDEDEDEE7ULL, 0xDEDEDEDEE9ULL };
60
61
// Defines for radio buffers
62
char RXPayload[33] = "";
63
char RXPayload2[33] = "";
64
char RXPayload3[33] = "";
65
66
char STR1[33],STR2[33],STR3[33] = "";
67
uint8_t flag0, flagA0, flagA1, flagB0, flagB1, flagB2 = 0;
68
69
int Sender, storeString = 0;
70
71
void setup(void)
72
{
73
//  Serial.begin(115200);
74
  Serial.begin(9600);
75
  Serial2.begin(9600);
76
  
77
  pinMode(2,OUTPUT);
78
  pinMode(3,OUTPUT);  
79
  
80
  printf_begin();
81
  radio.begin();
82
83
  // Default radio setings
84
  radio.enableDynamicPayloads();
85
  radio.setDataRate(RF24_1MBPS);
86
  radio.setPALevel(RF24_PA_MAX);
87
  radio.setChannel(80);
88
  // delay 1ms, 3 retries
89
  // 0 - 250us, 15 - 4000us
90
  radio.setRetries(15,15);
91
  // Enable AutoAck, send 2nd / 3rd fragment only after 1st/2nd fragment is ACK
92
  radio.setAutoAck(1);
93
94
  //check for which side is the sender ( receive data via h/w serial RX )
95
  // Uses hardware serial for GPS
96
  if ( Serial.available() > 0 ) {
97
     if ( Serial.read() ) { Sender = true; }
98
  }
99
   
100
  if ( Sender ) { 
101
    Serial2.println("Sender mode.. ");
102
    radio.openWritingPipe(pipes[0]); 
103
    radio.openReadingPipe(1,pipes[1]);
104
  } else {
105
    // this side is the receiver connected to Serial Monitor  
106
    Serial2.println("Receiver mode.. ");
107
    Serial.end();
108
    Serial.begin(57600);
109
    radio.openWritingPipe(pipes[1]); 
110
    radio.openReadingPipe(1,pipes[0]);  
111
    
112
    // Only print radio details on the receiver side
113
    radio.startListening();  
114
    radio.printDetails(); 
115
  }
116
117
  delay(500); 
118
119
}
120
121
void loop(void) {
122
123
  if ( !Sender ) {  
124
125
      nRF_Receive();
126
  } else { 
127
      nRF_Sender();
128
  }
129
} // End of loop()
130
131
132
void nRF_Sender() {
133
  
134
  char dataBuffer2[DATABUFFERSIZE]="";
135
136
  if (getSerialString() ) {
137
 
138
   // Serial2.println(dataBuffer);  
139
    
140
    // Make a copy of dataBuffer array
141
    memcpy(&dataBuffer2, &dataBuffer,strlen(dataBuffer));
142
143
    fragmentPackets(dataBuffer2,strlen(dataBuffer2) );
144
    sendPackets(STR1,STR2,STR3);
145
    
146
 }  
147
}
148
149
150
boolean getSerialString(){
151
    static byte dataBufferIndex = 0;
152
    while(Serial.available()>0){
153
        char incomingbyte = Serial.read();
154
        if(incomingbyte==startChar){
155
            dataBufferIndex = 0;  //Initialize our dataBufferIndex variable
156
            storeString = true;
157
        }
158
        if(storeString){
159
            //Let's check our index here, and abort if we're outside our buffer size
160
            //We use our define here so our buffer size can be easily modified
161
            if(dataBufferIndex==DATABUFFERSIZE){
162
                //Oops, our index is pointing to an array element outside our buffer.
163
                dataBufferIndex = 0;
164
                break;
165
            }
166
            if(incomingbyte==endChar){
167
                dataBuffer[dataBufferIndex] = 0; //null terminate the C string
168
                //Our data string is complete.  return true
169
                return true;
170
            }
171
            else{
172
                dataBuffer[dataBufferIndex++] = incomingbyte;
173
                dataBuffer[dataBufferIndex] = 0; //null terminate the C string
174
            }
175
        }
176
        else{     
177
        }
178
    }
179
    // Did not get a valid string, so return false
180
    return false;
181
}
182
183
184
void fragmentPackets(char Buffer2[DATABUFFERSIZE],int len) {
185
// Two headers with 30 bytes payload
186
// 1st byte
187
//      7 bit - fragment, 1 or 0
188
// 6 to 4 bit - number of fragment, 111, 7 max fragment
189
//      3 bit - none
190
// 0 to 2 bit - fragment number, starting with 0 to 7, 000 to 111
191
//
192
// 2nd byte, reserved
193
194
195
   STR1[0], STR2[0], STR3[0] = 0;
196
   
197
   if ( len < 31 ) {
198
     STR1[0] = B00010000;    // No fragmentation, 1 segment
199
     STR1[1] = 0xff;         // Reversed header   
200
     STR1[2] = 0;            // null terminate string
201
     strcat(STR1,Buffer2);  
202
   } else if ( len < 61 ) {
203
        STR1[0] = 0xA0; // fragmentation, 1010 0000, fragment bit, 2 fragments, fragment no. 0
204
        STR1[1] = 0xff; // Reverse header           
205
        STR1[2] = 0;     // null terminate string
206
        strncat(STR1, Buffer2,30);
207
  
208
        STR2[0] = 0xA1; // fragmentation, 1010 0001, fragment bit, 2 fragments, fragment no. 1
209
        STR2[1] = 0xff; // Reverse header            
210
        STR2[2] = 0;     // null terminate string, 32 bytes + 2 extra bytes
211
        strcat(STR2, &Buffer2[30]);    // Copy the balance of pointer address 30 and above
212
        
213
   } else if ( len < 91 )  {   
214
        STR1[0] = 0xB0; // fragmentation, 1011 0000, fragment bit, 3 fragments, fragment no. 0
215
        STR1[1] = 0xff; // Reverse header           
216
        STR1[2] = 0;     // null terminate string  
217
        strncat(STR1, Buffer2,30);    // Copy the 1st 30 bytes to STR1
218
        
219
        STR2[0] = 0xB1; // fragmentation, 1011 0001, fragment bit, 3 fragments, fragment no. 1
220
        STR2[1] = 0xff; // Reverse header   
221
        STR2[2] = 0;     // null terminate string
222
        strncat(STR2, &Buffer2[30],30);  // Copy the next 30 bytes to STR2
223
 
224
        STR3[0] = 0xB2; // fragmentation, 1011 0011, fragment bit, 3 fragments, fragment no. 2
225
        STR3[1] = 0xff; // Reverse header         
226
        STR3[2] = 0;     // null terminate string      
227
        strcat(STR3, &Buffer2[60]);        
228
        
229
      } else {
230
      // payload > 90 bytes, discard or add more fragments   
231
      Serial2.print("Input serial string more than 90 bytes");
232
   } // end if
233
234
}  // end fragmentPackets 
235
236
237
void sendPackets(char TMP1[33], char TMP2[33], char TMP3[33]) {
238
239
  // Mask the 1st Byte, bits 5 & 6 and shift 4 places to right
240
  // Return 0, 2 or 3 fragments
241
  int status = (STR1[0] & B00110000)>>4; 
242
  digitalWrite(2, LOW);
243
  digitalWrite(3, LOW);
244
    
245
  radio.stopListening();
246
  
247
  switch (status) {
248
    case 1:
249
          radio.write( TMP1,strlen(TMP1));
250
          // fine tune the correct delay values based on radio.setRetries()
251
          delay(20);    
252
          break;
253
    case 2:
254
          radio.write(TMP1,strlen(TMP1));   
255
          delay(20);
256
          radio.write( TMP2,strlen(TMP2));   
257
258
          // fine tune the correct delay values based on radio.setRetries()
259
          delay(20);    
260
          break;
261
    case 3:
262
          radio.write(TMP1,strlen(TMP1));
263
          delay(20);
264
          radio.write(TMP2,strlen(TMP2));   
265
          delay(20);
266
          radio.write(TMP3,strlen(TMP3));
267
268
          // fine tune the correct delay values based on radio.setRetries()
269
          delay(20);
270
          break;
271
    } // switch/case  end
272
    
273
    radio.startListening();
274
  
275
} // nrf_Send end
276
277
278
279
// Receive payload from nRF at remote end
280
281
void nRF_Receive(){
282
283
  uint8_t len=0, Header = 0, recvPacket = 0;
284
  
285
 // Call startlistening everytime here
286
    
287
  RXPayload[0] = 0;
288
  
289
  if ( radio.available() > 0 ) {
290
    len = radio.getDynamicPayloadSize();
291
    radio.read( &RXPayload, len );
292
    RXPayload[len] = 0; // Terminate RxPayload string with 0 
293
294
    // Extract header bits for comparision
295
    Header = RXPayload[0] & 0xff; 
296
    
297
//Serial.print("RXPayload:");
298
//Serial.print(Header,HEX);
299
//Serial.print(" ");
300
//Serial.println(RXPayload);
301
302
    switch ( Header ) {
303
  
304
    case 0x10: 
305
     // No fragment, strip off first 2 header bytes
306
        memcpy(&STR1,&RXPayload[2],len-2 );  
307
        STR1[len-2]=0;
308
        flag0 = 1;
309
//Serial.print("flag0:");
310
//Serial.println(STR1);
311
        break;
312
        
313
    case 0xA0:    
314
     // Fragment packets, with 2 fragments, 1st fragment
315
        memcpy(&STR1, &RXPayload[2],30);
316
        STR1[30]=0;
317
        flagA0 = 1;
318
//Serial.print("flagA0:");
319
//Serial.println(STR1);        
320
        break;
321
        
322
    case 0xA1:
323
      // Fragment packets, with 2 fragments, last fragment
324
        memcpy(&STR2, &RXPayload[2],len-2);
325
        STR2[len-2]=0;
326
        flagA1 = 1;
327
//Serial.print("flagA1:");
328
//Serial.println(STR2);   
329
        break;   
330
  
331
    case 0xB0:
332
      // Fragment packets, with 3 fragments, 1st fragment
333
        memcpy(&STR1, &RXPayload[2],30);
334
        STR1[30]=0;
335
        flagB0 = 1;
336
//Serial.print("flagB0:");
337
//Serial.println(STR1);           
338
        break;
339
        
340
    case 0xB1:
341
      // Fragment packets, with 3 fragments, 2nd fragment
342
        memcpy(&STR2, &RXPayload[2],30);
343
        STR2[30]=0;
344
        flagB1 = 1;
345
//Serial.print("flagB1:");
346
//Serial.println(STR2);           
347
        break;  
348
349
    case 0xB2:
350
      // Fragment packets, with 3 fragments, last fragment
351
        memcpy(&STR3, &RXPayload[2],len-2);
352
        STR3[len-2]=0;
353
        flagB2 = 1;
354
//Serial.print("flagB2:");
355
//Serial.println(STR3);           
356
        break;  
357
    default:
358
        Serial.println("Invalid Headers");
359
    
360
    } // end of switch    
361
        
362
        
363
    // Merge payload to Serial Monitor
364
    
365
    if ( flag0 ) {
366
         sprintf(dataBuffer,"%s",STR1);
367
         flag0 = 0;
368
    } else if ( flagA0 && flagA1 ) {
369
         sprintf(dataBuffer,"%s%s",STR1,STR2);
370
         flagA0, flagA1 = 0;
371
    } else if ( flagB0 && flagB1 && flagB2 ) {
372
         sprintf(dataBuffer,"%s%s%s",STR1,STR2,STR3);
373
         flagB0, flagB1, flagB2 = 0;
374
    } 
375
    
376
    if ( (dataBuffer[0] == '$') ) {
377
     Serial.println(dataBuffer);
378
     // Reset all buffers and flags
379
     dataBuffer[0] = 0;
380
     STR1[0] = 0; STR2[0] = 0; STR3[0] = 0;
381
    }
382
  
383
  } // endif radio.available()  
384
}