BayEOSArduino Library
SerialRouterBoard.h
1 /*
2  * This is a header file, designed to make scetches of Low Current Board easier
3  *
4  * It depends on some conventions:
5  * 1. bayeos.client must be named "client"
6  * 2. Changes in CONSTANTS must be declared before include
7  */
8 
9 #include <Sleep.h>
10 #include <RTClib.h>
11 #include <BayEOSBufferSPIFlash.h>
12 #include <BaySerial.h>
13 BaySerial rx_client=BaySerial(Serial);
14 uint16_t rx1_count, rx1_error;
15 #define CTS_PIN 6
16 #define TXRX_PIN 4
17 
18 #ifdef NRF24_CHANNEL
19 #include <RF24.h>
20 RF24 radio(9, 10);
21 uint16_t rx2_count, rx2_error;
22 
23 #endif
24 
25 
26 uint8_t tx_res, tx_error;
27 SPIFlash flash(8);
28 BayEOSBufferSPIFlash myBuffer;
29 uint8_t gprs_status; //1 = 0n, 0 = Off
30 
31 #ifndef BAT_MULTIPLIER
32 #define BAT_MULTIPLIER 3.3*200/100/1023
33 #endif
34 
35 #ifndef TICKS_PER_SECOND
36 #define TICKS_PER_SECOND 16
37 #endif
38 
39 #ifndef SAMPLING_INT
40 #define SAMPLING_INT 128
41 #endif
42 
43 #ifndef BAUD_RATE
44 #define BAUD_RATE 38400
45 #endif
46 
47 #define LED_PIN 5
48 #define LED_RX1 3
49 #define LED_RX2 2
50 #define POWER_PIN 7
51 
52 volatile uint16_t ticks;
53 volatile uint8_t action;
54 
55 
56 #define ISSET_ACTION(nr) ((1<<nr)&action)
57 #define UNSET_ACTION(nr) (action&= ~(1<<nr))
58 
59 #ifndef ACTION_COUNT
60 #define ACTION_COUNT 1
61 #endif
62 
63 
64 
65 #ifndef CHECKSUM_FRAMES
66 #define CHECKSUM_FRAMES 0
67 #endif
68 
69 #ifndef RESET_COUNT
70 #define RESET_COUNT 8
71 #endif
72 
73 
74 #if TICKS_PER_SECOND>3
75 #define LED_TICK_DIV (TICKS_PER_SECOND/4)
76 #else
77 #define LED_TICK_DIV 1
78 #endif
79 
80 
81 #if RESET_COUNT
82 volatile uint8_t action0_pending_count=0;
83 #endif
84 
85 volatile uint8_t seconds;
86 volatile unsigned long current_micros, last_micros;
87 volatile uint8_t adjust_osccal_flag;
88 volatile uint8_t led_blink = 0;
89 volatile uint8_t led_blink_rx1 = 0;
90 volatile uint8_t led_blink_rx2 = 0;
91 volatile uint8_t led_blink_rx3 = 0;
92 
93 #ifndef SENDING_INTERVAL
94 #define SENDING_INTERVAL 120000L
95 #endif
96 
97 #ifndef NEXT_TRY_INTERVAL
98 #define NEXT_TRY_INTERVAL 300000L
99 #endif
100 
101 #ifndef MAX_BUFFER_AVAILABLE
102 #define MAX_BUFFER_AVAILABLE 2000
103 #endif
104 
105 float batLCB;
106 RTC_Timer2 myRTC;
107 
108 #ifdef RTC_SECOND_CORRECT
109 volatile long rtc_seconds_correct;
110 #endif
111 
112 #ifdef GPRS_CONFIG
113 #include <BayTCPSim900.h>
114 BayGPRS client(Serial, 0); //No Power Pin
115 #else
116 #ifdef WLAN_CONFIG
117 #include <BayTCPESP8266.h>
118 BayESP8266 client(Serial, POWER_PIN);
119 #else
120 #include <BayDebug.h>
121 BayDebug client(Serial);
122 #define DEBUG_CONFIG 1
123 #endif
124 #endif
125 
126 
127 /*
128  * ISR for timer2
129  * increments RTC-Time
130  * sets action bits
131  */
132 ISR(TIMER2_OVF_vect) {
133  ticks++;
134  if(adjust_osccal_flag){
135  last_micros=current_micros;
136  current_micros=micros();
137  adjust_osccal_flag++;
138  if(adjust_osccal_flag>2){
139  if((current_micros-last_micros)>(1005000L/TICKS_PER_SECOND)){
140  if(OSCCAL) OSCCAL--;
141  else adjust_osccal_flag=0; //reached limit!
142  }
143  else if((current_micros-last_micros)<(995000L/TICKS_PER_SECOND)){
144  if(OSCCAL<255) OSCCAL++;
145  else adjust_osccal_flag=0; //reached limit!
146  }
147  else {
148  //Timing is ok :-)
149  adjust_osccal_flag=0;
150  }
151 
152  }
153 
154  }
155 
156  if((ticks % TICKS_PER_SECOND)==0) {
157  myRTC._seconds ++; //RTC_Timer2.get() and adjust() are interrupt save now!
158  seconds++;
159 #ifdef RTC_SECOND_CORRECT
160 
161 #if RTC_SECOND_CORRECT < 0
162  rtc_seconds_correct--;
163  if(rtc_seconds_correct<=RTC_SECOND_CORRECT){
164  rtc_seconds_correct=0;
165  myRTC._seconds --;
166  seconds--;
167  }
168 #else
169  rtc_seconds_correct++;
170  if(rtc_seconds_correct>=RTC_SECOND_CORRECT){
171  rtc_seconds_correct=0;
172  myRTC._seconds ++;
173  seconds++;
174  }
175 
176 #endif
177 #endif
178  uint16_t tick_mod=myRTC._seconds%SAMPLING_INT;
179  if(tick_mod<ACTION_COUNT) {
180 #if RESET_COUNT
181  if(tick_mod==0){
182  if(ISSET_ACTION(0))
183  action0_pending_count++;
184 
185  else
186  action0_pending_count=0;
187  if(action0_pending_count>RESET_COUNT)
188  asm volatile (" jmp 0"); //restart programm
189 
190  }
191 #endif
192  action|=(1<<tick_mod);
193  } else {
194  action|=(1<<7);
195  }
196  }
197 
198  if((led_blink>0) && ((ticks%LED_TICK_DIV)==0)) {
199  if(digitalRead(LED_PIN)) led_blink--;
200  digitalWrite(LED_PIN,!digitalRead(LED_PIN));
201  }
202  if((led_blink_rx1>0) && ((ticks%LED_TICK_DIV)==0)) {
203  if(digitalRead(LED_RX1)) led_blink_rx1--;
204  digitalWrite(LED_RX1,!digitalRead(LED_RX1));
205  }
206 #ifdef NRF24_CHANNEL
207  if((led_blink_rx2>0) && ((ticks%LED_TICK_DIV)==0)) {
208  if(digitalRead(LED_RX2)) led_blink_rx2--;
209  digitalWrite(LED_RX2,!digitalRead(LED_RX2));
210  }
211 #endif
212 }
213 
214 /*
215  * Adjust the OSCCAL of internal oscillator using TIMER2 RTC
216  */
217 void adjust_OSCCAL(void){
218  adjust_osccal_flag=1;
219  while(adjust_osccal_flag){
220  delay(1);
221  }
222 }
223 
224 
225 
226 /*
227  * blinkLED is done by timer2
228  */
229 void blinkLED(uint8_t times) {
230  if (LED_PIN > -1)
231  led_blink = times;
232 }
233 
234 void sleepLCB() {
235  Sleep.sleep(TIMER2_ON, SLEEP_MODE_PWR_SAVE);
236 }
237 
238 void delayLCB(uint16_t _millis) {
239  _millis /= (1000 / TICKS_PER_SECOND);
240  noInterrupts();
241  uint16_t end_ticks = ticks + _millis + 2;
242  interrupts();
243  do {
244  sleepLCB();
245  } while ((ticks != end_ticks));
246 }
247 
248 /*
249  * init Time2 and LED pin
250  */
251 void initLCB() {
252 #if TICKS_PER_SECOND==128
253  Sleep.setupTimer2(1); //init timer2 to 0,0078125sec
254 #elif TICKS_PER_SECOND==16
255  Sleep.setupTimer2(2); //init timer2 to 0,0625sec
256 #elif TICKS_PER_SECOND==4
257  Sleep.setupTimer2(3); //init timer2 to 0,25sec
258 #elif TICKS_PER_SECOND==2
259  Sleep.setupTimer2(4); //init timer2 to 0,5sec
260 #elif TICKS_PER_SECOND==1
261  Sleep.setupTimer2(5); //init timer2 to 1sec
262 #else
263 #error unsupported TICKS_PER_SECOND
264 #endif
265 
266  pinMode(TXRX_PIN, OUTPUT);
267  digitalWrite(TXRX_PIN,0); //TX-MODE
268  pinMode(CTS_PIN,OUTPUT);
269  digitalWrite(CTS_PIN,0); //Block RX
270 
271  pinMode(LED_PIN, OUTPUT);
272  pinMode(LED_RX1, OUTPUT);
273 #ifdef NRF24_CHANNEL
274  pinMode(LED_RX2, OUTPUT);
275 #endif
276 
277  myBuffer.init(flash); //This will restore old pointers
278  myBuffer.skip();
279  myBuffer.setRTC(myRTC, 0); //Nutze RTC relativ!
280  //We could also try to use absolute times received from GPRS!
281  client.setBuffer(myBuffer);
282  rx_client.setBuffer(myBuffer);
283  pinMode(POWER_PIN, OUTPUT);
284  digitalWrite(POWER_PIN, HIGH);
285  blinkLED(2);
286  adjust_OSCCAL();
287 #ifdef GPRS_CONFIG
288  client.readConfigFromStringPGM(PSTR(GPRS_CONFIG));
289  tx_res = client.begin(38400);
290 #else
291 #ifdef WLAN_CONFIG
292  client.readConfigFromStringPGM(PSTR(WLAN_CONFIG));
293  tx_res = client.begin(38400);
294 #else
295  client.begin(38400,1);
296 #endif
297 #endif
298 
299 #ifdef GPRS_CONFIG
300  if (! tx_res) myRTC.adjust(client.now());
301 #endif
302  blinkLED(tx_res + 1);
303  /*
304  1 == OK
305  2 == NO Communication
306  3 == PIN failed
307  4 == PIN locked
308  5 == Not CREG
309  6 == Not CGATT
310  7 == No SIM Card
311  */
312  delay(2000);
313 
314  tx_res = client.sendMessage("Router started");
315  blinkLED(tx_res + 1);
316  delay(1000 + tx_res * 500);
317 
318  /*
319  1 == OK
320  2 == no success
321  3 == timeout
322  4 == network timeout
323  5 == gprs modem timeout
324  */
325 // if (myRTC.now().get() < 2000) myBuffer.skip(); //got no time! skip the unread frames in Buffer!!
326  gprs_status = 1;
327 }
328 #ifdef NRF24_CHANNEL
329 
330 void initRF24(void) {
331  radio.begin();
332  radio.powerUp();
333  radio.setChannel(NRF24_CHANNEL);
334  radio.setPayloadSize(32);
335  radio.enableDynamicPayloads();
336  radio.setCRCLength(RF24_CRC_16);
337  radio.setDataRate(RF24_250KBPS);
338  radio.setPALevel(RF24_PA_MAX);
339  radio.setRetries(15, 15);
340  radio.setAutoAck(true);
341  radio.openReadingPipe(0, pipe_0);
342  radio.openReadingPipe(1, pipe_1);
343  radio.openReadingPipe(2, pipe_2);
344  radio.openReadingPipe(3, pipe_3);
345  radio.openReadingPipe(4, pipe_4);
346  radio.openReadingPipe(5, pipe_5);
347 
348 }
349 
350 uint8_t handleRF24(void) {
351  uint8_t pipe_num, len;
352  uint8_t payload[32];
353  char origin[] = "A0";
354 #ifdef RF24_P1_LETTER
355  origin[0]=RF24_P1_LETTER;
356 #endif
357  uint8_t count=0;
358  uint8_t rx = 0;
359  while (radio.available(&pipe_num)) {
360  count++;
361  if (len = radio.getDynamicPayloadSize()) {
362  rx++;
363  origin[1] = '0' + pipe_num;
364  client.startOriginFrame(origin, 1); //Routed Origin!
365  if (len > 32)
366  len = 32;
367  radio.read(payload, len);
368  for (uint8_t i = 0; i < len; i++) {
369  client.addToPayload(payload[i]);
370  }
371 #if WITH_RF24_CHECKSUM
372  if(! client.validateChecksum()) {
373  client.writeToBuffer();
374  led_blink_rx1 = 1;
375  rx2_count++;
376  } else
377  rx2_error++;
378 #else
379  client.writeToBuffer();
380  led_blink_rx1 = 1;
381  rx2_count++;
382 #endif
383 
384  } else {
385  rx2_error++;
386  }
387  if (count > 10)
388  break;
389  }
390  if (count > 10)
391  initRF24();
392 
393  delay(2);
394  return rx;
395 }
396 #endif
397 
398 void checkAction0(void){
399  if(! ISSET_ACTION(0)) return;
400  UNSET_ACTION(0);
401 
402  digitalWrite(POWER_PIN, HIGH);
403  digitalWrite(TXRX_PIN,0); //TX-MODE
404  pinMode(CTS_PIN,OUTPUT);
405  digitalWrite(CTS_PIN,0); //Block RX
406  analogReference (DEFAULT);
407  if(! gprs_status) delayLCB(1000);
408 #ifdef WLAN_CONFIG
409  delayLCB(100);
410 #endif
411  adjust_OSCCAL();
412  batLCB = BAT_MULTIPLIER * analogRead(A7);
413 
414  client.startDataFrame();
415  client.addChannelValue(millis() / 1000);
416  client.addChannelValue(myBuffer.writePos());
417  client.addChannelValue(myBuffer.readPos());
418 #ifdef GPRS_CONFIG
419  if (gprs_status)
420  client.addChannelValue(client.getRSSI());
421  else
422  client.addChannelValue(0);
423 #else
424  client.addChannelValue(0);
425 #endif
426  client.addChannelValue(batLCB);
427  client.addChannelValue(tx_error);
428  client.addChannelValue(tx_res);
429  client.addChannelValue(rx1_count);
430  client.addChannelValue(rx1_error);
431  rx1_count = 0;
432  rx1_error = 0;
433 #ifdef NRF24_CHANNEL
434  client.addChannelValue(rx2_count);
435  client.addChannelValue(rx2_error);
436  rx2_count = 0;
437  rx2_error = 0;
438 #endif
439  client.writeToBuffer();
440 
441 #ifndef DEBUG_CONFIG
442  if (! gprs_status && batLCB > 3.9) {
443  client.begin(38400);
444 #ifdef NRF24_CHANNEL
445  initRF24();
446 #endif
447  gprs_status = 1;
448  }
449  if (batLCB < 3.7) {
450  if (gprs_status) {
451 #ifdef NRF24_CHANNEL
452  radio.powerDown();
453 #endif
454  gprs_status = 0;
455  }
456  }
457 #endif
458 
459  if (gprs_status) {
460 #ifndef DEBUG_CONFIG
461  tx_res = client.sendMultiFromBuffer(1000);
462 #else
463  tx_res = client.sendFromBuffer();
464 #endif
465  if(tx_res) tx_error++;
466  else tx_error=0;
467  blinkLED(tx_res + 1);
468 #ifndef DEBUG_CONFIG
469  if(tx_error>5 && (tx_error % 5)==0){
470  digitalWrite(POWER_PIN, LOW);
471  delay(1000);
472  digitalWrite(POWER_PIN, HIGH);
473  client.begin(38400);
474  }
475 #endif
476 
477  while (! tx_res && myBuffer.available() && ! ISSET_ACTION(0)) {
478 #ifdef NRF24_CHANNEL
479  handleRF24();
480 #endif
481 
482 #ifndef DEBUG_CONFIG
483  tx_res = client.sendMultiFromBuffer(1000);
484 #else
485  tx_res = client.sendFromBuffer();
486 #endif
487  blinkLED(tx_res + 1);
488  }
489  } else {
490  digitalWrite(POWER_PIN, LOW);
491  }
492 #ifdef DEBUG_CONFIG
493  Serial.flush();
494 #endif
495  digitalWrite(TXRX_PIN,1); //RX-MODE
496  pinMode(CTS_PIN,INPUT);//Free RX
497 
498 #ifdef WLAN_CONFIG
499  client.powerDown();
500 #endif
501 
502 
503 }
504 
505 void startLCB() {
506  blinkLED(3);
507  delayLCB(2000);
508  noInterrupts();
509  action = 0;
510  ticks = 0;
511  myRTC._seconds=SAMPLING_INT-1;
512  interrupts();
513 }
514 
515 void readRX(){
516  uint8_t res = rx_client.readIntoPayload();
517  if (res == 0) {
518  rx_client.writeToBuffer();
519  led_blink_rx1=1;
520  rx1_count++;
521  } else if (res == 1) {
522  rx1_error++;
523  }
524 }
Definition: BayDebug.h:54
unsigned long available(void)
Definition: BayEOSBuffer.cpp:78
void setRTC(RTC &rtc, uint8_t timeType=RTC_ABSOLUTE_SECONDS)
Definition: BayEOSBuffer.cpp:258
void skip(void)
Definition: BayEOSBuffer.cpp:173
Definition: BayEOSBufferSPIFlash.h:6
void init(SPIFlash &flash, uint8_t flush_skip=20)
Definition: BayEOSBufferSPIFlash.cpp:7
void setBuffer(BayEOSBuffer &buffer, uint16_t max_skip=0)
Definition: BayEOS.h:452
uint8_t addChannelValue(float v, uint8_t channel_number=0)
Definition: BayEOS.cpp:61
uint8_t writeToBuffer(void)
Definition: BayEOS.cpp:322
uint8_t sendMessage(const char *s)
Definition: BayEOS.cpp:295
uint8_t sendFromBuffer(void)
Definition: BayEOS.cpp:394
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
Definition: BayTCPSim900.h:144
Definition: BaySerial.h:106
uint8_t readIntoPayload(int timeout=0)
Definition: BaySerial.cpp:95
Definition: RTClib.h:39
Definition: SPIFlash.h:32