jp112

HM-WDS40-TH-I-BME280 mit LCD

Sep 30th, 2019
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //- -----------------------------------------------------------------------------------------------------------------------
  2. // AskSin++
  3. // 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
  4. //- -----------------------------------------------------------------------------------------------------------------------
  5.  
  6. // define this to read the device id, serial and device type from bootloader section
  7. // #define USE_OTA_BOOTLOADER
  8. #define USE_LCD             //bei Verwendung des LCD Displays https://www.aliexpress.com/item/1435066364.html
  9.  
  10. #define EI_NOTEXTERNAL
  11. #include <EnableInterrupt.h>
  12. #include <AskSinPP.h>
  13. #include <LowPower.h>
  14.  
  15. #include <MultiChannelDevice.h>
  16. // https://github.com/spease/Sensirion.git
  17. #include <sensors/Bme280.h>
  18.  
  19. #ifdef USE_LCD
  20. #include "lcd.h"
  21. #define LCD_CS               3
  22. #define LCD_WR               7
  23. #define LCD_DATA             9
  24. #define LCD_INTERVAL_SECONDS 10
  25. #endif
  26.  
  27. // we use a Pro Mini
  28. // Arduino pin for the LED
  29. // D4 == PIN 4 on Pro Mini
  30. #define LED_PIN 4
  31. // Arduino pin for the config button
  32. // B0 == PIN 8 on Pro Mini
  33. #define CONFIG_BUTTON_PIN 8
  34.  
  35. //-----------------------------------------------------------------------------------------
  36.  
  37. //Korrektur von Temperatur und Luftfeuchte
  38. //Einstellbarer OFFSET für Temperatur -> gemessene Temp +/- Offset = Angezeigte Temp.
  39. #define OFFSETtemp 0 //z.B -50 ≙ -5°C / 50 ≙ +5°C
  40.  
  41. //Einstellbarer OFFSET für Luftfeuchte -> gemessene Luftf. +/- Offset = Angezeigte Luftf.
  42. #define OFFSEThumi 0 //z.B -10 ≙ -10%RF / 10 ≙ +10%RF
  43.  
  44. //-----------------------------------------------------------------------------------------
  45.  
  46. // number of available peers per channel
  47. #define PEERS_PER_CHANNEL 6
  48.  
  49. //seconds between sending messages
  50. #define MSG_INTERVAL 180
  51.  
  52. // all library classes are placed in the namespace 'as'
  53. using namespace as;
  54.  
  55. // define all device properties
  56. const struct DeviceInfo PROGMEM devinfo = {
  57.   {0x34, 0x56, 0x81},     // Device ID
  58.   "JPTH10I004",           // Device Serial
  59.   {0x00, 0x3f},           // Device Model Indoor
  60.   0x10,                   // Firmware Version
  61.   as::DeviceType::THSensor, // Device Type
  62.   {0x01, 0x00}            // Info Bytes
  63. };
  64.  
  65. /**
  66.    Configure the used hardware
  67. */
  68. typedef AvrSPI<10, 11, 12, 13> SPIType;
  69. typedef Radio<SPIType, 2> RadioType;
  70. typedef StatusLed<LED_PIN> LedType;
  71. typedef AskSin<LedType, BatterySensor, RadioType> BaseHal;
  72. class Hal : public BaseHal {
  73.   public:
  74.     void init (const HMID& id) {
  75.       BaseHal::init(id);
  76.       // measure battery every 1h
  77.       battery.init(seconds2ticks(60UL * 60), sysclock);
  78.       battery.low(22);
  79.       battery.critical(19);
  80.     }
  81.  
  82.     bool runready () {
  83.       return sysclock.runready() || BaseHal::runready();
  84.     }
  85. } hal;
  86.  
  87. class WeatherEventMsg : public Message {
  88.   public:
  89.     void init(uint8_t msgcnt, int16_t temp, uint8_t humidity, bool batlow) {
  90.       uint8_t t1 = (temp >> 8) & 0x7f;
  91.       uint8_t t2 = temp & 0xff;
  92.       if ( batlow == true ) {
  93.         t1 |= 0x80; // set bat low bit
  94.       }
  95.       Message::init(0xc, msgcnt, 0x70, BIDI | WKMEUP, t1, t2);
  96.       pload[0] = humidity;
  97.     }
  98. };
  99.  
  100. #ifdef USE_LCD
  101. class LCD : public Alarm {
  102.   public:
  103.     Lcd lcd;
  104.   private:
  105.     bool            showTemperature;
  106.     int16_t         temperature;
  107.     uint8_t         humidity;
  108.   public:
  109.     LCD () :  Alarm(0), showTemperature(true), temperature(0), humidity(0) {}
  110.     virtual ~LCD () {}
  111.  
  112.     void init() {
  113.       lcd.begin(LCD_CS, LCD_WR, LCD_DATA);
  114.       lcd.clear();
  115.       sysclock.add(*this);
  116.     }
  117.  
  118.     void setValues(int16_t t, uint8_t h) {
  119.       temperature = t;
  120.       humidity = h;
  121.       displayValues();
  122.     }
  123.  
  124.     void displayValues() {
  125.       if (showTemperature) {
  126.         lcd.printC(temperature);
  127.       } else {
  128.         lcd.printH(humidity);
  129.       }
  130.     }
  131.  
  132.     virtual void trigger (__attribute__((unused)) AlarmClock& clock) {
  133.       set(seconds2ticks(LCD_INTERVAL_SECONDS));
  134.       showTemperature = !showTemperature;
  135.       displayValues();
  136.       sysclock.add(*this);
  137.     }
  138. };
  139. #endif
  140.  
  141. class WeatherChannel : public Channel<Hal, List1, EmptyList, List4, PEERS_PER_CHANNEL, List0>, public Alarm {
  142.  
  143.     WeatherEventMsg msg;
  144.  
  145.     Bme280          bme280;
  146.     uint16_t        millis;
  147.  
  148. #ifdef USE_LCD
  149.     LCD             lcd;
  150. #endif
  151.  
  152.   public:
  153.     WeatherChannel () : Channel(), Alarm(5), millis(0) {}
  154.     virtual ~WeatherChannel () {}
  155.  
  156.  
  157.     // here we do the measurement
  158.     void measure () {
  159.       DPRINT("Measure...\n");
  160.       bme280.measure();
  161.       DPRINT("T/H = ");DDEC(bme280.temperature()+OFFSETtemp);DPRINT("/");DDECLN(bme280.humidity()+OFFSEThumi);
  162.     }
  163.  
  164.     virtual void trigger (__attribute__ ((unused)) AlarmClock& clock) {
  165.       uint8_t msgcnt = device().nextcount();
  166.       // reactivate for next measure
  167.       tick = delay();
  168.       clock.add(*this);
  169.       measure();
  170. #ifdef USE_LCD
  171.       lcd.setValues(temp, humidity);
  172. #endif
  173.       msg.init(msgcnt, bme280.temperature()+OFFSETtemp,bme280.humidity()+OFFSEThumi, device().battery().low());
  174.       if (msgcnt % 20 == 1) device().sendPeerEvent(msg, *this); else device().broadcastEvent(msg, *this);
  175.     }
  176.  
  177.     uint32_t delay () {
  178.       return seconds2ticks(MSG_INTERVAL);
  179.     }
  180.     void setup(Device<Hal, List0>* dev, uint8_t number, uint16_t addr) {
  181.       Channel::setup(dev, number, addr);
  182.       bme280.init();
  183. #ifdef USE_LCD
  184.       lcd.init();
  185. #endif
  186.       sysclock.add(*this);
  187.     }
  188.  
  189.     uint8_t status () const {
  190.       return 0;
  191.     }
  192.  
  193.     uint8_t flags () const {
  194.       return 0;
  195.     }
  196. };
  197.  
  198. typedef MultiChannelDevice<Hal, WeatherChannel, 1> WeatherType;
  199. WeatherType sdev(devinfo, 0x20);
  200. ConfigButton<WeatherType> cfgBtn(sdev);
  201.  
  202. void setup () {
  203.   DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER);
  204.   sdev.init(hal);
  205.   buttonISR(cfgBtn, CONFIG_BUTTON_PIN);
  206.   sdev.initDone();
  207. }
  208.  
  209. void loop() {
  210.   bool worked = hal.runready();
  211.   bool poll = sdev.pollRadio();
  212.   if ( worked == false && poll == false ) {
  213.     hal.activity.savePower<Sleep<>>(hal);
  214.   }
  215. }
Advertisement
Add Comment
Please, Sign In to add comment