Advertisement
Guest User

Untitled

a guest
Jul 11th, 2017
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.98 KB | None | 0 0
  1. /*******************************************************************************
  2. * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
  3. *
  4. * Permission is hereby granted, free of charge, to anyone
  5. * obtaining a copy of this document and accompanying files,
  6. * to do whatever they want with them without any restriction,
  7. * including, but not limited to, copying, modification and redistribution.
  8. * NO WARRANTY OF ANY KIND IS PROVIDED.
  9. *
  10. * This example sends a valid LoRaWAN packet with payload "Hello,
  11. * world!", using frequency and encryption settings matching those of
  12. * the (early prototype version of) The Things Network.
  13. *
  14. * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in g1,
  15. * 0.1% in g2).
  16. *
  17. * Change DEVADDR to a unique address!
  18. * See http://thethingsnetwork.org/wiki/AddressSpace
  19. *
  20. * Do not forget to define the radio type correctly in config.h.
  21. *
  22. *******************************************************************************/
  23.  
  24. // show debug statements; comment next line to disable debug statements
  25. #define DEBUG
  26.  
  27. //start merge lowpower
  28. #define SLEEP
  29.  
  30. #ifdef SLEEP
  31. #include "LowPower.h"
  32. bool next = true;
  33. #endif
  34. //end merge lowpower
  35.  
  36. #include <lmic.h>
  37. #include <hal/hal.h>
  38. #include <SPI.h>
  39.  
  40. #include <OneWire.h>
  41.  
  42. // LoRaWAN NwkSKey, network session key
  43. // This is the default Semtech key, which is used by the prototype TTN
  44. // network initially.
  45. static const PROGMEM u1_t NWKSKEY[16] = { KEY HERE };
  46.  
  47. // LoRaWAN AppSKey, application session key
  48. // This is the default Semtech key, which is used by the prototype TTN
  49. // network initially.
  50. static const u1_t PROGMEM APPSKEY[16] = { KEY HERE };
  51.  
  52. // LoRaWAN end-device address (DevAddr)
  53. // See http://thethingsnetwork.org/wiki/AddressSpace
  54. static const u4_t DEVADDR = KEY HERE;
  55.  
  56. // These callbacks are only used in over-the-air activation, so they are
  57. // left empty here (we cannot leave them out completely unless
  58. // DISABLE_JOIN is set in config.h, otherwise the linker will complain).
  59. void os_getArtEui (u1_t* buf) { }
  60. void os_getDevEui (u1_t* buf) { }
  61. void os_getDevKey (u1_t* buf) { }
  62.  
  63. static osjob_t sendjob;
  64.  
  65. // Schedule TX every this many seconds (might become longer due to duty
  66. // cycle limitations).
  67. const unsigned TX_INTERVAL = 60;
  68.  
  69. // Pin mapping
  70. const lmic_pinmap lmic_pins = {
  71. .nss = 10,
  72. .rxtx = LMIC_UNUSED_PIN,
  73. .rst = 9,
  74. .dio = {2, 6, 7},
  75. };
  76.  
  77. // DS18S20 Temperature chip i/o
  78. OneWire ds(5); // on pin 10
  79.  
  80. void onEvent (ev_t ev) {
  81. switch(ev) {
  82. case EV_SCAN_TIMEOUT:
  83. Serial.println(F("EV_SCAN_TIMEOUT"));
  84. break;
  85. case EV_BEACON_FOUND:
  86. Serial.println(F("EV_BEACON_FOUND"));
  87. break;
  88. case EV_BEACON_MISSED:
  89. Serial.println(F("EV_BEACON_MISSED"));
  90. break;
  91. case EV_BEACON_TRACKED:
  92. Serial.println(F("EV_BEACON_TRACKED"));
  93. break;
  94. case EV_JOINING:
  95. Serial.println(F("EV_JOINING"));
  96. break;
  97. case EV_JOINED:
  98. Serial.println(F("EV_JOINED"));
  99. break;
  100. case EV_RFU1:
  101. Serial.println(F("EV_RFU1"));
  102. break;
  103. case EV_JOIN_FAILED:
  104. Serial.println(F("EV_JOIN_FAILED"));
  105. break;
  106. case EV_REJOIN_FAILED:
  107. Serial.println(F("EV_REJOIN_FAILED"));
  108. break;
  109. break;
  110. case EV_TXCOMPLETE:
  111. Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
  112. if(LMIC.dataLen) {
  113. // data received in rx slot after tx
  114. Serial.print(F("Data Received: "));
  115. Serial.write(LMIC.frame+LMIC.dataBeg, LMIC.dataLen);
  116. Serial.println();
  117. }
  118. // Schedule next transmission
  119. // start merge lowpower
  120. // os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); // disabled for merge
  121.  
  122. #ifndef SLEEP
  123. os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
  124. #else
  125. next = true;
  126. #endif
  127.  
  128. // end merge lowpower
  129. break;
  130. case EV_LOST_TSYNC:
  131. Serial.println(F("EV_LOST_TSYNC"));
  132. break;
  133. case EV_RESET:
  134. Serial.println(F("EV_RESET"));
  135. break;
  136. case EV_RXCOMPLETE:
  137. // data received in ping slot
  138. Serial.println(F("EV_RXCOMPLETE"));
  139. break;
  140. case EV_LINK_DEAD:
  141. Serial.println(F("EV_LINK_DEAD"));
  142. break;
  143. case EV_LINK_ALIVE:
  144. Serial.println(F("EV_LINK_ALIVE"));
  145. break;
  146. default:
  147. Serial.println(F("Unknown event"));
  148. break;
  149. }
  150. }
  151.  
  152. void do_send(osjob_t* j){
  153.  
  154. float celsius = GetTemp();
  155. Serial.print("Temperature: ");
  156. Serial.println(celsius);
  157.  
  158. //only send when no error condition 995 before
  159. if (celsius <= 1000) {
  160. int16_t temp = int16_t(celsius * 100);
  161. uint8_t data[3];
  162. data[0] = 0x00; //first byte is send as 00 to recognise this is a temperature
  163. data[1] = temp >> 8;
  164. data[2] = temp & 0xFF;
  165.  
  166. #ifdef DEBUG
  167. byte i;
  168. Serial.print("data send =");
  169. for( i = 0; i < sizeof(data); i++) {
  170. Serial.write(' ');
  171. Serial.print(data[i], HEX);
  172. }
  173. Serial.println();
  174. #endif
  175.  
  176. // Check if there is not a current TX/RX job running
  177. if (LMIC.opmode & OP_TXRXPEND) {
  178. Serial.println(F("OP_TXRXPEND, not sending"));
  179. } else {
  180. // Prepare upstream data transmission at the next possible time.
  181. LMIC_setTxData2(1, data, sizeof(data), 0);
  182. Serial.println(F("Packet queued"));
  183. }
  184. } else {
  185. Serial.print("Error reading sensor: ");
  186. Serial.println(celsius);
  187. }
  188. }
  189.  
  190. void setup() {
  191. Serial.begin(9600);
  192. Serial.println(F("Starting ....."));
  193.  
  194. #ifdef DEBUG
  195. float A = GetTemp();
  196. Serial.print("Temp during setup: ");
  197. Serial.println(A);
  198. #endif
  199.  
  200. #ifdef VCC_ENABLE
  201. // For Pinoccio Scout boards
  202. pinMode(VCC_ENABLE, OUTPUT);
  203. digitalWrite(VCC_ENABLE, HIGH);
  204. delay(1000);
  205. #endif
  206.  
  207. // LMIC init
  208. os_init();
  209. // Reset the MAC state. Session and pending data transfers will be discarded.
  210. LMIC_reset();
  211.  
  212. // Set static session parameters. Instead of dynamically establishing a session
  213. // by joining the network, precomputed session parameters are be provided.
  214. #ifdef PROGMEM
  215. // On AVR, these values are stored in flash and only copied to RAM
  216. // once. Copy them to a temporary buffer here, LMIC_setSession will
  217. // copy them into a buffer of its own again.
  218. uint8_t appskey[sizeof(APPSKEY)];
  219. uint8_t nwkskey[sizeof(NWKSKEY)];
  220. memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
  221. memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
  222. LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);
  223. #else
  224. // If not running an AVR with PROGMEM, just use the arrays directly
  225. LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY);
  226. #endif
  227.  
  228. // Set up the channels used by the Things Network, which corresponds
  229. // to the defaults of most gateways. Without this, only three base
  230. // channels from the LoRaWAN specification are used, which certainly
  231. // works, so it is good for debugging, but can overload those
  232. // frequencies, so be sure to configure the full frequency range of
  233. // your network here (unless your network autoconfigures them).
  234. // Setting up channels should happen after LMIC_setSession, as that
  235. // configures the minimal channel set.
  236. LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
  237. LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
  238. LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
  239. LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
  240. LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
  241. LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
  242. LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
  243. LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
  244. LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
  245. // TTN defines an additional channel at 869.525Mhz using SF9 for class B
  246. // devices' ping slots. LMIC does not have an easy way to define set this
  247. // frequency and support for class B is spotty and untested, so this
  248. // frequency is not configured here.
  249.  
  250. // Disable link check validation
  251. LMIC_setLinkCheckMode(0);
  252.  
  253. // Set data rate and transmit power (note: txpow seems to be ignored by the library)
  254. LMIC_setDrTxpow(DR_SF7,14);
  255.  
  256. // Start job
  257. do_send(&sendjob);
  258. }
  259. // start merge lowpower (replaced the std loop())
  260.  
  261. void loop() {
  262.  
  263. #ifndef SLEEP
  264.  
  265. os_runloop_once();
  266.  
  267. #else
  268.  
  269. if (next == false) {
  270.  
  271. os_runloop_once();
  272.  
  273. } else {
  274.  
  275. int sleepcycles = TX_INTERVAL / 8; // calculate the number of sleepcycles (8s) given the TX_INTERVAL
  276. #ifdef DEBUG
  277. Serial.print(F("Enter sleeping for "));
  278. Serial.print(sleepcycles);
  279. Serial.println(F(" cycles of 8 seconds"));
  280. #endif
  281. delay(1000); // give the serial print chance to complete
  282. for (int i=0; i<sleepcycles; i++) {
  283. // Enter power down state for 8 s with ADC and BOD module disabled
  284. LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  285. //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF);
  286. }
  287. #ifdef DEBUG
  288. Serial.println(F("Sleep complete"));
  289. #endif
  290. next = false;
  291. // Start job
  292. do_send(&sendjob);
  293. }
  294.  
  295. #endif
  296. } //added to mail, mq
  297.  
  298.  
  299.  
  300. // end merge lowpower
  301. float GetTemp()
  302. {
  303. byte i;
  304. byte present = 0;
  305. byte type_s;
  306. byte data[12];
  307. byte addr[8];
  308. float celsius, fahrenheit;
  309.  
  310. #ifdef DEBUG
  311. Serial.println(" ");
  312. Serial.println("GetTemp function");
  313. #endif
  314.  
  315. ds.reset_search();
  316. if ( !ds.search(addr)) {
  317. Serial.println("No more addresses.");
  318. ds.reset_search();
  319. delay(250);
  320. return(999);
  321. }
  322.  
  323. #ifdef DEBUG
  324. Serial.print("ROM =");
  325. for( i = 0; i < 8; i++) {
  326. Serial.write(' ');
  327. Serial.print(addr[i], HEX);
  328. }
  329.  
  330. if (OneWire::crc8(addr, 7) != addr[7]) {
  331. Serial.println("CRC is not valid!");
  332. return(998);
  333. }
  334. Serial.println();
  335. #endif
  336.  
  337. // the first ROM byte indicates which chip
  338. switch (addr[0]) {
  339. case 0x10:
  340. #ifdef DEBUG
  341. Serial.println(" Chip = DS18S20"); // or old DS1820
  342. #endif
  343. type_s = 1;
  344. break;
  345. case 0x28:
  346. #ifdef DEBUG
  347. Serial.println(" Chip = DS18B20");
  348. #endif
  349. type_s = 0;
  350. break;
  351. case 0x22:
  352. #ifdef DEBUG
  353. Serial.println(" Chip = DS1822");
  354. #endif
  355. type_s = 0;
  356. break;
  357. default:
  358. #ifdef DEBUG
  359. Serial.println(" Device is not a DS18x20 family device.");
  360. #endif
  361. return(997);
  362. }
  363.  
  364. ds.reset();
  365. ds.select(addr);
  366. ds.write(0x44, 1); // start conversion, with parasite power on at the end
  367.  
  368. delay(1000); // maybe 750ms is enough, maybe not
  369. // we might do a ds.depower() here, but the reset will take care of it.
  370.  
  371. present = ds.reset();
  372. ds.select(addr);
  373. ds.write(0xBE); // Read Scratchpad
  374.  
  375. #ifdef DEBUG
  376. Serial.print(" Data = ");
  377. Serial.print(present, HEX);
  378. Serial.print(" ");
  379. #endif
  380. for ( i = 0; i < 9; i++) { // we need 9 bytes
  381. data[i] = ds.read();
  382. #ifdef DEBUG
  383. Serial.print(data[i], HEX);
  384. Serial.print(" ");
  385. #endif
  386. }
  387. #ifdef DEBUG
  388. Serial.print(" CRC=");
  389. Serial.print(OneWire::crc8(data, 8), HEX);
  390. Serial.println();
  391. #endif
  392.  
  393. // Convert the data to actual temperature
  394. // because the result is a 16 bit signed integer, it should
  395. // be stored to an "int16_t" type, which is always 16 bits
  396. // even when compiled on a 32 bit processor.
  397. int16_t raw = (data[1] << 8) | data[0];
  398. if (type_s) {
  399. raw = raw << 3; // 9 bit resolution default
  400. if (data[7] == 0x10) {
  401. // "count remain" gives full 12 bit resolution
  402. raw = (raw & 0xFFF0) + 12 - data[6];
  403. }
  404. } else {
  405. byte cfg = (data[4] & 0x60);
  406. // at lower res, the low bits are undefined, so let's zero them
  407. if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
  408. else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
  409. else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
  410. //// default is 12 bit resolution, 750 ms conversion time
  411. }
  412.  
  413. celsius = (float)raw / 16.0;
  414. return celsius;
  415. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement