Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. My Project
  3. LCD Clock and Text sensor node with new V_TEXT

LCD Clock and Text sensor node with new V_TEXT

Scheduled Pinned Locked Moved My Project
39 Posts 11 Posters 30.2k Views 21 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • AWIA AWI

    @user1306 you can do anything with the text sent but be aware that this would imply you are making your own (non standard MySensors) protocol. V_TEXT is intended only for information.
    I am the 'misusing' it myself but only where there is no MySensors solution.

    user1306U Offline
    user1306U Offline
    user1306
    wrote on last edited by
    #19

    @AWI
    thank you for the info, i'm a bit new to arduino and my sensors, so i'm not really sure how to do that.
    if possible could you let me know what piece of code i need to be able to do that?

    thanks

    AWIA 1 Reply Last reply
    0
    • user1306U user1306

      @AWI
      thank you for the info, i'm a bit new to arduino and my sensors, so i'm not really sure how to do that.
      if possible could you let me know what piece of code i need to be able to do that?

      thanks

      AWIA Offline
      AWIA Offline
      AWI
      Hero Member
      wrote on last edited by
      #20

      @user1306 This is a part from the routine where I read three values from a V_TEXT value (renamed to V_ORIENTATION) separated by a ";". (I think V_ORIENTATION would be a good addition for MySensors ;-) in addition to V_POSITION but I haven't suggested it officially yet)

      Also be aware that Domoticz only sends the V_TEXT after it has been requested. So you need to send a request(sensor_id, V_TEXT)first .

      #define V_ORIENTATION V_TEXT								// Own (not existing in MySensors protocol) type for orientation (payload = Pitch ; Roll ; Yaw in degrees)
      #define S_ORIENTATION S_INFO								// Yaw = 0 (north)to 360) ; Horizontal = 0 ; 
      
      
      			if (message.type==V_ORIENTATION) {
      				char payload[12] ;								// temporary buffer
      				strcpy(payload, message.getString());			// read and copy payload
      				Yaw = atoi(strtok(payload, ";"));				// get variables from payload (; seperated int)
      				Pitch = atoi(strtok(NULL, ";"));
      				Roll = atoi(strtok(NULL, ";"));
      				attachServos(true) ;							// power up servo's
      				servoH.write(map(-constrain(Yaw, -90, 90),-90, 90, 0, 180));		// servo middle 90 deg == 0 deg Yaw 
      				servoV.write(map(Pitch, -90, 90, 0, 180));
      				}
      1 Reply Last reply
      1
      • AWIA Offline
        AWIA Offline
        AWI
        Hero Member
        wrote on last edited by
        #21

        On special request of @pepov attached a piece of LUA script for Domoticz. This demonstrates how to fill V_TEXT devices from other values so that thes can be displayed on the Text sensor node.

        This special example demonstrates how to fill V_TEXT with weather data from a virtual device connected to Weather Underground. Please search the Domoticz wiki for more information on this special service.

        -- script to read the virtual Weatherstation (Weather Underground) service and send it to "V_TEXT" MySensors devices
        -- Weather Underground values are in 'WUWeer' and 'WUWind'
        
        commandArray = {} ;
        --Weatherstation data:
        sWeatherTemp, sWeatherHumidity, sWeatherUV, sWeatherPressure, sWeatherUV2 = otherdevices_svalues['WUWeer']:match("([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)") ;
        sWeatherTemp = tonumber(sWeatherTemp);
        sWeatherHumidity = tonumber(sWeatherHumidity);
        sWeatherUV = tonumber(sWeatherUV);
        sWeatherPressure = tonumber(sWeatherPressure);
        sWeatherUV2 = tonumber(sWeatherUV2);
        -- print to log 
        print("Weather station: Temperature is " .. sWeatherTemp .. " ");
        print("Weather station: Humidity is " .. sWeatherHumidity .. " ");
        print("Weather station: UV is " .. sWeatherUV .. " ");
        print("Weather station: Pressure is " .. sWeatherPressure .. " ");
        print("Weather station: UV2 is " .. sWeatherUV2 .. " ");
         
        ------------------------------------------------------------------------
         
        --Windmeter data:
        sWindDirectionDegrees, sWindDirection, sWindSpeed, sWindGust, sWindTemperature, sWindFeel = otherdevices_svalues['WUWind']:match("([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)") ;
         
        sWindDirectionDegrees = tonumber(sWindDirectionDegrees);
        sWindDirection = (sWindDirection);
        sWindSpeed = tonumber(sWindSpeed);
        sWindGust = tonumber(sWindGust);
        sWindTemperature = tonumber(sWindTemperature);
        sWindFeel = tonumber(sWindFeel);
         
        print("Windmeter: Winddirection (in degrees) is: " .. sWindDirectionDegrees .. " ");
        print("Windmeter: Winddirection is: " .. sWindDirection .. " ");
        print("Windmeter: Windspeed is: " .. sWindSpeed .. " ");
        print("Windmeter: Windgust is: " .. sWindGust .. " ");
        print("Windmeter: Windtemperature is: " .. sWindTemperature .. " ");
        print("Windmeter: Windfeel is: " .. sWindFeel .. " ");
        
        -- device numbers 725/ 873 and 872 are V_TEXT  
        commandArray[1] = {['UpdateDevice'] = string.format ("725|0|out %4.1f\01 %2d\07 %4d\02\03  ", sWeatherTemp, sWeatherHumidity, sWeatherPressure)}
        commandArray[2] = {['UpdateDevice'] = string.format ("873|0|%2.1f:%3d:%4.1f", sWeatherTemp, sWeatherHumidity, sWeatherPressure)}
        commandArray[3] = {['UpdateDevice'] = string.format ("872|0|%3d:%4.1f:%4.1f:%4.1f:%4.1f", sWindDirectionDegrees, sWindSpeed/10 , sWindGust/10, sWindTemperature, sWindFeel)}
        
        
        return commandArray
        
        pepovP 1 Reply Last reply
        3
        • AWIA AWI

          On special request of @pepov attached a piece of LUA script for Domoticz. This demonstrates how to fill V_TEXT devices from other values so that thes can be displayed on the Text sensor node.

          This special example demonstrates how to fill V_TEXT with weather data from a virtual device connected to Weather Underground. Please search the Domoticz wiki for more information on this special service.

          -- script to read the virtual Weatherstation (Weather Underground) service and send it to "V_TEXT" MySensors devices
          -- Weather Underground values are in 'WUWeer' and 'WUWind'
          
          commandArray = {} ;
          --Weatherstation data:
          sWeatherTemp, sWeatherHumidity, sWeatherUV, sWeatherPressure, sWeatherUV2 = otherdevices_svalues['WUWeer']:match("([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)") ;
          sWeatherTemp = tonumber(sWeatherTemp);
          sWeatherHumidity = tonumber(sWeatherHumidity);
          sWeatherUV = tonumber(sWeatherUV);
          sWeatherPressure = tonumber(sWeatherPressure);
          sWeatherUV2 = tonumber(sWeatherUV2);
          -- print to log 
          print("Weather station: Temperature is " .. sWeatherTemp .. " ");
          print("Weather station: Humidity is " .. sWeatherHumidity .. " ");
          print("Weather station: UV is " .. sWeatherUV .. " ");
          print("Weather station: Pressure is " .. sWeatherPressure .. " ");
          print("Weather station: UV2 is " .. sWeatherUV2 .. " ");
           
          ------------------------------------------------------------------------
           
          --Windmeter data:
          sWindDirectionDegrees, sWindDirection, sWindSpeed, sWindGust, sWindTemperature, sWindFeel = otherdevices_svalues['WUWind']:match("([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)") ;
           
          sWindDirectionDegrees = tonumber(sWindDirectionDegrees);
          sWindDirection = (sWindDirection);
          sWindSpeed = tonumber(sWindSpeed);
          sWindGust = tonumber(sWindGust);
          sWindTemperature = tonumber(sWindTemperature);
          sWindFeel = tonumber(sWindFeel);
           
          print("Windmeter: Winddirection (in degrees) is: " .. sWindDirectionDegrees .. " ");
          print("Windmeter: Winddirection is: " .. sWindDirection .. " ");
          print("Windmeter: Windspeed is: " .. sWindSpeed .. " ");
          print("Windmeter: Windgust is: " .. sWindGust .. " ");
          print("Windmeter: Windtemperature is: " .. sWindTemperature .. " ");
          print("Windmeter: Windfeel is: " .. sWindFeel .. " ");
          
          -- device numbers 725/ 873 and 872 are V_TEXT  
          commandArray[1] = {['UpdateDevice'] = string.format ("725|0|out %4.1f\01 %2d\07 %4d\02\03  ", sWeatherTemp, sWeatherHumidity, sWeatherPressure)}
          commandArray[2] = {['UpdateDevice'] = string.format ("873|0|%2.1f:%3d:%4.1f", sWeatherTemp, sWeatherHumidity, sWeatherPressure)}
          commandArray[3] = {['UpdateDevice'] = string.format ("872|0|%3d:%4.1f:%4.1f:%4.1f:%4.1f", sWindDirectionDegrees, sWindSpeed/10 , sWindGust/10, sWindTemperature, sWindFeel)}
          
          
          return commandArray
          
          pepovP Offline
          pepovP Offline
          pepov
          wrote on last edited by
          #22

          @AWI said:

          evices from other values so that thes can be displayed on the Text sensor node.

          This special example demonstrates how to fill V_TEXT with weather data from a virtual device connected to Weather Underground. Please search the Domoticz wiki for more informati

          Wow Thanks AWI!!!!

          1 Reply Last reply
          0
          • NiklasON Offline
            NiklasON Offline
            NiklasO
            wrote on last edited by
            #23

            Does this work with MySensors 2.0? If someone has this running on 2.0, please share the code. :)

            Q 1 Reply Last reply
            0
            • Marc-Olivier ChaubetM Offline
              Marc-Olivier ChaubetM Offline
              Marc-Olivier Chaubet
              wrote on last edited by
              #24

              Hi,
              i try to send message but nothing change on LcdDisplay.

              I d'ont undestant what is wrong.

              Can you help me pls.

              send: 49-49-20-0 s=8,c=2,t=47,pt=0,l=0,sg=0,st=ok:
              send: 49-49-20-0 s=9,c=2,t=47,pt=0,l=0,sg=0,st=ok:
              read: 0-20-49 s=9,c=1,t=16,pt=0,l=4,sg=0:test
              send: 49-49-20-0 s=9,c=1,t=16,pt=0,l=4,sg=0,st=ok:test
              send: 49-49-20-0 s=8,c=2,t=47,pt=0,l=0,sg=0,st=ok:
              
              AWIA 1 Reply Last reply
              0
              • NiklasON NiklasO

                Does this work with MySensors 2.0? If someone has this running on 2.0, please share the code. :)

                Q Offline
                Q Offline
                Qu3Uk
                wrote on last edited by
                #25

                @NiklasO I have something similar running on MYS 2.0 and can paste the code. I'm using a 4x1 display and using V_VAR-1-4 to send each line over.
                If that's useful to you I can post it.

                NiklasON 1 Reply Last reply
                0
                • Q Qu3Uk

                  @NiklasO I have something similar running on MYS 2.0 and can paste the code. I'm using a 4x1 display and using V_VAR-1-4 to send each line over.
                  If that's useful to you I can post it.

                  NiklasON Offline
                  NiklasON Offline
                  NiklasO
                  wrote on last edited by NiklasO
                  #26

                  @Qu3Uk said:

                  @NiklasO I have something similar running on MYS 2.0 and can paste the code. I'm using a 4x1 display and using V_VAR-1-4 to send each line over.
                  If that's useful to you I can post it.

                  Yes please. I ported to 2.0 late yesterday and it works ok. I have 4 lines, 20 chars.

                  Q 1 Reply Last reply
                  0
                  • Marc-Olivier ChaubetM Marc-Olivier Chaubet

                    Hi,
                    i try to send message but nothing change on LcdDisplay.

                    I d'ont undestant what is wrong.

                    Can you help me pls.

                    send: 49-49-20-0 s=8,c=2,t=47,pt=0,l=0,sg=0,st=ok:
                    send: 49-49-20-0 s=9,c=2,t=47,pt=0,l=0,sg=0,st=ok:
                    read: 0-20-49 s=9,c=1,t=16,pt=0,l=4,sg=0:test
                    send: 49-49-20-0 s=9,c=1,t=16,pt=0,l=4,sg=0,st=ok:test
                    send: 49-49-20-0 s=8,c=2,t=47,pt=0,l=0,sg=0,st=ok:
                    
                    AWIA Offline
                    AWIA Offline
                    AWI
                    Hero Member
                    wrote on last edited by AWI
                    #27

                    @Marc-Olivier-Chaubet Can you post a little more information (the sketch)?

                    The text seems to be arriving at the node. So first check if the information comes in on serial (Serial.print(....)).
                    And next: is your display working? just print something it in the local sketch.

                    1 Reply Last reply
                    0
                    • NiklasON NiklasO

                      @Qu3Uk said:

                      @NiklasO I have something similar running on MYS 2.0 and can paste the code. I'm using a 4x1 display and using V_VAR-1-4 to send each line over.
                      If that's useful to you I can post it.

                      Yes please. I ported to 2.0 late yesterday and it works ok. I have 4 lines, 20 chars.

                      Q Offline
                      Q Offline
                      Qu3Uk
                      wrote on last edited by
                      #28

                      @NiklasO

                      Here is it.

                      // Enable debug prints to serial monitor
                      //#define MY_DEBUG
                      
                      //#define MY_NODE_ID 200
                      #define MY_SENSOR_ID 1
                      
                      // Enable and select radio type attached
                      #define MY_RADIO_NRF24
                      //#define MY_RADIO_RFM69
                      
                      // Enable repeater functionality for this node
                      #define MY_REPEATER_FEATURE
                      
                      // LCD includes
                      #include <Wire.h> 
                      #include <LiquidCrystal_I2C.h>
                      
                      // MYS includes
                      #include <SPI.h>
                      #include <MySensors.h>
                      
                      #define LCD_ON 1  // GPIO value to write to turn on attached relay
                      #define LCD_OFF 0 // GPIO value to write to turn off attached relay
                      
                      LiquidCrystal_I2C lcd(0x3f, 20, 4); //0x3f is the LCD address.
                      String LINE_BLANK = "                    ";
                      
                      void before() {
                      }
                      
                      void setup() {
                        // Set off  LCD module
                        lcd.begin (); 
                        lcd.backlight();
                      
                        lcd.setCursor(0, 0); //
                        lcd.print("Ready!"); // We expect the controller to remove this from display.
                      }
                      
                      void presentation()
                      {
                        // Send the sketch version information to the gateway and Controller
                        sendSketchInfo("LCD Display", "1.0");
                      
                        present(MY_SENSOR_ID, S_INFO);
                      }
                      
                      
                      void loop()
                      {
                        // extra processing if required.
                      }
                      
                      void receive(const MyMessage &message) {
                        // We only expect one type of message from controller. But we better check anyway.
                        if (message.type == V_STATUS) {
                          // Use V_STATUS to turn on/off the LCD display
                          // if supported by LCD.
                        }
                      
                        // temp string, probably don't need this.
                        if (message.type == V_VAR1) {
                          writeScreen(0, message.data);
                        }
                      
                        if (message.type == V_VAR2) {
                          writeScreen(1, message.data);
                        }
                      
                        if (message.type == V_VAR3) {
                          writeScreen(2, message.data);
                        }
                      
                        if (message.type == V_VAR4) {
                          writeScreen(3, message.data);
                        }
                      }
                      
                      void writeScreen(int line, String text)
                      {
                        // Trim whitespace from incoming text.
                        text.trim();
                      
                        // Remove anything over 20 char in text.
                        if(text.length() > 19)
                        {
                            text.remove(20);
                        }
                        
                        // Clear the line
                        lcd.setCursor(0, line);
                        lcd.print(LINE_BLANK);
                      
                        // Set Line
                        lcd.setCursor(0, line);
                        lcd.print(text);
                      }
                      
                      user1306U 1 Reply Last reply
                      0
                      • Marc-Olivier ChaubetM Offline
                        Marc-Olivier ChaubetM Offline
                        Marc-Olivier Chaubet
                        wrote on last edited by Marc-Olivier Chaubet
                        #29

                        Hi AWI,
                        Yes my display is working, i can see the date and "Line 1 - First....."

                        I think what i send is not correct....0_o
                        This is from the serial monitor

                        read: 0-20-49 s=9,c=1,t=16,pt=0,l=4,sg=0:test
                        

                        Should it be something like this

                        read: 0-20-49 s=9,c=1,t=16,pt=0,l=4,sg=0:Line1=test
                        

                        this is the sketch.

                        
                        /*
                         PROJECT: MySensors / LCD display for text from controller
                         PROGRAMMER: AWI
                         DATE: september 8, 2015/ last update: september 8, 2015
                         FILE: AWI_LCD_49.ino
                         LICENSE: Public domain
                        
                         Hardware: tbd ..MYS Ceech - ATmega328p board w/ NRF24l01
                            and MySensors 1.5 ()
                                
                        Special:
                            MySensors - Development (as of sept 2015)
                            
                        SUMMARY:
                            display time & 2 lines of text from Controller Text sensors
                        */
                        
                        #include <MyMessage.h>
                        #include <MySensor.h>                       // Mysensor network
                        #include <SPI.h>
                        #include <LiquidCrystal_I2C.h>
                        #include <Time.h>                           //http://playground.arduino.cc/Code/Time
                        #include <Wire.h>                           
                        
                        // uncomment if you are using the DEVELOPMENT version with V_TEXT & V_INFO defined (better to use development MyMessage.h)
                        const byte V_TEXT = 47 ;                  // values taken from development edition MyMessage.h
                        const byte S_INFO = 36 ;
                        
                        const byte nodeId = 49 ;                    // MySensors fixed node id
                        const byte LCD1_CHILD = 8 ;                 // LCD line 1
                        const byte LCD2_CHILD = 9 ;                 // LCD line 2
                        
                        char lastLCD1[21] = "Line1 - first   ";     // define & init before first receive
                        char lastLCD2[21] = "Line2 - second  ";
                        
                        boolean timeReceived = false ;
                        // timers for loop delays
                        unsigned long lastUpdate=0, lastRequest=0, lastDisplay=0;
                        int display_no = 0 ;                        // current display
                        
                        // *** Definition and initialisation
                        // define the MySensor network
                        MyTransportNRF24 transport(9,10);           // Sensoduino (8,7) Ceech board, 3.3v (7,8)  (pin default 9,10)
                        MySensor gw(transport);  
                        
                        // Initialize messages for sensor network
                        MyMessage textMsg(0, V_TEXT);
                        //                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
                        LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
                        
                        // OPTIONAL: Custom characters for display - Units)
                        byte heart[8] = { B00000, B01010, B11111, B11111, B01110, B00100, B00000, B00000};
                        
                        void setup(void){
                            //Serial in Sensor network = 115200
                            gw.begin(incomingMessage, nodeId);                  // this node is 49 fixed 
                            //Send the sensor node sketch version information to the gateway
                            gw.sendSketchInfo("AWI_LCD text 49", "1.1");
                            gw.present(LCD1_CHILD, S_INFO, "LCD_line1");        // new S_type 20150905 (not know by domoticz)
                            gw.present(LCD2_CHILD, S_INFO, "LCD_line2");
                            gw.send(textMsg.setSensor(LCD1_CHILD).set("-"));    // initialize the V_TEXT at controller for sensor to none (trick for Domoticz)
                            gw.send(textMsg.setSensor(LCD2_CHILD).set("-"));        
                        
                            // Initializations
                            gw.requestTime(receiveTime);                        // get the time from controller (handled by receiveTime)
                            
                            // ** LCD display **
                            Wire.begin();                                       // I2C
                            lcd.begin(16, 2);                                   // LCD 2 lines * 16 char.
                            lcd.setBacklight(HIGH);
                            lcd.setCursor(0, 0);
                            lcd.createChar(1, heart);
                        
                            // lcd.write(byte(0)); // write units
                        }
                        
                        void loop(void){
                            // timer for loop delays
                            unsigned long now = millis();
                            gw.process() ;
                            // If no time has been received yet, request it every 10 second from controller
                            // When time has been received, request update every hour
                            if ((!timeReceived && (now-lastRequest > 10*1000)) ||   
                                (now-lastRequest > 3600000UL)){                 // request update every hour to keep in sync
                               // Request time from controller. 
                               Serial.println("requesting time");
                               timeReceived = false;
                               gw.requestTime(receiveTime);  
                               lastRequest = now;
                                }
                            // Change display and update sensors every 5 seconds (default = 5000)
                            if (now-lastDisplay > 5000){
                                lastDisplay = now;
                                gw.request(LCD1_CHILD, V_TEXT, 0);                  // request new values from controller
                                gw.request(LCD2_CHILD, V_TEXT, 0);                ;// request new values from controller
                                // change display 
                                display_no++;
                                    if (display_no >= 2){ // wrap for number of different displays for second line
                                    display_no = 0;
                                    }
                                }
                            // Update display every second
                            if (now-lastUpdate > 1000) {
                                LCD_local_display();
                                lastUpdate = now;
                                }
                            }
                        
                        // This is called when a new time value was received
                        void receiveTime(unsigned long controllerTime) {
                            Serial.print("Time value received: ");
                            Serial.println(controllerTime);
                            setTime(controllerTime);                            // time from controller
                            timeReceived = true;
                            }
                        
                        // This is called when a message is received 
                        void incomingMessage(const MyMessage &message) {
                            if (message.type==V_TEXT) {                         // Text messages only
                             // Write some debug info
                             Serial.print("Message: "); Serial.print(message.sensor); Serial.print(", Message: "); Serial.println(message.getString());
                            if (message.sensor == LCD1_CHILD ) {
                                snprintf(lastLCD1, sizeof(lastLCD1), "%16s", message.getString());  // load text into LCD string
                                }
                            else if (message.sensor == LCD2_CHILD){
                                snprintf(lastLCD2, sizeof(lastLCD2), "%16s", message.getString());
                                }
                            } 
                        }
                        
                        void LCD_local_display(void){
                        // take car of LCD display information
                            char buf[17]; // temp buffer for max 16 char display
                            // start with location & time on first line
                            snprintf(buf, sizeof buf, "%02d:%02d:%02d %02d-%02d", hour(), minute(), second(), day(), month());
                            lcd.setCursor(0, 0);
                            lcd.print(buf);
                            lcd.setCursor(0, 1);
                            if (display_no == 0){
                              lcd.print(lastLCD1);                          // second line is text value from controller
                            } else {                                        // display == 2
                              lcd.print(lastLCD2);
                            }
                        }
                        
                        

                        Thxs

                        AWIA 1 Reply Last reply
                        0
                        • Marc-Olivier ChaubetM Marc-Olivier Chaubet

                          Hi AWI,
                          Yes my display is working, i can see the date and "Line 1 - First....."

                          I think what i send is not correct....0_o
                          This is from the serial monitor

                          read: 0-20-49 s=9,c=1,t=16,pt=0,l=4,sg=0:test
                          

                          Should it be something like this

                          read: 0-20-49 s=9,c=1,t=16,pt=0,l=4,sg=0:Line1=test
                          

                          this is the sketch.

                          
                          /*
                           PROJECT: MySensors / LCD display for text from controller
                           PROGRAMMER: AWI
                           DATE: september 8, 2015/ last update: september 8, 2015
                           FILE: AWI_LCD_49.ino
                           LICENSE: Public domain
                          
                           Hardware: tbd ..MYS Ceech - ATmega328p board w/ NRF24l01
                              and MySensors 1.5 ()
                                  
                          Special:
                              MySensors - Development (as of sept 2015)
                              
                          SUMMARY:
                              display time & 2 lines of text from Controller Text sensors
                          */
                          
                          #include <MyMessage.h>
                          #include <MySensor.h>                       // Mysensor network
                          #include <SPI.h>
                          #include <LiquidCrystal_I2C.h>
                          #include <Time.h>                           //http://playground.arduino.cc/Code/Time
                          #include <Wire.h>                           
                          
                          // uncomment if you are using the DEVELOPMENT version with V_TEXT & V_INFO defined (better to use development MyMessage.h)
                          const byte V_TEXT = 47 ;                  // values taken from development edition MyMessage.h
                          const byte S_INFO = 36 ;
                          
                          const byte nodeId = 49 ;                    // MySensors fixed node id
                          const byte LCD1_CHILD = 8 ;                 // LCD line 1
                          const byte LCD2_CHILD = 9 ;                 // LCD line 2
                          
                          char lastLCD1[21] = "Line1 - first   ";     // define & init before first receive
                          char lastLCD2[21] = "Line2 - second  ";
                          
                          boolean timeReceived = false ;
                          // timers for loop delays
                          unsigned long lastUpdate=0, lastRequest=0, lastDisplay=0;
                          int display_no = 0 ;                        // current display
                          
                          // *** Definition and initialisation
                          // define the MySensor network
                          MyTransportNRF24 transport(9,10);           // Sensoduino (8,7) Ceech board, 3.3v (7,8)  (pin default 9,10)
                          MySensor gw(transport);  
                          
                          // Initialize messages for sensor network
                          MyMessage textMsg(0, V_TEXT);
                          //                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
                          LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
                          
                          // OPTIONAL: Custom characters for display - Units)
                          byte heart[8] = { B00000, B01010, B11111, B11111, B01110, B00100, B00000, B00000};
                          
                          void setup(void){
                              //Serial in Sensor network = 115200
                              gw.begin(incomingMessage, nodeId);                  // this node is 49 fixed 
                              //Send the sensor node sketch version information to the gateway
                              gw.sendSketchInfo("AWI_LCD text 49", "1.1");
                              gw.present(LCD1_CHILD, S_INFO, "LCD_line1");        // new S_type 20150905 (not know by domoticz)
                              gw.present(LCD2_CHILD, S_INFO, "LCD_line2");
                              gw.send(textMsg.setSensor(LCD1_CHILD).set("-"));    // initialize the V_TEXT at controller for sensor to none (trick for Domoticz)
                              gw.send(textMsg.setSensor(LCD2_CHILD).set("-"));        
                          
                              // Initializations
                              gw.requestTime(receiveTime);                        // get the time from controller (handled by receiveTime)
                              
                              // ** LCD display **
                              Wire.begin();                                       // I2C
                              lcd.begin(16, 2);                                   // LCD 2 lines * 16 char.
                              lcd.setBacklight(HIGH);
                              lcd.setCursor(0, 0);
                              lcd.createChar(1, heart);
                          
                              // lcd.write(byte(0)); // write units
                          }
                          
                          void loop(void){
                              // timer for loop delays
                              unsigned long now = millis();
                              gw.process() ;
                              // If no time has been received yet, request it every 10 second from controller
                              // When time has been received, request update every hour
                              if ((!timeReceived && (now-lastRequest > 10*1000)) ||   
                                  (now-lastRequest > 3600000UL)){                 // request update every hour to keep in sync
                                 // Request time from controller. 
                                 Serial.println("requesting time");
                                 timeReceived = false;
                                 gw.requestTime(receiveTime);  
                                 lastRequest = now;
                                  }
                              // Change display and update sensors every 5 seconds (default = 5000)
                              if (now-lastDisplay > 5000){
                                  lastDisplay = now;
                                  gw.request(LCD1_CHILD, V_TEXT, 0);                  // request new values from controller
                                  gw.request(LCD2_CHILD, V_TEXT, 0);                ;// request new values from controller
                                  // change display 
                                  display_no++;
                                      if (display_no >= 2){ // wrap for number of different displays for second line
                                      display_no = 0;
                                      }
                                  }
                              // Update display every second
                              if (now-lastUpdate > 1000) {
                                  LCD_local_display();
                                  lastUpdate = now;
                                  }
                              }
                          
                          // This is called when a new time value was received
                          void receiveTime(unsigned long controllerTime) {
                              Serial.print("Time value received: ");
                              Serial.println(controllerTime);
                              setTime(controllerTime);                            // time from controller
                              timeReceived = true;
                              }
                          
                          // This is called when a message is received 
                          void incomingMessage(const MyMessage &message) {
                              if (message.type==V_TEXT) {                         // Text messages only
                               // Write some debug info
                               Serial.print("Message: "); Serial.print(message.sensor); Serial.print(", Message: "); Serial.println(message.getString());
                              if (message.sensor == LCD1_CHILD ) {
                                  snprintf(lastLCD1, sizeof(lastLCD1), "%16s", message.getString());  // load text into LCD string
                                  }
                              else if (message.sensor == LCD2_CHILD){
                                  snprintf(lastLCD2, sizeof(lastLCD2), "%16s", message.getString());
                                  }
                              } 
                          }
                          
                          void LCD_local_display(void){
                          // take car of LCD display information
                              char buf[17]; // temp buffer for max 16 char display
                              // start with location & time on first line
                              snprintf(buf, sizeof buf, "%02d:%02d:%02d %02d-%02d", hour(), minute(), second(), day(), month());
                              lcd.setCursor(0, 0);
                              lcd.print(buf);
                              lcd.setCursor(0, 1);
                              if (display_no == 0){
                                lcd.print(lastLCD1);                          // second line is text value from controller
                              } else {                                        // display == 2
                                lcd.print(lastLCD2);
                              }
                          }
                          
                          

                          Thxs

                          AWIA Offline
                          AWIA Offline
                          AWI
                          Hero Member
                          wrote on last edited by AWI
                          #30

                          @Marc-Olivier-Chaubet You should be receiving the TEXT value coming from the controller. Is node showing other information on serial?

                          // This is called when a message is received 
                          void incomingMessage(const MyMessage &message) {
                               // Write some debug info
                               Serial.print("Message: "); Serial.print(message.sensor); Serial.print(", Message: "); Serial.println(message.getString());
                              if (message.type==V_TEXT) {                         // Text messages only
                               // Write some debug info
                               Serial.print("Text Message: "); Serial.print(message.sensor); Serial.print(", Message: "); Serial.println(message.getString());
                              if (message.sensor == LCD1_CHILD ) {
                                  snprintf(lastLCD1, sizeof(lastLCD1), "%16s", message.getString());  // load text into LCD string
                                  }
                              else if (message.sensor == LCD2_CHILD){
                                  snprintf(lastLCD2, sizeof(lastLCD2), "%16s", message.getString());
                                  }
                              } 
                          }
                          

                          In incomingmessage routing add a print statement to show which messages are coming in (see above).

                          1 Reply Last reply
                          0
                          • Marc-Olivier ChaubetM Offline
                            Marc-Olivier ChaubetM Offline
                            Marc-Olivier Chaubet
                            wrote on last edited by
                            #31

                            Hi,
                            I've change this line with "!=" and it work. but i dont undestand why....?

                            
                            void incomingMessage(const MyMessage &message) {
                                if (message.type!=V_TEXT) {                         // Text messages only
                            
                            AWIA 1 Reply Last reply
                            0
                            • Marc-Olivier ChaubetM Marc-Olivier Chaubet

                              Hi,
                              I've change this line with "!=" and it work. but i dont undestand why....?

                              
                              void incomingMessage(const MyMessage &message) {
                                  if (message.type!=V_TEXT) {                         // Text messages only
                              
                              AWIA Offline
                              AWIA Offline
                              AWI
                              Hero Member
                              wrote on last edited by
                              #32

                              @Marc-Olivier-Chaubet A closer look at what happens on you seria outputl:
                              0_1476200021647_upload-770a6b42-dfb9-43dc-b647-0957e02cc9b8

                              • on the first 2 lines there are 2 requests for values from your controller. The "t=47' indicates that the type is V_TEXT.
                              • on the the third line you receive a value with payload "test". however the 't=16' indicates that this is a V_TRIPPED value. (see Serial Protocol).

                              So there is something completely wrong. What is your controller and does it show the right types of sensors?

                              1 Reply Last reply
                              0
                              • Q Qu3Uk

                                @NiklasO

                                Here is it.

                                // Enable debug prints to serial monitor
                                //#define MY_DEBUG
                                
                                //#define MY_NODE_ID 200
                                #define MY_SENSOR_ID 1
                                
                                // Enable and select radio type attached
                                #define MY_RADIO_NRF24
                                //#define MY_RADIO_RFM69
                                
                                // Enable repeater functionality for this node
                                #define MY_REPEATER_FEATURE
                                
                                // LCD includes
                                #include <Wire.h> 
                                #include <LiquidCrystal_I2C.h>
                                
                                // MYS includes
                                #include <SPI.h>
                                #include <MySensors.h>
                                
                                #define LCD_ON 1  // GPIO value to write to turn on attached relay
                                #define LCD_OFF 0 // GPIO value to write to turn off attached relay
                                
                                LiquidCrystal_I2C lcd(0x3f, 20, 4); //0x3f is the LCD address.
                                String LINE_BLANK = "                    ";
                                
                                void before() {
                                }
                                
                                void setup() {
                                  // Set off  LCD module
                                  lcd.begin (); 
                                  lcd.backlight();
                                
                                  lcd.setCursor(0, 0); //
                                  lcd.print("Ready!"); // We expect the controller to remove this from display.
                                }
                                
                                void presentation()
                                {
                                  // Send the sketch version information to the gateway and Controller
                                  sendSketchInfo("LCD Display", "1.0");
                                
                                  present(MY_SENSOR_ID, S_INFO);
                                }
                                
                                
                                void loop()
                                {
                                  // extra processing if required.
                                }
                                
                                void receive(const MyMessage &message) {
                                  // We only expect one type of message from controller. But we better check anyway.
                                  if (message.type == V_STATUS) {
                                    // Use V_STATUS to turn on/off the LCD display
                                    // if supported by LCD.
                                  }
                                
                                  // temp string, probably don't need this.
                                  if (message.type == V_VAR1) {
                                    writeScreen(0, message.data);
                                  }
                                
                                  if (message.type == V_VAR2) {
                                    writeScreen(1, message.data);
                                  }
                                
                                  if (message.type == V_VAR3) {
                                    writeScreen(2, message.data);
                                  }
                                
                                  if (message.type == V_VAR4) {
                                    writeScreen(3, message.data);
                                  }
                                }
                                
                                void writeScreen(int line, String text)
                                {
                                  // Trim whitespace from incoming text.
                                  text.trim();
                                
                                  // Remove anything over 20 char in text.
                                  if(text.length() > 19)
                                  {
                                      text.remove(20);
                                  }
                                  
                                  // Clear the line
                                  lcd.setCursor(0, line);
                                  lcd.print(LINE_BLANK);
                                
                                  // Set Line
                                  lcd.setCursor(0, line);
                                  lcd.print(text);
                                }
                                
                                user1306U Offline
                                user1306U Offline
                                user1306
                                wrote on last edited by
                                #33

                                @Qu3Uk

                                thank you very much for sharing your code.
                                sorry this might be simple but i'm not sure how do you send text to the display? How do you update V_VAR1 in domoticz?

                                thanks

                                AWIA 1 Reply Last reply
                                0
                                • NiklasON Offline
                                  NiklasON Offline
                                  NiklasO
                                  wrote on last edited by NiklasO
                                  #34

                                  This is my test code. Not optimized, just testing. I have just started to play with arduino (got my first ever this month) so I can't say I know what I am doing. ;) Made som changes in the code below, not tested yet. It compiles, guess that's good. ;)

                                  I have commented out stuff related to line1 because that is always showing the time and date, in code, from GW/controller. Enable if you want to control all 4 lines from Domoticz.

                                  Update display by using the domoticz api:
                                  json.htm?type=command&param=udevice&idx=XXXX&nvalue=0&svalue=Banana
                                  Replace XXXX with the IDX for each of the 3 lines. You'll see it when adding the 3 text devices in Domoticz. Then use the Event-system in Domoticz to add Lua-script to update the display as example in this thread.

                                  //Credits: https://forum.mysensors.org/topic/1957/lcd-clock-and-text-sensor-node-with-new-v_text
                                  
                                  //Soft signing.
                                  //#define MY_SIGNING_SOFT
                                  //#define MY_SIGNING_REQUEST_SIGNATURES
                                  //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
                                  
                                  #define MY_RADIO_NRF24
                                  #define MY_REPEATER_FEATURE
                                  #define MY_DEBUG
                                  
                                  #include <TimeLib.h>
                                  #include <Wire.h>
                                  #include <LiquidCrystal_I2C.h>
                                  #include <SPI.h>
                                  #include <MySensors.h>
                                  
                                  //char lastLCD1[21] = "Line1"; //Line 1 always showing current time
                                  char lastLCD2[21] = "Line2";
                                  char lastLCD3[21] = "Line3";
                                  char lastLCD4[21] = "Line4";
                                  
                                  //20 whitespace characters used to clear your LCD line before printing to it.
                                  //Change to fit your LCD. Don't forget to change number of chars in the writeScreen function if needed.
                                  String LINE_BLANK = "                    ";
                                  
                                  boolean timeReceived = false ;
                                  unsigned long lastUpdate = 0, lastRequest = 0, lastDisplay = 0;
                                  
                                  //const byte LCD1_CHILD = 1;                          // Child ID for LCD line 1
                                  const byte LCD2_CHILD = 2;                          // Child ID for LCD line 2
                                  const byte LCD3_CHILD = 3;                          // Child ID for LCD line 3
                                  const byte LCD4_CHILD = 4;                          // Child ID for LCD line 4
                                  
                                  MyMessage textMsg(0, V_TEXT);
                                  
                                  // Initialize display. Google the correct settings for your display.
                                  // The follwoing setting should work for the recommended display in the MySensors "shop".
                                  LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
                                  
                                  void before() {
                                    Wire.begin();                                       // I2C.
                                    lcd.begin(20, 4);                                   // LCD with 20 chars, 4 lines.
                                    lcd.setBacklight(HIGH);                             // Make sure backlight is on.
                                    writeScreen(0, "Waiting for GW...");                // Print initial text before contact with GW.                 
                                  }
                                  
                                  void setup(void)
                                  {
                                    Serial.begin(115200);                               // Start serial.
                                    requestTime();                                      // Request time from controller.
                                  }
                                  
                                  void presentation()  {
                                  
                                    sendSketchInfo("Domoticz LCD", "1.0");                    // Send the sketch version information to the gateway and Controller
                                  
                                    //present(LCD1_CHILD, S_INFO, "LCD_line1");
                                    //wait(500);
                                    present(LCD2_CHILD, S_INFO, "LCD_line2");
                                    wait(500);
                                    present(LCD3_CHILD, S_INFO, "LCD_line3");
                                    wait(500);
                                    present(LCD4_CHILD, S_INFO, "LCD_line4");
                                    wait(500);
                                    //send(textMsg.setSensor(LCD1_CHILD).set("-"));      // initialize the V_TEXT at controller for sensor to none (trick for Domoticz)
                                    send(textMsg.setSensor(LCD2_CHILD).set("-"));
                                    send(textMsg.setSensor(LCD3_CHILD).set("-"));
                                    send(textMsg.setSensor(LCD4_CHILD).set("-"));
                                  }
                                  
                                  void loop()     {
                                    // timer for loop delays
                                    unsigned long now = millis();
                                    // If no time has been received yet, request it every 10 second from controller
                                    // When time has been received, request update every hour
                                    if ((!timeReceived && (now - lastRequest > 10 * 1000)) ||
                                        (now - lastRequest > 3600000UL)) {              // request update from GW every hour to keep in sync
                                      // Request time from controller.
                                      Serial.println("Requesting time...");
                                      timeReceived = false;
                                      requestTime();
                                      lastRequest = now;
                                    }
                                  
                                    // Update sensors every 5 seconds
                                    if (now - lastDisplay > 5000) {
                                      lastDisplay = now;
                                      //request(LCD1_CHILD, V_TEXT, 0);                  // request new values from controller
                                      request(LCD2_CHILD, V_TEXT, 0);                  // request new values from controller
                                      request(LCD3_CHILD, V_TEXT, 0);                  // request new values from controller
                                      request(LCD4_CHILD, V_TEXT, 0);                  // request new values from controller
                                    }
                                  
                                    // Update LCD time every second
                                    if (now - lastUpdate > 1000) {
                                      LCD_time();
                                      lastUpdate = now;
                                    }
                                  }
                                  
                                  // This is called when a message is received
                                  void receive(const MyMessage &message) {
                                    if (message.type == V_TEXT) {                       // Text messages only
                                      Serial.print("Message: "); Serial.print(message.sensor); Serial.print(", Message: "); Serial.println(message.getString());     // Write some debug info
                                      //if (message.sensor == LCD1_CHILD) {
                                      //  writeScreen(0, message.data);
                                      //}
                                  
                                  // Don't forget to change "if" to "else if" when controlling all 4 lines:
                                      if (message.sensor == LCD2_CHILD) {
                                        writeScreen(1, message.data);
                                      }
                                      else if (message.sensor == LCD3_CHILD) {
                                        writeScreen(2, message.data);
                                      }
                                      else if (message.sensor == LCD4_CHILD) {
                                        writeScreen(3, message.data);
                                      }
                                    }
                                  }
                                  
                                  void receiveTime(unsigned long ts) {
                                    setTime(ts);
                                    timeReceived = true;
                                  }
                                  
                                  void LCD_time(void) {
                                    lcd.setCursor(0, 0);
                                    if (timeReceived) {
                                      lcd.print(year());
                                      lcd.print("-");
                                      printDigits(month());
                                      lcd.print("-");
                                      printDigits(day());
                                      lcd.print("     ");
                                      printDigits(hour());
                                      lcd.print(":");
                                      printDigits(minute());
                                    } else {
                                      writeScreen(0, "Waiting for time...");
                                    }
                                  }
                                  
                                  void printDigits(int digits) {
                                  //add leading 0 if digit = 0-9
                                    if (digits < 10)
                                      lcd.print('0');
                                    lcd.print(digits);
                                  }
                                  
                                  void writeScreen(int line, String text)
                                  {
                                    // Remove anything over 20 char in text.
                                    if (text.length() > 19)
                                    {
                                      text.remove(20);
                                    }
                                  
                                    // Clear the line
                                    lcd.setCursor(0, line);
                                    lcd.print(LINE_BLANK);
                                  
                                    // Set Line
                                    lcd.setCursor(0, line);
                                    lcd.print(text);
                                  }
                                  
                                  1 Reply Last reply
                                  1
                                  • user1306U user1306

                                    @Qu3Uk

                                    thank you very much for sharing your code.
                                    sorry this might be simple but i'm not sure how do you send text to the display? How do you update V_VAR1 in domoticz?

                                    thanks

                                    AWIA Offline
                                    AWIA Offline
                                    AWI
                                    Hero Member
                                    wrote on last edited by
                                    #35

                                    @user1306 V_VAR1 in Domoticz can not be updated or changed in Domotics (Blockly/ Lua/ Json, etc.). It's can only be used to store and retrieve values from MySensors. You should use V_TEXT as in the original example.

                                    1 Reply Last reply
                                    0
                                    • user1306U Offline
                                      user1306U Offline
                                      user1306
                                      wrote on last edited by
                                      #36

                                      thanks guy for the help,
                                      what i'm trying to do, is send text to the display (16x2) using both lines (dont really need the time on top), and attach a 4 button keypad on it. then have these buttons sends commands (on.off) to Domoticz which will trigger Event and send that data/text back to the display.
                                      if i manage to figure it out i'll post my code.

                                      1 Reply Last reply
                                      0
                                      • AndurilA Offline
                                        AndurilA Offline
                                        Anduril
                                        wrote on last edited by
                                        #37

                                        Is there a limitation in text length? I plan to use a bigger display and want to maybe send strings with 30+ chars. Is it impossible (maybe then split this into two strings) or is it internally seperated in 2 messages (as nrf-payload is 32 byte - 7 byte MySensors-header)?

                                        AWIA 1 Reply Last reply
                                        0
                                        • AndurilA Anduril

                                          Is there a limitation in text length? I plan to use a bigger display and want to maybe send strings with 30+ chars. Is it impossible (maybe then split this into two strings) or is it internally seperated in 2 messages (as nrf-payload is 32 byte - 7 byte MySensors-header)?

                                          AWIA Offline
                                          AWIA Offline
                                          AWI
                                          Hero Member
                                          wrote on last edited by
                                          #38

                                          @Anduril The text length is limited to the maximum payload size. So I guess you need to do some tweaking ;)

                                          sellierS 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          12

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.1k

                                          Posts


                                          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular