Text-Node as Temperature-Display



  • Hi!

    I use MySensors with Domoticz for tracking indoor and outdoor temperatures. In summer it is important for me to know the temperatures, so I don't open the windows before it is cooler outside than inside.
    On the hottest summer nights the time to open the windows can be in the middle of the night. At this time it isn't very handy to check the Domoticz-page with a Laptop or Phone.
    For this application I found a good solution with the V_TEXT-node.

    Currently it is still a breadboard-design, but I will make something more permanent soon.
    I plan to power it with a battery and switch it off after reading.
    DSC_0030a.jpg

    The arduino-sketch requests 5 texts (for 5 display lines) and goes to sleep afterwards. It can be woken up again with a button on pin 3. In this case, the texts are requested again.

    /*
     * Text-Node:
     * this node requests five texts and goes to sleep afterwards
     *
     */
    
    #define MY_RADIO_NRF24
    #define MY_RF24_CE_PIN 5
    #define MY_RF24_CS_PIN 6
    #define MY_NODE_ID 51
    
    #include "U8glib.h"
    #include <MySensor.h>
    #include <SPI.h>
    
    U8GLIB_SSD1306_128X64 u8g(7, 8, 9); //u8g constructor cs=7, dc=8, res=9
    
    char lastLCD[5][21] = {"Booting", "MySens up", "", "", ""};                  //array of strings
    unsigned long lastUpdate = 0;
    boolean received[5] = {false, false, false, false, false};
    
    void setup() {
      pinMode(3, INPUT_PULLUP); //interrupt pin
      updateDisplay();
    
      sendSketchInfo("Temperature Text", "1.0");
    
      strcpy(lastLCD[2], "Info sent");
      updateDisplay();
    
      for ( uint8_t i = 0; i < 5; i++) {
        present(i, S_INFO);
        request(i, V_TEXT);
      }
      
      strcpy(lastLCD[3], "First requ");
      updateDisplay();
    }
    
    void loop() {
      while (received[0] == false || received[1] == false || received[2] == false || received[3] == false || received[4] == false ) {
        unsigned long now = millis();
        transportProcess();
        if (now - lastUpdate > 1000) {//repeat request every second until every string is received.
          for ( uint8_t i = 0; i < 5; i++) {
            if ( !received[i]) request(i, V_TEXT);
          }
          lastUpdate = now;
        }
        updateDisplay();
      }
    
      sleep(1, FALLING); //sleep forever, interrupt pin 3
    
      for (uint8_t i = 0; i < 5; i++) received[i] = false; //after wake up reset received status
    }
    
    void updateDisplay() {
      u8g.setFont(u8g_font_courB12);
      u8g.setFontPosTop();
    
      u8g.firstPage();
      do {
        for (uint8_t i = 0; i < 5; i++) {
          u8g.drawStr(0, i * 13, lastLCD[i]);
        }
      } while (u8g.nextPage());
    }
    
    void receive(const MyMessage & message) {
      if (message.type == V_TEXT) {                 // Text messages only
    #ifdef MY_DEBUG    // Write some debug info
        Serial.print("Sensor: "); Serial.print(message.sensor); Serial.print(", Message: "); Serial.println(message.getString());
    #endif
        if (message.sensor < 5) {
          strcpy(lastLCD[message.sensor], message.getString());
          received[message.sensor] = true;
        }
      }
    }
    

    On the Domoticz-side is a lua script, which updates the texts whenever the corresponding temperature is updated:

    -- script_device_text.lua
    local line1 = 'Textline1'
    local line1idx = '25'
    local line1text = 'Innen:  '
    local line1temp = 'Wohnzimmer'
    local line2 = 'Textline2'
    local line2idx = '26'
    local line2text = 'Aussen: '
    local line2temp = 'großer Hof'
    local line3 = 'Textline3'
    local line3idx = '27'
    local line3text = 'kl.Hof: '
    local line3temp = 'kleiner Hof'
    local line4 = 'Textline4'
    local line4idx = '28'
    local line4text = 'Kizi:   '
    local line4temp = 'Kinderzimmer'
    local line5 = 'Textline5'
    local line5idx = '29'
    local line5text = 'Gang:   '
    local line5temp = 'Gang aussen'
    
    commandArray = {}
    
    
    if devicechanged[line1temp] then
    	commandArray['UpdateDevice']=line1idx..'|0|'..line1text..otherdevices_svalues[line1temp]
    end
    
    if devicechanged[line2temp] then
    	commandArray['UpdateDevice']=line2idx..'|0|'..line2text..otherdevices_svalues[line2temp]
    end
    
    if devicechanged[line3temp] then
        commandArray['UpdateDevice']=line3idx..'|0|'..line3text..otherdevices_svalues[line3temp]
    end
    
    if devicechanged[line4temp] then
        commandArray['UpdateDevice']=line4idx..'|0|'..line4text..otherdevices_svalues[line4temp]
    end
    
    if devicechanged[line5temp] then
        commandArray['UpdateDevice']=line5idx..'|0|'..line5text..otherdevices_svalues[line5temp]
    end
    
    return commandArray
    

    I also made a sketch for a continuous-update display. As Domoticz doesn't push the texts, the sketch contains a switch. Every time the switch is switched on, the sketch requests the text:

    #define MY_RADIO_NRF24
    #define MY_RF24_CE_PIN 5
    #define MY_RF24_CS_PIN 6
    #define MY_NODE_ID 50
    
    #include "U8glib.h"
    #include <MySensor.h>
    #include <SPI.h>
    
    
    U8GLIB_SSD1306_128X64 u8g(7, 8, 9); //u8g constructor
    
    const byte LCD_CHILD = 1;
    const byte LCD_NEW_SWITCH = 0;
    char lastLCD[21] = "";
    unsigned long lastUpdate = 0, lastDisplay = 0;
    boolean incoming = false;
    
    MyMessage swMsg(LCD_NEW_SWITCH, V_LIGHT);
    
    void setup() {
      sendSketchInfo("text-push-node", "1.0");
      present(LCD_CHILD, S_INFO);
      present(LCD_NEW_SWITCH, S_LIGHT);
    
      request(LCD_CHILD, V_TEXT);
      request(LCD_NEW_SWITCH, V_LIGHT);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      unsigned long now = millis();
    
      if (incoming) { //request text, if there is a new one available
        send(swMsg.set(false)); //reset the switch (not needed, but serves as ack)
        request(LCD_CHILD, V_TEXT);
        incoming = false;
      }
    
      if (now - lastDisplay > 1000) { //update every 1 s
        lastDisplay = now;
    
        u8g.setFont(u8g_font_helvB10);
        u8g.setFontPosTop();
    
        //update the Display:
        u8g.firstPage();
        do {
          u8g.drawStr(0, 0, lastLCD);
        } while (u8g.nextPage());
      }
    }
    
    
    void receive(const MyMessage & message) {
      if (message.type == V_TEXT) {                       // Text messages only
        // Write some debug info
    #ifdef MY_DEBUG
        Serial.print("Message: "); Serial.print(message.sensor); Serial.print(", Message: "); Serial.println(message.getString());
    #endif
        if (message.sensor == LCD_CHILD ) {
          strcpy(lastLCD, message.getString());
        }
      }
      else if (message.type == V_LIGHT && message.sensor == LCD_NEW_SWITCH) {
    #ifdef MY_DEBUG
        Serial.print("New status: "); Serial.println(message.getBool());
    #endif
        incoming = true;
      }
    }
    

    In this case you need to set the switch in the lua-script with commandArray[switch]='On' after every update of the text.

    EDIT: The sketches first published were based on an old version (ca. september '15) of the development branch, which is no longer available. Updated the sketches to Version 1.6



  • Great work, I tried to get the other v_text example working to do the same, but gave up, will give this a go! Thanks for sharing 🙂



  • I built something similar here, but it just displays its 'own' values rather than getting them from Domoticz with V_TEXT.


Log in to reply
 

Suggested Topics

  • 8
  • 1
  • 3
  • 90
  • 1
  • 44

0
Online

11.2k
Users

11.1k
Topics

112.5k
Posts