Advertisement
BoogeyCZ

Untitled

Feb 18th, 2018
423
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.41 KB | None | 0 0
  1. //AVR
  2. #include <avr/sleep.h>
  3. #include <avr/wdt.h>
  4.  
  5. //Arduino
  6. #include <EEPROM.h>
  7.  
  8. //Third party
  9. #include <SerialCommand.h>
  10.  
  11. #include <U8g2lib.h>             // Display
  12. #include <ClosedCube_HDC1080.h>  // Temperature, humidity
  13. #include <RFM69.h>               // Wireless
  14. #include <Adafruit_TSL2561_U.h>  // Light Sensor
  15.  
  16.  
  17. #define SERIAL_BAUD 9600
  18. #define BUTTON_INTERRUPT_PIN 3
  19. #define LED_PIN 4
  20. const char ENCRYPTKEY[] PROGMEM = "TajneHeslo123456";
  21.  
  22. volatile bool powerDownEnabled = true;
  23. volatile bool wdtInterrupted = true; // To send data after power up
  24. uint8_t lastSource = 0;
  25. int16_t lastRssi = 0;
  26. long int prepis = 0;
  27.  
  28.  
  29. struct Settings
  30. {
  31.   byte networkid;
  32.   byte nodeid;
  33. };
  34.  
  35. Settings settings;
  36.  
  37. struct Packet
  38. {
  39.   float temperature;
  40.   float humidity;
  41.   uint32_t light;
  42. };
  43.  
  44. struct Hal
  45. {
  46.   bool tsl;
  47.   bool hdc;
  48. };
  49.  
  50. Hal hal;
  51.  
  52. SerialCommand SCmd;
  53.  
  54. // Senzor teploty a vlhkosti
  55. ClosedCube_HDC1080 hdc;
  56.  
  57. // RF modul
  58. RFM69 radio;
  59.  
  60. // Oled display
  61. U8X8_SSD1306_128X64_NONAME_HW_I2C oled(U8G2_R0);
  62.  
  63. // Senzor svetla
  64. Adafruit_TSL2561_Unified tsl(TSL2561_ADDR_FLOAT, 12345);
  65.  
  66.  
  67. void setup(void)
  68. {
  69.   Serial.begin(SERIAL_BAUD);
  70.  
  71.   Serial.println(F("[CMD]"));
  72.   SCmd.addCommand("sleep", cmdSleep);
  73.   SCmd.addCommand("gNetworkId", cmdGetNetowrkId);
  74.   SCmd.addCommand("sNetworkId", cmdSetNetworkId);
  75.   SCmd.addCommand("gNodeId", cmdGetNodeId);
  76.   SCmd.addCommand("sNodeId", cmdSetNodeId);
  77.   SCmd.addDefaultHandler(cmdUnrecognized);
  78.  
  79.  
  80.   Serial.print(F("[EEPROM] "));
  81.   EEPROM.get(0, settings);
  82.   Serial.print(F("Network id: "));
  83.   Serial.print(settings.networkid);
  84.   Serial.print(F(" Node id: "));
  85.   Serial.println(settings.nodeid);
  86.  
  87.  
  88.   Serial.println(F("[PINS]"));
  89.   pinMode(LED_PIN, OUTPUT);
  90.   digitalWrite(LED_PIN, HIGH);
  91.   pinMode(BUTTON_INTERRUPT_PIN, INPUT_PULLUP);
  92.  
  93.  
  94.   Serial.println(F("[OLED]"));
  95.   oled.begin();
  96.   oled.setFont(u8x8_font_chroma48medium8_r);
  97.   oled.draw2x2String(0, 0, "Booting");
  98.  
  99.  
  100.   Serial.print(F("[HDC1080] "));
  101.   hdc.begin(0x40);
  102.   hal.hdc = true;
  103.   if( hal.hdc )
  104.   {
  105.     uint16_t manId = hdc.readManufacturerId();
  106.     uint16_t devId = hdc.readDeviceId();
  107.     Serial.print(F("Manufacture: "));
  108.     Serial.print(manId, HEX);
  109.     Serial.print(F(" Device: "));
  110.     Serial.println(devId, HEX);
  111.   }
  112.   else
  113.   {
  114.     Serial.println(F(" Failed"));
  115.   }
  116.  
  117.  
  118.   Serial.print(F("[TSL2561]"));
  119.   hal.tsl = tsl.begin();
  120.   if( hal.tsl )
  121.   {
  122.     tsl.enableAutoRange(true);
  123.     tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS);
  124.     sensor_t sensor;
  125.     tsl.getSensor(&sensor);
  126.     Serial.print(F(" Sensor: "));
  127.     Serial.print(sensor.name);
  128.     Serial.print(F(" Ver: "));
  129.     Serial.print(sensor.version);
  130.     Serial.print(F(" ID: "));
  131.     Serial.println(sensor.sensor_id);
  132.   }
  133.   else
  134.   {
  135.     Serial.println(F(" Failed"));
  136.   }
  137.  
  138.   Serial.print(F("[RFM69] "));
  139.   bool init = radio.initialize(RF69_868MHZ, settings.nodeid, settings.networkid);
  140.   if(init)
  141.   {
  142.     radio.setHighPower(true);
  143.     radio.setPowerLevel(2); // 0-31
  144.     radio.encrypt(ENCRYPTKEY);
  145.     uint8_t temp = radio.readTemperature();
  146.     Serial.print(F("Temperature: "));
  147.     Serial.println(temp);
  148.   }
  149.   else
  150.   {
  151.     Serial.println(F(" Failed"));
  152.   }
  153.  
  154. }
  155.  
  156.  
  157. void loop(void)
  158. {
  159.   SCmd.readSerial();
  160.  
  161.  
  162.   if (radio.receiveDone())
  163.   {
  164.     Serial.print(F("[RFM69] Incoming packet from: "));
  165.     Serial.print(radio.SENDERID, DEC);
  166.     Serial.print(F(" LEN: "));
  167.     Serial.print(radio.DATALEN);
  168.     Serial.print(F(" RSSI: "));
  169.     Serial.println(radio.RSSI);
  170.    
  171.     if(settings.nodeid == 0)
  172.     {
  173.       masterPacket();
  174.     }
  175.     else
  176.     {
  177.       nodePacket();  
  178.     }
  179.   }
  180.  
  181.  
  182.   // If timed out set new interval
  183.   if( wdtInterrupted )
  184.   {
  185.     if(settings.nodeid == 0)
  186.     {
  187.       masterLoop();
  188.     }
  189.     else
  190.     {
  191.       nodeLoop();  
  192.     }
  193.  
  194.     // Set new wdt timer
  195.     wdtInterrupted = false;
  196.  
  197.     wdt_enable(WDTO_8S);
  198.     WDTCSR |= (1 << WDIE);
  199.   }
  200.  
  201.   attachInterrupt(digitalPinToInterrupt(BUTTON_INTERRUPT_PIN), ButtonInterrupt, LOW);
  202.  
  203.   if( powerDownEnabled )
  204.   {
  205.     powerDown();
  206.   }
  207. }
  208.  
  209. // Receive
  210. void masterPacket()
  211. {
  212.   if(radio.DATALEN == sizeof(Packet))
  213.   {
  214.     Serial.print(F("[RFM69] DATA: "));
  215.  
  216.     Packet *p = (Packet*)radio.DATA;
  217.     printPacket(p);
  218.  
  219.     lastSource = radio.SENDERID;
  220.     lastRssi = radio.RSSI;
  221.   }
  222.   else
  223.   {
  224.     Serial.println(F("[RFM69] Invalid packet size"));
  225.   }
  226. }
  227.  
  228.  
  229. void masterLoop()
  230. {
  231.   sensors_event_t event;
  232.   tsl.getEvent(&event);
  233.   uint32_t light = event.light;
  234.  
  235.   updateDisplay(hdc.readTemperature(), hdc.readHumidity(), light, lastSource, lastRssi);
  236. }
  237.  
  238. // Receive
  239. void nodePacket()
  240. {
  241.  
  242. }
  243.  
  244.  
  245. void nodeLoop()
  246. {
  247.   Packet p;
  248.  
  249.   Serial.print(F("[SENSORS] Reading"));
  250.  
  251.   if( hal.hdc )
  252.   {
  253.     p.temperature = hdc.readTemperature();
  254.     p.humidity = hdc.readHumidity();
  255.     Serial.print(F(" hdc1080"));
  256.   }
  257.  
  258.   if( hal.tsl )
  259.   {
  260.     sensors_event_t event;
  261.     tsl.getEvent(&event);
  262.     p.light = event.light;
  263.     Serial.println(F(" tsl2561"));
  264.   }
  265.  
  266.   // Send to master (nodeid == 0)
  267.   // 255 = broadcast
  268.   Serial.print(F("[RFM69] Sending packet: "));
  269.   printPacket(&p);
  270.   radio.send(0, &p, sizeof(Packet));
  271.  
  272.   updateDisplay(p.temperature, p.humidity, p.light, lastSource, lastRssi);
  273. }
  274.  
  275.  
  276. void printPacket(Packet *p)
  277. {
  278.     Serial.print(F("S: "));
  279.     Serial.print(radio.SENDERID, DEC);
  280.     Serial.print(F(" R: "));
  281.     Serial.print(radio.RSSI, DEC);    
  282.     Serial.print(F(" T: "));
  283.     Serial.print(p->temperature);
  284.     Serial.print(F(" H: "));
  285.     Serial.print(p->humidity);
  286.     Serial.print(F(" L: "));
  287.     Serial.print(p->light);
  288.    
  289.     Serial.println(F(""));
  290. }
  291.  
  292. void updateDisplay(float t, float h, uint32_t l, uint8_t source, int16_t rssi)
  293. {
  294.   Serial.println(F("[OLED] Updating"));
  295.   const int MAX_LEN = 17;
  296.   char line[MAX_LEN];
  297.  
  298.   ++prepis;
  299.  
  300.   // 1. zluty radek
  301.   snprintf(line, MAX_LEN, "Net:%3d SIG:%4d", settings.networkid, rssi);
  302.   oled.drawString(0, 0, line);
  303.  
  304.   // 2. zluty radek
  305.   snprintf(line, MAX_LEN, "Node:%3d Src:%3d", settings.nodeid, source);
  306.   oled.drawString(0, 1, line);
  307.  
  308.   // 3. modry radek
  309.   dtostrf(t, 4, 2, line);
  310.   snprintf(line, MAX_LEN, "%s C", line);
  311.   //oled.draw2x2String(0, 2, line);
  312.   oled.drawString(0, 2, line);
  313.  
  314.   // 4. modry radek
  315.   dtostrf(h, 4, 2, line);
  316.   snprintf(line, MAX_LEN, "%s %%", line);
  317.   //oled.draw2x2String(0, 4, line);
  318.   oled.drawString(0, 3, line);
  319.  
  320.   // 5. modry radek
  321.   dtostrf(l, 4, 0, line);
  322.   snprintf(line, MAX_LEN, "%s lux", line);
  323.   oled.drawString(0, 4, line);
  324.  
  325.   // 8. Posledni radek
  326.   snprintf(line, MAX_LEN, "%d x", prepis);
  327.   oled.drawString(0, 7, line);
  328. }
  329.  
  330.  
  331. void cmdSleep()
  332. {
  333.   powerDownEnabled = true;
  334. }
  335.  
  336. void cmdGetNetowrkId()
  337. {
  338.   Serial.print(F("Network ID: "));
  339.   Serial.println(settings.networkid);
  340. }
  341.  
  342. void cmdSetNetworkId()
  343. {
  344.   char *arg = SCmd.next();
  345.  
  346.   if(arg)
  347.   {
  348.     uint8_t nid = constrain(atoi(arg), 0, 255);
  349.     Serial.print(F("new Network ID: "));
  350.     Serial.println(nid);
  351.     settings.networkid = nid;
  352.  
  353.     EEPROM.put(0, settings);
  354.     radio.setNetwork(nid);
  355.   }
  356.   else
  357.   {
  358.     Serial.println(F("[CMD] Missing argument"));
  359.   }
  360. }
  361.  
  362.  
  363. void cmdGetNodeId()
  364. {
  365.   Serial.print(F("Node ID: "));
  366.   Serial.println(settings.nodeid);
  367. }
  368.  
  369.  
  370. void cmdSetNodeId()
  371. {
  372.   char *arg = SCmd.next();
  373.  
  374.   if(arg)
  375.   {
  376.     uint8_t nid = constrain(atoi(arg), 0, 255);
  377.     Serial.print(F("new Node ID: "));
  378.     Serial.println(nid);
  379.     settings.nodeid = nid;
  380.  
  381.     EEPROM.put(0, settings);
  382.     radio.setAddress(nid);
  383.   }
  384.   else
  385.   {
  386.     Serial.println(F("[CMD] Missing argument"));
  387.   }
  388. }
  389.  
  390.  
  391. void cmdUnrecognized()
  392. {
  393.   Serial.println(F("[CMD] Uncrecognized commands"));
  394. }
  395.  
  396.  
  397. void ButtonInterrupt(void)
  398. {
  399.   detachInterrupt(digitalPinToInterrupt(BUTTON_INTERRUPT_PIN));
  400.   powerDownEnabled = false;
  401. }
  402.  
  403.  
  404. ISR(WDT_vect)
  405. {
  406.   wdt_disable();
  407.  
  408.   wdtInterrupted = true;
  409. }
  410.  
  411. void powerDown()
  412. {
  413.   digitalWrite(LED_PIN, LOW);
  414.   Serial.flush();
  415.   radio.receiveDone();  // Must be here to have working waking interrupt when packet is received
  416.   //attachInterrupt(digitalPinToInterrupt(BUTTON_INTERRUPT_PIN), ButtonInterrupt, LOW);
  417.  
  418.   //Turn off ADC
  419.   ADCSRA &= ~(1 << ADEN);
  420.  
  421.   //Do the sleep according to documentation
  422.   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  423.   cli();
  424.   sleep_enable();
  425.   sleep_bod_disable();
  426.   sei();
  427.   sleep_cpu();
  428.   sleep_disable();
  429.   sei();
  430.  
  431.   //Turn on ADC
  432.   ADCSRA |= (1 << ADEN);
  433.  
  434.   digitalWrite(LED_PIN, HIGH);
  435. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement