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. Troubleshooting
  3. Multisensor PIR problem [solved]

Multisensor PIR problem [solved]

Scheduled Pinned Locked Moved Troubleshooting
53 Posts 7 Posters 22.7k Views 3 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.
  • BulldogLowellB BulldogLowell

    @n3ro

    you are sending an update on the PIR status every time the arduino wakes from a sleep, which you don't need.

    Also, and this probably isn't a problem right now, but will case a problem later, use unsigned subtraction in your millis( ) timers

    could not see where you were using the library, so I commented it out below, not having it on my computer

    I also made a few more notes in the code:

    #include <MySensor.h>
    //#include <readVcc.h> // cannot see where you are using this library yet
    #include <SPI.h>
    #include <DHT.h>
    
    #define NODE_ID 10                       // ID of node
    unsigned long SLEEP_TIME = 10000UL;        // Sleep time between reports (in milliseconds)
    
    #define CHILD_ID_PIR 1                   // Id of the sensor PIR
    #define CHILD_ID_HUM 2                   // Id of the sensor HUM
    #define CHILD_ID_TEMP 3                  // Id of the sensor TEMP
    #define CHILD_ID_LIGHT 4                 // Id of the sensor LIGHT
    
    #define PIR_SENSOR_DIGITAL 3           // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define INTERRUPT PIR_SENSOR_DIGITAL-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    #define HUMIDITY_SENSOR_DIGITAL_PIN 2
    #define LIGHT_SENSOR_ANALOG_PIN 0
    
    MySensor gw;
    // Initialize Variables
    MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED);
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    
    DHT dht;
    float lastTemp;
    float lastHum;
    boolean metric = true;
    boolean lastTripped = false;
    int oldBatteryPcnt;
    int lastLightLevel;
    unsigned long mytime;
    //int MIN_V = 2700; // empty voltage (0%)
    //int MAX_V = 3200; // full voltage (100%)
    
    void setup()
    {
      gw.begin(NULL, NODE_ID, false);
      gw.sendSketchInfo("Motion Sensor", "1.0"); // here you call it motion sensor
      pinMode(PIR_SENSOR_DIGITAL, INPUT_PULLUP);
      gw.present(CHILD_ID_PIR, S_MOTION);
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
      //gw.sendSketchInfo("Humidity", "1.0"); // here you call it humidity
      gw.present(CHILD_ID_HUM, S_HUM);
      gw.present(CHILD_ID_TEMP, S_TEMP);
      metric = gw.getConfig().isMetric;
      //gw.sendSketchInfo("Light Sensor", "1.0");// pick a name for your sketch, it will only be one
      gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
    }
    
    void loop()
    {
      // why send this every time?  
      /*
      boolean tripped = digitalRead(PIR_SENSOR_DIGITAL) == HIGH;
      Serial.print("---------- PIR: ");
      Serial.println(tripped);
      gw.send(msgPir.set(tripped ? "1" : "0"));
      */
      boolean tripped = digitalRead(PIR_SENSOR_DIGITAL) == HIGH;
      if (tripped != lastTripped)  // only need to update controller on a change.
      {
        gw.send(msgPir.set(tripped? "1" : "0"));
        Serial.print("---------- PIR: ");
        Serial.println(tripped? "tripped" : " not tripped");
        lastTripped = tripped;
      }
      if ( millis() - mytime >= SLEEP_TIME )  //use UNSIGNED SUBRTACTION im your millis() timers to avoid rollover issues later on down the line
      {
        float temperature = dht.getTemperature();
        if (isnan(temperature))
        {
          Serial.println("Failed reading temperature from DHT");
        }
        else if (temperature != lastTemp)
        {
          lastTemp = temperature;
          if (!metric) 
          {
            temperature = dht.toFahrenheit(temperature);
          }
          gw.send(msgTemp.set(temperature, 1));
          Serial.print("---------- Temp: ");
          Serial.println(temperature);
        }
        float humidity = dht.getHumidity();
        if (isnan(humidity)) 
        {
          Serial.println("Failed reading humidity from DHT");
        } 
        else if (humidity != lastHum) 
        {
          lastHum = humidity;
          gw.send(msgHum.set(humidity, 1));
          Serial.print("---------- Humidity: ");
          Serial.println(humidity);
        }
        mytime = millis();
      }
      gw.sleep(INTERRUPT, CHANGE, SLEEP_TIME); // Sleep until interrupt detected from motion sensor. Send update every SLEEP_TIME.
    }
    
    n3roN Offline
    n3roN Offline
    n3ro
    wrote on last edited by
    #44

    @BulldogLowell

    Hey, its a good idea to send only PIR if changed!
    The unused code in the sketch is because i have reduced the used functions to the minimum to debug it better. The full sketch has LDR and battery lifetime output too.

    i have added some extra output in the modified sketch:

    #include <MySensor.h>
    //#include <readVcc.h> // cannot see where you are using this library yet
    #include <SPI.h>
    #include <DHT.h>
    
    #define NODE_ID 10                       // ID of node
    unsigned long SLEEP_TIME = 10000UL;        // Sleep time between reports (in milliseconds)
    
    #define CHILD_ID_PIR 1                   // Id of the sensor PIR
    #define CHILD_ID_HUM 2                   // Id of the sensor HUM
    #define CHILD_ID_TEMP 3                  // Id of the sensor TEMP
    #define CHILD_ID_LIGHT 4                 // Id of the sensor LIGHT
    
    #define PIR_SENSOR_DIGITAL 3           // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define INTERRUPT PIR_SENSOR_DIGITAL-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    #define HUMIDITY_SENSOR_DIGITAL_PIN 2
    #define LIGHT_SENSOR_ANALOG_PIN 0
    
    MySensor gw;
    // Initialize Variables
    MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED);
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    
    DHT dht;
    float lastTemp;
    float lastHum;
    boolean metric = true;
    boolean lastTripped = false;
    int oldBatteryPcnt;
    int lastLightLevel;
    unsigned long mytime;
    //int MIN_V = 2700; // empty voltage (0%)
    //int MAX_V = 3200; // full voltage (100%)
    
    void setup()
    {
      gw.begin(NULL, NODE_ID, false);
      gw.sendSketchInfo("Motion Sensor", "1.0"); // here you call it motion sensor
      pinMode(PIR_SENSOR_DIGITAL, INPUT_PULLUP);
      gw.present(CHILD_ID_PIR, S_MOTION);
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
      //gw.sendSketchInfo("Humidity", "1.0"); // here you call it humidity
      gw.present(CHILD_ID_HUM, S_HUM);
      gw.present(CHILD_ID_TEMP, S_TEMP);
      metric = gw.getConfig().isMetric;
      //gw.sendSketchInfo("Light Sensor", "1.0");// pick a name for your sketch, it will only be one
      gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
    }
    
    void loop()
    {
      // why send this every time?
      /*
      boolean tripped = digitalRead(PIR_SENSOR_DIGITAL) == HIGH;
      Serial.print("---------- PIR: ");
      Serial.println(tripped);
      gw.send(msgPir.set(tripped ? "1" : "0"));
      */
      boolean tripped = digitalRead(PIR_SENSOR_DIGITAL) == HIGH;
      if (tripped != lastTripped)  // only need to update controller on a change.
      {
        gw.send(msgPir.set(tripped ? "1" : "0"));
        Serial.print("---------- PIR: ");
        Serial.println(tripped ? "tripped" : " not tripped");
        lastTripped = tripped;
      }
      if ( millis() - mytime >= SLEEP_TIME )  //use UNSIGNED SUBRTACTION im your millis() timers to avoid rollover issues later on down the line
      {
        delay(dht.getMinimumSamplingPeriod());
        float temperature = dht.getTemperature();
        if (isnan(temperature))
        {
          Serial.println("Failed reading temperature from DHT");
        }
        else if (temperature != lastTemp)
        {
          lastTemp = temperature;
          if (!metric)
          {
            temperature = dht.toFahrenheit(temperature);
          }
          gw.send(msgTemp.set(temperature, 1));
          Serial.print("---------- Temp: ");
          Serial.println(temperature);
        }
        float humidity = dht.getHumidity();
        if (isnan(humidity))
        {
          Serial.println("Failed reading humidity from DHT");
        }
        else if (humidity != lastHum)
        {
          lastHum = humidity;
          gw.send(msgHum.set(humidity, 1));
          Serial.print("---------- Humidity: ");
          Serial.println(humidity);
        }
        mytime = millis();
    
      }
      else
      {
        Serial.println("no millis");
      }
      Serial.println(millis());
      Serial.println(mytime);
      Serial.println(SLEEP_TIME);
      gw.sleep(INTERRUPT, CHANGE, SLEEP_TIME); // Sleep until interrupt detected from motion sensor. Send update every SLEEP_TIME.
    }
    

    send: 10-10-0-0 s=1,c=1,t=16,pt=0,l=1,st=fail:0
    ---------- PIR: not tripped
    no millis
    2185
    0
    10000
    no millis
    2189
    0
    10000
    no millis
    2193
    0
    10000
    no millis
    2195
    0
    10000
    no millis
    2197
    0
    10000
    no millis
    2201
    0
    10000
    no millis
    2203
    0
    10000
    no millis
    2205
    0
    10000
    no millis
    2209
    0
    10000
    no millis
    2211
    0
    10000
    no millis

    You can see that the "if millis" will never used .:(

    pimatic + MySensors + Homeduino + z-way
    https://github.com/n3roGit/MySensors_n3ro

    1 Reply Last reply
    0
    • n3roN Offline
      n3roN Offline
      n3ro
      wrote on last edited by
      #45

      i think millis didnt work with sleep. the counter is not increasing when sleeping..

      pimatic + MySensors + Homeduino + z-way
      https://github.com/n3roGit/MySensors_n3ro

      1 Reply Last reply
      0
      • BulldogLowellB Offline
        BulldogLowellB Offline
        BulldogLowell
        Contest Winner
        wrote on last edited by
        #46

        @n3ro said:

        delay(dht.getMinimumSamplingPeriod());

        you dont need this:

        delay(dht.getMinimumSamplingPeriod());
        

        since you are sleeping longer than the minimum sampling period

        try like this, removing the timer, just use the sleep period t update temp/humidity (untested):

        #include <MySensor.h>
        //#include <readVcc.h> // cannot see where you are using this library yet
        #include <SPI.h>
        #include <DHT.h>
        
        #define NODE_ID 10                       // ID of node
        unsigned long SLEEP_TIME = 10000UL;        // Sleep time between reports (in milliseconds)
        
        #define CHILD_ID_PIR 1                   // Id of the sensor PIR
        #define CHILD_ID_HUM 2                   // Id of the sensor HUM
        #define CHILD_ID_TEMP 3                  // Id of the sensor TEMP
        #define CHILD_ID_LIGHT 4                 // Id of the sensor LIGHT
        
        #define PIR_SENSOR_DIGITAL 3           // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
        #define INTERRUPT PIR_SENSOR_DIGITAL-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
        #define HUMIDITY_SENSOR_DIGITAL_PIN 2
        #define LIGHT_SENSOR_ANALOG_PIN 0
        
        MySensor gw;
        // Initialize Variables
        MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED);
        MyMessage msgHum(CHILD_ID_HUM, V_HUM);
        MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
        MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
        
        DHT dht;
        float lastTemp;
        float lastHum;
        boolean metric = true;
        boolean lastTripped = false;
        int oldBatteryPcnt;
        int lastLightLevel;
        //int MIN_V = 2700; // empty voltage (0%)
        //int MAX_V = 3200; // full voltage (100%)
        
        void setup()
        {
          gw.begin(NULL, NODE_ID, false);
          gw.sendSketchInfo("Motion Sensor", "1.0"); // here you call it motion sensor
          pinMode(PIR_SENSOR_DIGITAL, INPUT_PULLUP);
          gw.present(CHILD_ID_PIR, S_MOTION);
          dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
          //gw.sendSketchInfo("Humidity", "1.0"); // here you call it humidity
          gw.present(CHILD_ID_HUM, S_HUM);
          gw.present(CHILD_ID_TEMP, S_TEMP);
          metric = gw.getConfig().isMetric;
          //gw.sendSketchInfo("Light Sensor", "1.0");// pick a name for your sketch, it will only be one
          gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
        }
        
        void loop()
        {
          // why send this every time?
          /*
          boolean tripped = digitalRead(PIR_SENSOR_DIGITAL) == HIGH;
          Serial.print("---------- PIR: ");
          Serial.println(tripped);
          gw.send(msgPir.set(tripped ? "1" : "0"));
          */
          boolean tripped = digitalRead(PIR_SENSOR_DIGITAL) == HIGH;
          if (tripped != lastTripped)  // only need to update controller on a change.
          {
            gw.send(msgPir.set(tripped ? "1" : "0"));
            Serial.print("---------- PIR: ");
            Serial.println(tripped ? "tripped" : " not tripped");
            lastTripped = tripped;
          }
          float temperature = dht.getTemperature();
          if (isnan(temperature))
          {
            Serial.println("Failed reading temperature from DHT");
          }
          else if (temperature != lastTemp)
          {
            lastTemp = temperature;
            if (!metric)
            {
              temperature = dht.toFahrenheit(temperature);
            }
            gw.send(msgTemp.set(temperature, 1));
            Serial.print("---------- Temp: ");
            Serial.println(temperature);
          }
          float humidity = dht.getHumidity();
          if (isnan(humidity))
          {
            Serial.println("Failed reading humidity from DHT");
          }
          else if (humidity != lastHum)
          {
            lastHum = humidity;
            gw.send(msgHum.set(humidity, 1));
            Serial.print("---------- Humidity: ");
            Serial.println(humidity);
          }
          gw.sleep(INTERRUPT, CHANGE, SLEEP_TIME); // Sleep until interrupt detected from motion sensor. Send update every SLEEP_TIME.
        }
        
        n3roN 1 Reply Last reply
        0
        • BulldogLowellB BulldogLowell

          @n3ro said:

          delay(dht.getMinimumSamplingPeriod());

          you dont need this:

          delay(dht.getMinimumSamplingPeriod());
          

          since you are sleeping longer than the minimum sampling period

          try like this, removing the timer, just use the sleep period t update temp/humidity (untested):

          #include <MySensor.h>
          //#include <readVcc.h> // cannot see where you are using this library yet
          #include <SPI.h>
          #include <DHT.h>
          
          #define NODE_ID 10                       // ID of node
          unsigned long SLEEP_TIME = 10000UL;        // Sleep time between reports (in milliseconds)
          
          #define CHILD_ID_PIR 1                   // Id of the sensor PIR
          #define CHILD_ID_HUM 2                   // Id of the sensor HUM
          #define CHILD_ID_TEMP 3                  // Id of the sensor TEMP
          #define CHILD_ID_LIGHT 4                 // Id of the sensor LIGHT
          
          #define PIR_SENSOR_DIGITAL 3           // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
          #define INTERRUPT PIR_SENSOR_DIGITAL-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
          #define HUMIDITY_SENSOR_DIGITAL_PIN 2
          #define LIGHT_SENSOR_ANALOG_PIN 0
          
          MySensor gw;
          // Initialize Variables
          MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED);
          MyMessage msgHum(CHILD_ID_HUM, V_HUM);
          MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
          MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
          
          DHT dht;
          float lastTemp;
          float lastHum;
          boolean metric = true;
          boolean lastTripped = false;
          int oldBatteryPcnt;
          int lastLightLevel;
          //int MIN_V = 2700; // empty voltage (0%)
          //int MAX_V = 3200; // full voltage (100%)
          
          void setup()
          {
            gw.begin(NULL, NODE_ID, false);
            gw.sendSketchInfo("Motion Sensor", "1.0"); // here you call it motion sensor
            pinMode(PIR_SENSOR_DIGITAL, INPUT_PULLUP);
            gw.present(CHILD_ID_PIR, S_MOTION);
            dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
            //gw.sendSketchInfo("Humidity", "1.0"); // here you call it humidity
            gw.present(CHILD_ID_HUM, S_HUM);
            gw.present(CHILD_ID_TEMP, S_TEMP);
            metric = gw.getConfig().isMetric;
            //gw.sendSketchInfo("Light Sensor", "1.0");// pick a name for your sketch, it will only be one
            gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
          }
          
          void loop()
          {
            // why send this every time?
            /*
            boolean tripped = digitalRead(PIR_SENSOR_DIGITAL) == HIGH;
            Serial.print("---------- PIR: ");
            Serial.println(tripped);
            gw.send(msgPir.set(tripped ? "1" : "0"));
            */
            boolean tripped = digitalRead(PIR_SENSOR_DIGITAL) == HIGH;
            if (tripped != lastTripped)  // only need to update controller on a change.
            {
              gw.send(msgPir.set(tripped ? "1" : "0"));
              Serial.print("---------- PIR: ");
              Serial.println(tripped ? "tripped" : " not tripped");
              lastTripped = tripped;
            }
            float temperature = dht.getTemperature();
            if (isnan(temperature))
            {
              Serial.println("Failed reading temperature from DHT");
            }
            else if (temperature != lastTemp)
            {
              lastTemp = temperature;
              if (!metric)
              {
                temperature = dht.toFahrenheit(temperature);
              }
              gw.send(msgTemp.set(temperature, 1));
              Serial.print("---------- Temp: ");
              Serial.println(temperature);
            }
            float humidity = dht.getHumidity();
            if (isnan(humidity))
            {
              Serial.println("Failed reading humidity from DHT");
            }
            else if (humidity != lastHum)
            {
              lastHum = humidity;
              gw.send(msgHum.set(humidity, 1));
              Serial.print("---------- Humidity: ");
              Serial.println(humidity);
            }
            gw.sleep(INTERRUPT, CHANGE, SLEEP_TIME); // Sleep until interrupt detected from motion sensor. Send update every SLEEP_TIME.
          }
          
          n3roN Offline
          n3roN Offline
          n3ro
          wrote on last edited by
          #47

          @BulldogLowell
          when i use this sketch the PIR works but the DHT cant read:

          Failed reading temperature from DHT
          Failed reading humidity from DHT

          pimatic + MySensors + Homeduino + z-way
          https://github.com/n3roGit/MySensors_n3ro

          1 Reply Last reply
          0
          • BulldogLowellB Offline
            BulldogLowellB Offline
            BulldogLowell
            Contest Winner
            wrote on last edited by
            #48

            check the connections

            n3roN 1 Reply Last reply
            0
            • BulldogLowellB BulldogLowell

              check the connections

              n3roN Offline
              n3roN Offline
              n3ro
              wrote on last edited by
              #49

              @BulldogLowell the wires are OK.

              In sleep the DHT cant warm-up. so the dht need 2 sec before read. when i dont use the delay i cant read it.

              i dont understand why the interrupt didnt work with the enabled delay.

              do you have tested on a arduino?

              pimatic + MySensors + Homeduino + z-way
              https://github.com/n3roGit/MySensors_n3ro

              1 Reply Last reply
              0
              • n3roN Offline
                n3roN Offline
                n3ro
                wrote on last edited by
                #50

                https://github.com/n3roGit/MySensors_n3ro/tree/master/MotionSensor_DHT_light_battery_mod

                now its working. when i use PIN4 for DHT.:)

                pimatic + MySensors + Homeduino + z-way
                https://github.com/n3roGit/MySensors_n3ro

                BulldogLowellB 1 Reply Last reply
                0
                • rvendrameR Offline
                  rvendrameR Offline
                  rvendrame
                  Hero Member
                  wrote on last edited by
                  #51

                  @n3ro, i'm glad you fixed it. DHT was on PIN3 before, right? Pin 2 & Pin3 are connected to the interrupts, maybe this was the problem.

                  Home Assistant / Vera Plus UI7
                  ESP8266 GW + mySensors 2.3.2
                  Alexa / Google Home

                  n3roN 1 Reply Last reply
                  0
                  • rvendrameR rvendrame

                    @n3ro, i'm glad you fixed it. DHT was on PIN3 before, right? Pin 2 & Pin3 are connected to the interrupts, maybe this was the problem.

                    n3roN Offline
                    n3roN Offline
                    n3ro
                    wrote on last edited by
                    #52

                    @rvendrame yes i think so. but now its ok =)

                    pimatic + MySensors + Homeduino + z-way
                    https://github.com/n3roGit/MySensors_n3ro

                    1 Reply Last reply
                    0
                    • n3roN n3ro

                      https://github.com/n3roGit/MySensors_n3ro/tree/master/MotionSensor_DHT_light_battery_mod

                      now its working. when i use PIN4 for DHT.:)

                      BulldogLowellB Offline
                      BulldogLowellB Offline
                      BulldogLowell
                      Contest Winner
                      wrote on last edited by
                      #53

                      @n3ro said:

                      now its working. when i use PIN4 for DHT.:)

                      :clap:

                      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