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