gw send, how to do in my combination of sensors



  • In my project in development, I miss the GW send for my motion detector. I tried several options but nothing works. Anyone an idea, how to?

    #include <MySensor.h>
    #include <SPI.h>
    #include "Bounce2.h"
    #define USE_MOTION_SENSOR
    #define MOTION_SENSOR_PIN    3          //physical number of PIR
    #define LIGHT_SENSOR_ANALOG_PIN A0      //physical number of LDR
    #define CHILD_ID_LIGHT 6
    #define RELAY_ON 0                      // switch around for realy HIGH/LOW state
    #define RELAY_OFF 1
    
    Bounce motionsDebouncer = Bounce();
    
    MySensor gw;
    
    #define RADIO_ID 11                    // radio Id, whatever channel you assigned to
    #define noRelays 5                     //number of relais in use
    const int relayPin[] = {A1, A2, A3, A4, A5}; //  switch around pins to your desire number of relais
    const int buttonPin[] = {4, 5, 6, 7, 8   }; //  switch around pins to your desire number of buttons
    
    class Relay             // relay class, store all relevant data (equivalent to struct)
    {
    public: 
      int buttonPin;                    // physical pin number of button
      int relayPin;                     // physical pin number of relay
      byte oldValue;                    // last Values for key (debounce)
      boolean relayState;               // relay status (also stored in EEPROM)
    };
    
    Relay Relays[noRelays]; 
    Bounce debouncer[noRelays];
    MyMessage msgRelay[noRelays];
    MyMessage msgLDR(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    
    int lastLightLevel;
    unsigned long SLEEP_TIME = 6000; // Sleep time between reads (in milliseconds)
    
    void setup()
    {
      gw.begin(incomingMessage, RADIO_ID, true);
      delay(250);
      gw.sendSketchInfo("Multy-Relay&button-PIR&LDR", "0.2");
      delay(250);
      gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
    
      pinMode( MOTION_SENSOR_PIN, INPUT_PULLUP );
      motionsDebouncer.attach(MOTION_SENSOR_PIN);
      motionsDebouncer.interval(50);
    
      // Initialize Relays with corresponding buttons
      for (int i = 0; i < noRelays; i++)
      {
        Relays[i].buttonPin = buttonPin[i];              // assign physical pins
        Relays[i].relayPin = relayPin[i];
        msgRelay[i].sensor = i;                                   // initialize messages
        msgRelay[i].type = V_LIGHT;
        debouncer[i] = Bounce();                        // initialize debouncer
        debouncer[i].attach(buttonPin[i]);
        debouncer[i].interval(5);
        pinMode(Relays[i].buttonPin, INPUT_PULLUP);
        pinMode(Relays[i].relayPin, OUTPUT);
        Relays[i].relayState = gw.loadState(i);                               // retrieve last values from EEPROM
        digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly
        gw.send(msgRelay[i].set(Relays[i].relayState ? true : false));                 // make controller aware of last status
        gw.present(i, S_LIGHT);                               // present sensor to gateway
        delay(250);
    
      }
    }
    
    void loop()
    {
      if ( motionsDebouncer.update()) {
        int value = motionsDebouncer.read();
        Serial.println( "PIR " + (String)value );
      }
    {
      gw.process();
      for (byte i = 0; i < noRelays; i++)
      {
        debouncer[i].update();
        byte value = debouncer[i].read();
        if (value != Relays[i].oldValue && value == 0)
        {
          Relays[i].relayState = !Relays[i].relayState;
          digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF);
          gw.send(msgRelay[i].set(Relays[i].relayState ? true : false));
          gw.saveState( i, Relays[i].relayState );
        }                 // save sensor state in EEPROM (location == sensor number)
    
        Relays[i].oldValue = value;
      }
       int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23; 
      //Serial.println(LDR);
     if ((lightLevel > 1.05 * lastLightLevel)||(lightLevel < 0.95 * lastLightLevel))    //5% difference will send 
      {
           gw.send(msgLDR.set(lightLevel));
    
          lastLightLevel = lightLevel;
          Serial.print("LDR");
          
          Serial.println(lightLevel);
          
      }
    }
    }
    // process incoming message
    void incomingMessage(const MyMessage &message)
    {
    
      if (message.type == V_LIGHT)
      {
        if (message.sensor < noRelays)            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
        {
          Relays[message.sensor].relayState = message.getBool();
          digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly
          gw.saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
        }
      }
     // delay( 50 ); // give the input pins some rest. Incomming messages are still being processed.
    gw.wait(50);
    
    }
    

  • MySensors Evangelist

    @Dick I assume you are working on a version < 2.0.0. if I look at your sketch??



  • not yet, stil working with the 1.54. in the IDE serial it works all fine but the motion sensor is not visible in DOMOTICZ and probably because I do not send to GW but I am new in this area so support is welcome.


  • Mod

    @Dick have you looked at the motion example? https://www.mysensors.org/build/motion



  • @mfalkvidd
    Yes I did bud than I do not understand what I have now,

    if ( motionsDebouncer.update()) {
        int value = motionsDebouncer.read();
        Serial.println( "PIR " + (String)value );```
    
    only a GW send row needed or is that not right?
    
    What I saw on the https://www.mysensors.org/build/motion
    was clear but after implementation I got several errors during the compilation so I thought, perhaps only something with GW.send
    
    Or am I wrong?

  • Contest Winner

    @Dick added some comments in the code. And made some changes. It compiles. But I can't test it for you..

    #include <MySensor.h>
    #include <SPI.h>
    #include "Bounce2.h"
    #define USE_MOTION_SENSOR
    #define MOTION_SENSOR_PIN    3          //physical number of PIR
    #define LIGHT_SENSOR_ANALOG_PIN A0      //physical number of LDR
    #define CHILD_ID_LIGHT 6
    #define RELAY_ON 0                      // switch around for realy HIGH/LOW state
    #define RELAY_OFF 1
    
    Bounce motionsDebouncer = Bounce();
    
    MySensor gw;
    
    #define RADIO_ID 11                    // radio Id, whatever channel you assigned to
    #define noRelays 5                     //number of relais in use
    const int relayPin[] = {A1, A2, A3, A4, A5}; //  switch around pins to your desire number of relais
    const int buttonPin[] = {4, 5, 6, 7, 8   }; //  switch around pins to your desire number of buttons
    
    // <-- byTheo since you don't have any methods in your class, a simple C struct made be
    //                    more resource friendly
    class Relay             // relay class, store all relevant data (equivalent to struct)
    {
      public:
        int buttonPin;                    // physical pin number of button
        int relayPin;                     // physical pin number of relay
        byte oldValue;                    // last Values for key (debounce)
        boolean relayState;               // relay status (also stored in EEPROM)
    };
    
    Relay Relays[noRelays];
    Bounce debouncer[noRelays];
    MyMessage msgRelay[noRelays];
    MyMessage msgLDR(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    
    
    #define MOTION_CHILD_ID 8 // <-- byTheo
    MyMessage motionMsg( MOTION_CHILD_ID, V_TRIPPED ); // <-- byTheo
    
    int lastLightLevel;
    unsigned long SLEEP_TIME = 6000; // Sleep time between reads (in milliseconds)
    
    void setup()
    {
      gw.begin(incomingMessage, RADIO_ID, true);
      //  delay(250); // <-- byTheo
      gw.wait( 250 ); // <-- byTheo
      gw.sendSketchInfo("Multy-Relay&button-PIR&LDR", "0.2");
      //  delay(250); // <-- byTheo
      gw.wait( 250 ); // <-- byTheo
      gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
    
      pinMode( MOTION_SENSOR_PIN, INPUT_PULLUP );
      motionsDebouncer.attach(MOTION_SENSOR_PIN); // <---- byTheo I believe PIR sensors don't need debouncing
      motionsDebouncer.interval(50); // <---- byTheo I believe PIR sensors don't need debouncing
    
      // Initialize Relays with corresponding buttons
      for (int i = 0; i < noRelays; i++)
      {
        Relays[i].buttonPin = buttonPin[i];              // assign physical pins
        Relays[i].relayPin = relayPin[i];
        msgRelay[i].sensor = i;                                   // initialize messages
        msgRelay[i].type = V_LIGHT;
        debouncer[i] = Bounce();                        // initialize debouncer
        debouncer[i].attach(buttonPin[i]);
        debouncer[i].interval(5);
        pinMode(Relays[i].buttonPin, INPUT_PULLUP);
        pinMode(Relays[i].relayPin, OUTPUT);
        Relays[i].relayState = gw.loadState(i);                               // retrieve last values from EEPROM
        digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly
        gw.send(msgRelay[i].set(Relays[i].relayState ? true : false));                 // make controller aware of last status
        gw.present(i, S_LIGHT);                               // present sensor to gateway
        //  delay(250); // <-- byTheo
        gw.wait( 250 ); // <-- byTheo
    
      }
    
      gw.present( MOTION_CHILD_ID, S_MOTION, "Motion needs presentation", true ); // byTheo
      gw.wait( 250 ); // <-- byTheo
    }
    
    void loop()
    {
      if ( motionsDebouncer.update()) {
        int value = motionsDebouncer.read();
        Serial.println( "PIR " + (String)value );
        gw.send( motionMsg.set( value ), true ); // <-- byTheo : Also it might need inverted value
    
      }
      //  { <--- byTheo
      gw.process();
      for (byte i = 0; i < noRelays; i++)
      {
        debouncer[i].update();
        byte value = debouncer[i].read();
        if (value != Relays[i].oldValue && value == 0)
        {
          Relays[i].relayState = !Relays[i].relayState;
          digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF);
          gw.send(msgRelay[i].set(Relays[i].relayState ? true : false));
          gw.saveState( i, Relays[i].relayState );
        }                 // save sensor state in EEPROM (location == sensor number)
    
        Relays[i].oldValue = value;
      }
      int lightLevel = (1023 - analogRead(LIGHT_SENSOR_ANALOG_PIN)) / 10.23;
      //Serial.println(LDR);
      if ((lightLevel > 1.05 * lastLightLevel) || (lightLevel < 0.95 * lastLightLevel))  //5% difference will send
      {
        gw.send(msgLDR.set(lightLevel));
    
        lastLightLevel = lightLevel;
        Serial.print("LDR");
    
        Serial.println(lightLevel);
    
      }
      // } // <---- byTheo
    }
    // process incoming message
    void incomingMessage(const MyMessage &message)
    {
    
      if (message.type == V_LIGHT)
      {
        if (message.sensor < noRelays)            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
        {
          Relays[message.sensor].relayState = message.getBool();
          digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly
          gw.saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
        }
      }
      // delay( 50 ); // give the input pins some rest. Incomming messages are still being processed.
    //  gw.wait(50); // <-- byTheo don't use delays in message handler. Message handler needs the shortest execution time is possible
    
    }
    


  • @TheoL
    Hi Theo, the devil is playing with me, my PI stopped working and that is my Domoticz location. I read your commend, thank you for that, I am probably not able to test it this evening.
    sorry for that> I inform you about the results.


  • Contest Winner

    Hello @Dick,

    Don't be sorry. Just let me know if this is what you wanted after you've tested it.



  • @TheoL My Domoticz works again, I have to give it a fix ip because the IP was change and for your info, Your solution worked very well. It is now visible in Domoticz. Thanks for the support now I have to wait for other parts, I wait for my last parts for this project, an IR receiver so I can use a remote controle. After that I can use this project as a universal project, a default design in basic.
    Again thanks!


Log in to reply
 

474
Online

6.9k
Users

7.8k
Topics

82.7k
Posts

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.