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