BayEOSArduino Library
RF24Router.h
1 /*
2  * Functions and Variables for RF24Routing
3  *
4  * expects the following global variables to be defined:
5  * radio, client
6  */
7 #include <Sleep.h>
8 
9 uint16_t rx_ok, rx1_count, rx1_error;
10 
11 #ifdef NRF24_2CHANNEL
12 uint16_t rx2_count, rx2_error;
13 #endif
14 
15 #ifndef WITH_RF24_CHECKSUM
16 #define WITH_RF24_CHECKSUM 0
17 #endif
18 
19 volatile uint16_t wdcount = 0;
20 volatile uint8_t wdreset = 0;
21 volatile uint8_t tx_blink = 0;
22 volatile uint8_t rx_blink = 0;
23 
24 #ifndef POWER_DIVIDER
25 #define POWER_DIVIDER (470.0+100.0)/100.0
26 #endif
27 
28 #ifndef POWER_AD_PIN
29 #define POWER_AD_PIN A3
30 #endif
31 
32 #ifndef SENDING_INTERVAL
33 #define SENDING_INTERVAL 120000L
34 #endif
35 
36 #ifndef NEXT_TRY_INTERVAL
37 #define NEXT_TRY_INTERVAL 300000L
38 #endif
39 
40 #ifndef MAX_BUFFER_AVAILABLE
41 #define MAX_BUFFER_AVAILABLE 2000
42 #endif
43 
44 unsigned long last_alive, last_send, last_try;
45 uint16_t tx_error;
46 uint8_t tx_res;
47 uint8_t gprs_sendmode=0;
48 
49 ISR(WDT_vect) {
50  wdcount++;
51  // last_wdt_millis = wdt_millis;
52  // wdt_millis = millis();
53  if (wdreset) {
54  wdcount = 0;
55  wdreset = 0;
56  }
57  if (wdcount > 5*60*4) { //no action for more than 5 minutes.
58 #if SKETCH_DEBUG
59  Serial.println("RESET");
60  delay(100);
61 #endif
62  asm volatile (" jmp 0"); //restart programm
63  }
64 #ifdef TX_LED
65  if (tx_blink) {
66  if (digitalRead(TX_LED)) {
67  digitalWrite(TX_LED, LOW);
68  tx_blink--;
69  } else {
70  digitalWrite(TX_LED, HIGH);
71  }
72  }
73 #endif
74 #ifdef RX_LED
75  if (rx_blink) {
76  if (digitalRead(RX_LED)) {
77  digitalWrite(RX_LED, LOW);
78  rx_blink--;
79  } else {
80  digitalWrite(RX_LED, HIGH);
81  }
82  }
83 #endif
84 }
85 
86 void initWatchdog(void) {
87 #if SKETCH_DEBUG
88  Serial.begin(9600);
89  Serial.println("Starting");
90 #endif
91 
92  Sleep.setupWatchdog(WDTO_250MS); //250ms
93 #ifdef RX_LED
94  pinMode(RX_LED, OUTPUT);
95 #endif
96 #ifdef TX_LED
97  pinMode(TX_LED, OUTPUT);
98 #endif
99 #ifdef RX_LED
100  rx_blink = 2;
101  delay(500);
102  tx_blink = 1;
103  delay(1000);
104 #endif
105 }
106 
107 void initRF24(void) {
108  radio.begin();
109  radio.powerUp();
110  radio.setChannel(NRF24_CHANNEL);
111  radio.setPayloadSize(32);
112  radio.enableDynamicPayloads();
113  radio.setCRCLength(RF24_CRC_16);
114  radio.setDataRate(RF24_250KBPS);
115  radio.setPALevel(RF24_PA_MAX);
116  radio.setRetries(15, 15);
117  radio.setAutoAck(true);
118  radio.openReadingPipe(0, pipe_0);
119  radio.openReadingPipe(1, pipe_1);
120  radio.openReadingPipe(2, pipe_2);
121  radio.openReadingPipe(3, pipe_3);
122  radio.openReadingPipe(4, pipe_4);
123  radio.openReadingPipe(5, pipe_5);
124 
125  radio.startListening();
126 #ifdef NRF24_2CHANNEL
127  radio2.begin();
128  radio2.powerUp();
129  radio2.setChannel(NRF24_2CHANNEL);
130  radio2.setPayloadSize(32);
131  radio2.enableDynamicPayloads();
132  radio2.setCRCLength( RF24_CRC_16 );
133  radio2.setDataRate(RF24_250KBPS);
134  radio2.setPALevel(RF24_PA_MAX);
135  radio2.setRetries(15, 15);
136  radio2.setAutoAck(true);
137  radio2.openReadingPipe(0, pipe_0);
138  radio2.openReadingPipe(1, pipe_1);
139  radio2.openReadingPipe(2, pipe_2);
140  radio2.openReadingPipe(3, pipe_3);
141  radio2.openReadingPipe(4, pipe_4);
142  radio2.openReadingPipe(5, pipe_5);
143  radio2.startListening();
144 #endif
145 }
146 
147 uint8_t handleRF24(void) {
148  uint8_t pipe_num, len;
149  uint8_t payload[32];
150  char origin[] = "P0";
151 #ifdef RF24_P1_LETTER
152  origin[0]=RF24_P1_LETTER;
153 #endif
154  uint8_t count=0;
155  uint8_t rx = 0;
156  while (radio.available(&pipe_num)) {
157  count++;
158  if (len = radio.getDynamicPayloadSize()) {
159  rx++;
160  origin[1] = '0' + pipe_num;
161  client.startOriginFrame(origin, 1); //Routed Origin!
162  if (len > 32)
163  len = 32;
164  radio.read(payload, len);
165  for (uint8_t i = 0; i < len; i++) {
166  client.addToPayload(payload[i]);
167  }
168 #if WITH_RF24_CHECKSUM
169  if(! client.validateChecksum()) {
170  client.writeToBuffer();
171  rx_blink = 1;
172  rx1_count++;
173  } else
174  rx1_error++;
175 #else
176  client.writeToBuffer();
177  rx_blink = 1;
178  rx1_count++;
179 #endif
180 
181  } else {
182  rx1_error++;
183  }
184  if (count > 10)
185  break;
186  }
187 
188 #ifdef NRF24_2CHANNEL
189  count=0;
190 #ifdef RF24_P2_LETTER
191  origin[0]=RF24_P2_LETTER;
192 #else
193  origin[0]='R';
194 #endif
195 
196  while (radio2.available(&pipe_num)) {
197  wdreset = 1;
198  count++;
199  if (len = radio2.getDynamicPayloadSize()) {
200  rx++;
201  origin[1]='0'+pipe_num;
202  client.startOriginFrame(origin,1); //Routed Origin!
203  // Fetch the payload
204  if (len > 32) len = 32;
205  radio2.read( payload, len );
206  for (uint8_t i = 0; i < len; i++) {
207  client.addToPayload(payload[i]);
208  }
209 #if WITH_RF24_CHECKSUM
210  if(! client.validateChecksum()) {
211  client.writeToBuffer();
212  rx_blink = 1;
213  rx2_count++;
214  } else
215  rx2_error++;
216 #else
217  client.writeToBuffer();
218  rx_blink = 1;
219  rx2_count++;
220 #endif
221 
222  } else {
223  rx2_error++;
224  }
225  if (count > 10) break;
226  }
227 
228 #endif
229  if (count > 10)
230  initRF24();
231 
232  delay(2); //Do not query RF24 to often...
233  return rx;
234 }
235 
236 void startGPRS(uint8_t checkRF24 = 1) {
237  uint8_t try_count = 0;
238  while (try_count < 5) {
239  wdreset = 1;
240  if (checkRF24)
241  handleRF24();
242  try_count++;
243  rx_blink = 1;
244  tx_res = client.begin(38400);
245  tx_blink = tx_res + 1;
246  delay(600 * tx_res);
247 #if SKETCH_DEBUG
248  Serial.print("Client.begin: ");
249  Serial.println(tx_res);
250 #endif
251  if (!tx_res)
252  return;
253  if (try_count % 2 == 0)
254  client.softSwitch();
255  }
256  return;
257 
258 }
259 
260 void checkAlive(void) {
261  if ((millis() - last_alive) < SENDING_INTERVAL)
262  return;
263 #if SKETCH_DEBUG
264  Serial.print("Alive: ");
265  Serial.print(millis());
266  Serial.print(" ");
267  Serial.println(last_alive);
268 #endif
269  // radio.startListening();
270  if (rx1_count == 0
271 #ifdef NRF24_2CHANNEL
272  || rx2_count == 0
273 #endif
274  )
275  initRF24();
276  if (rx1_error > 5
277 #ifdef NRF24_2CHANNEL
278  || rx2_error>5
279 #endif
280  )
281  initRF24();
282 
283  last_alive = millis();
284  client.startDataFrame(BayEOS_Float32le);
285  client.addChannelValue(millis() / 1000);
286  client.addChannelValue(myBuffer.writePos());
287  client.addChannelValue(myBuffer.readPos());
288  client.addChannelValue(client.getRSSI());
289  analogReference (DEFAULT);
290  for (uint8_t z = 0; z < 3; z++) {
291  analogRead (POWER_AD_PIN);
292  delay(10);
293  }
294  client.addChannelValue(
295  (float) analogRead(POWER_AD_PIN) / 1023 * 3.3 * POWER_DIVIDER);
296  client.addChannelValue(tx_error);
297  client.addChannelValue(tx_res);
298  client.addChannelValue(rx1_count);
299  client.addChannelValue(rx1_error);
300  rx1_count = 0;
301  rx1_error = 0;
302 #ifdef NRF24_2CHANNEL
303  client.addChannelValue(rx2_count);
304  client.addChannelValue(rx2_error);
305  rx2_count = 0;
306  rx2_error = 0;
307 #endif
308  client.writeToBuffer();
309 
310 }
311 
312 void checkSend(void) {
313  if (!myBuffer.available()){
314  return;
315  }
316  if (!gprs_sendmode && (millis() - last_send) < SENDING_INTERVAL
317  && myBuffer.available() < MAX_BUFFER_AVAILABLE)
318  return;
319  if (tx_error>1 && (millis() - last_try) < NEXT_TRY_INTERVAL){
320  return;
321  }
322 #if SKETCH_DEBUG
323  Serial.print("Send: ");
324  Serial.print(millis());
325  Serial.print(" ");
326  Serial.println(last_send);
327 #endif
328  last_send = millis();
329  last_try = millis();
330  gprs_sendmode=1;
331 
332  if (tx_res = client.sendMultiFromBuffer(MAX_BUFFER_AVAILABLE)) {
333  tx_error++;
334  } else {
335  tx_error = 0;
336 #if (BOARD == GBoardPro)
337  unsigned long current_time=client.now().get();
338  unsigned long max_dev=7200;
339  if(myBuffer.available()) max_dev=10;
340  else gprs_sendmode=0;
341 
342  if( current_time-myRTC.now().get()<max_dev || myRTC.now().get()-current_time<max_dev )
343  myRTC.adjust(current_time);
344 #endif
345  }
346  tx_blink = tx_res + 1;
347 
348 #if SKETCH_DEBUG
349  Serial.print("TX Error: ");
350  Serial.print(millis());
351  Serial.print(" ");
352  Serial.println(tx_error);
353 #endif
354  if (tx_error % 8 == 7) {
355  client.softSwitch();
356  client.startFrame(BayEOS_Message);
357  client.addToPayload("TX-ERROR SoftSwitch");
358  client.writeToBuffer();
359  startGPRS();
360  }
361 
362 }
unsigned long available(void)
Definition: BayEOSBuffer.cpp:78
uint8_t addChannelValue(float v, uint8_t channel_number=0)
Definition: BayEOS.cpp:61
uint8_t writeToBuffer(void)
Definition: BayEOS.cpp:322
void startFrame(void)
Definition: BayEOS.cpp:8
void startOriginFrame(const char *o, uint8_t routed=0)
Definition: BayEOS.cpp:20
uint8_t addToPayload(uint8_t b)
Definition: BayEOS.h:469
void startDataFrame(uint8_t subtype=BayEOS_Float32le, uint8_t checksum=0)
Definition: BayEOS.cpp:12