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
 

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