Advertisement
Guest User

Untitled

a guest
Feb 26th, 2020
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.19 KB | None | 0 0
  1.  
  2. #include <Arduino.h>
  3. #include <Sodaq_RN2483.h>
  4. #include <SPI.h>
  5. #include <RN487x_BLE.h>
  6. #include <RTCTimer.h>
  7. #include <RTCZero.h>
  8.  
  9. #define CONSOLE_STREAM SERIAL_PORT_MONITOR
  10.  
  11. #define bleSerial Serial1 // Bluetooth module Serial
  12. #define loraSerial Serial2 // LoRa module Serial
  13.  
  14. #define LORA_BAUD 57600
  15. #define DEBUG_BAUD 57600
  16.  
  17. #define NIBBLE_TO_HEX_CHAR(i) ((i <= 9) ? ('0' + i) : ('A' - 10 + i))
  18. #define HIGH_NIBBLE(i) ((i >> 4) & 0x0F)
  19. #define LOW_NIBBLE(i) (i & 0x0F)
  20.  
  21. RTCZero rtc;
  22. RTCTimer timer;
  23.  
  24. volatile bool minuteFlag;
  25.  
  26. //
  27. // setup your constants here!!
  28. //
  29. const uint8_t records_to_send = 2; // set this to change the amount of records to send
  30. const uint8_t record_every_x_minutes = 1; // set this to the desired interval in minutes
  31. const uint8_t spreading_factor = 7; // set this to the desired LoRa spreading factor
  32.  
  33.  
  34. // *****************************************************************************************
  35. // LoRa communication setup!
  36.  
  37. // true: use OTAA
  38. // false: use ABP
  39. bool OTAA = true;
  40.  
  41. // ABP setup (device address)
  42. // USE YOUR OWN KEYS!
  43. const uint8_t devAddr[4] =
  44. {
  45. 0x26, 0x01, 0x27, 0xD6
  46. };
  47.  
  48. // application session key
  49. // USE YOUR OWN KEYS!
  50. const uint8_t appSKey[16] =
  51. {
  52. 0x86, 0xB1, 0x88, 0xD3, 0xD6, 0xCD, 0xEF, 0x53, 0x12, 0x0A, 0xA7, 0x98, 0x38, 0x7D, 0x70, 0x1A
  53. };
  54.  
  55. // network session key
  56. // USE YOUR OWN KEYS!
  57. const uint8_t nwkSKey[16] =
  58. {
  59. 0x56, 0x69, 0x47, 0x84, 0xC9, 0x6D, 0xE7, 0x4F, 0x07, 0x0D, 0xF1, 0x80, 0xB2, 0x72, 0x27, 0x7D
  60. };
  61.  
  62. // OTAA (device EUI) - use msb formatting
  63. // With using the GetHWEUI() function the HWEUI will be used
  64. static uint8_t DevEUI[8]
  65. {
  66. 0x00, 0x04, 0xA3, 0x0B, 0x00, 0x1F, 0xF9, 0x08
  67. };
  68.  
  69. const uint8_t AppEUI[8] =
  70. {
  71. 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x02, 0xB0, 0xAB
  72. };
  73.  
  74. const uint8_t AppKey[16] =
  75. {
  76. 0x5B, 0xC9, 0xD8, 0xC8, 0x4B, 0xBA, 0x8C, 0x80, 0xD6, 0x2A, 0x17, 0xF5, 0x78, 0x52, 0xD2, 0xB5
  77. };
  78.  
  79. // *****************************************************************************************
  80. // setup
  81.  
  82. bool LoRa_sleeps = false;
  83. uint8_t message[records_to_send*2];
  84.  
  85. void setup()
  86. {
  87. sodaq_wdt_enable(WDT_PERIOD_8X); // Enable the wdt at maximum interval
  88. sodaq_wdt_reset();
  89. sodaq_wdt_safe_delay(5000);
  90.  
  91. pinMode(TEMP_SENSOR, INPUT);
  92.  
  93. initRtc();
  94.  
  95. SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // sets SAMD sleep mode to deep sleep
  96.  
  97. // networks
  98. loraSerial.begin(LoRaBee.getDefaultBaudRate());
  99. LoRaBee.init(loraSerial, LORA_RESET);
  100. setupLoRa(); // set the gears in motion
  101.  
  102. initRtcTimer(); // timer interrupt > 1 minute interval
  103.  
  104. sodaq_wdt_reset();
  105.  
  106. SerialUSB.flush();
  107. SerialUSB.end();
  108. USBDevice.detach();
  109. USB->DEVICE.CTRLA.reg &= ~USB_CTRLA_ENABLE; // Disable USB
  110.  
  111. sleep_setup();
  112. }
  113.  
  114. // *****************************************************************************************
  115. // loop
  116.  
  117. // array for temperature we wish to send;
  118. // here we're taking a 6-value (12 bytes) array to send at once
  119. // intended to measure every n*60 seconds, send every x messages.
  120.  
  121. const uint8_t measurements_to_send = 6;
  122. int temperature_array[measurements_to_send];
  123. uint8_t list_iter = 0; // variable to keep track of array index and when to send
  124.  
  125. void loop()
  126. {
  127. if (sodaq_wdt_flag) {
  128. sodaq_wdt_reset();
  129. sodaq_wdt_flag = false;
  130. }
  131.  
  132. if (minuteFlag) {
  133. timer.update();
  134. minuteFlag = false;
  135. }
  136.  
  137. systemSleep();
  138. }
  139.  
  140. // *****************************************************************************************
  141. // Sleep commands
  142.  
  143. void BT_powerdown()
  144. {
  145. rn487xBle.hwInit();
  146. bleSerial.begin(rn487xBle.getDefaultBaudRate());
  147. rn487xBle.initBleStream(&bleSerial);
  148. rn487xBle.enterCommandMode();
  149. rn487xBle.hwSleep();
  150. bleSerial.end();
  151. }
  152.  
  153. void sleep_setup()
  154. {
  155. // set FLASH to deep sleep & reset SPI pins for min. energy consumption
  156. DFlashUltraDeepSleep();
  157.  
  158. sleep_LoRa();
  159.  
  160. // RN4871 BT/BLE module sleep
  161. BT_powerdown();
  162. }
  163.  
  164. void systemSleep() // Since only LoRa and MCU awake, only set those to sleep
  165. {
  166. if (!LoRa_sleeps) // Skip if LoRa is asleep
  167. {
  168. sleep_LoRa();
  169. }
  170.  
  171. noInterrupts();
  172. if (!(sodaq_wdt_flag || minuteFlag)) {
  173. interrupts();
  174. debugSerial.println("Sleeping");
  175. __WFI(); // SAMD sleep
  176. }
  177. interrupts();
  178. }
  179.  
  180. void sleep_LoRa()
  181. {
  182. loraSerial.flush();
  183. LoRaBee.sleep();
  184. LoRa_sleeps = true;
  185. sodaq_wdt_safe_delay(5);
  186. }
  187.  
  188. void wake_LoRa()
  189. {
  190. LoRa_sleeps = false;
  191. LoRaBee.wakeUp();
  192. }
  193.  
  194.  
  195. // *****************************************************************************************
  196. // SST25PF040C Flash functions (SPI)
  197.  
  198. void DFlashUltraDeepSleep()
  199. {
  200. static const uint8_t SS_DFLASH = 44 ;
  201. // SPI initialisation
  202. SPI.begin();
  203.  
  204. // Initialise the CS pin for the data flash
  205. pinMode(SS_DFLASH, OUTPUT);
  206. digitalWrite(SS_DFLASH, HIGH);
  207.  
  208. transmit(0xB9);
  209.  
  210. SPI.end();
  211.  
  212. // Resets the pins used
  213. resetSPIPins();
  214. }
  215.  
  216. void transmit(uint8_t val)
  217. {
  218. SPISettings settings;
  219. digitalWrite(SS_DFLASH, LOW);
  220. SPI.beginTransaction(settings);
  221.  
  222. SPI.transfer(val);
  223.  
  224. SPI.endTransaction();
  225. digitalWrite(SS_DFLASH, HIGH);
  226.  
  227. delayMicroseconds(1000);
  228. }
  229.  
  230. void resetSPIPins()
  231. {
  232. resetPin(MISO);
  233. resetPin(MOSI);
  234. resetPin(SCK);
  235. resetPin(SS_DFLASH);
  236. }
  237.  
  238. void resetPin(uint8_t pin)
  239. {
  240. PORT->Group[g_APinDescription[pin].ulPort].
  241. PINCFG[g_APinDescription[pin].ulPin].reg=(uint8_t)(0);
  242. PORT->Group[g_APinDescription[pin].ulPort].
  243. DIRCLR.reg = (uint32_t)(1<Group[g_APinDescription[pin].ulPort].
  244. OUTCLR.reg = (uint32_t) (1<> 8) | negativeFlag;
  245. message[list_iter*2 + 1] = int_temp & 0xFF;
  246. }
  247.  
  248.  
  249.  
  250. // *****************************************************************************************
  251. // RTC functions
  252.  
  253. // Initializes the RTC
  254. void initRtc()
  255. {
  256. rtc.begin();
  257.  
  258. // Schedule the wakeup interrupt for every minute
  259. // Alarm is triggered 1 cycle after match
  260. rtc.setAlarmSeconds(59);
  261. rtc.enableAlarm(RTCZero::MATCH_SS); // alarm every minute
  262.  
  263. // Attach handler
  264. rtc.attachInterrupt(rtcAlarmHandler);
  265.  
  266. // This sets it to 2000-01-01
  267. rtc.setEpoch(0);
  268. }
  269.  
  270. // Runs every minute by the rtc alarm.
  271. void rtcAlarmHandler()
  272. {
  273. minuteFlag = true;
  274. }
  275.  
  276. // Initializes the RTC Timer
  277. void initRtcTimer()
  278. {
  279. debugSerial.println("init rtc timer");
  280. timer.setNowCallback(getNow); // set how to get the current time
  281. timer.allowMultipleEvents();
  282.  
  283. resetRtcTimerEvents();
  284. }
  285.  
  286.  
  287. void resetRtcTimerEvents()
  288. {
  289. // Schedule the default fix event (if applicable)
  290. timer.every(record_every_x_minutes * 60, measureTemperature);
  291. debugSerial.println("event set");
  292. }
  293.  
  294. // Returns current datetime in seconds since epoch
  295. uint32_t getNow()
  296. {
  297. return rtc.getEpoch();
  298. }
  299.  
  300. // Default event parameter
  301. void measureTemperature(uint32_t now)
  302. {
  303. getTemperature();
  304.  
  305. list_iter++;
  306.  
  307. if (!(list_iter < records_to_send)) {
  308. send_message((uint8_t*) &message, sizeof(message));
  309. list_iter = 0;
  310. }
  311. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement