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. Development
  3. My motion / dallas / light sensor

My motion / dallas / light sensor

Scheduled Pinned Locked Moved Development
3 in 1 example
7 Posts 3 Posters 4.2k Views 6 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.
  • R Offline
    R Offline
    rtenklooster
    wrote on last edited by rtenklooster
    #1

    Hello,
    I was looking for a good working non-battery powered 3 in 1 sketch but couln't find one, that worked the way i wanted it to work. My wishlist:

    • Instant update's on temp and light changes
    • Only send motion stop if motion stopped for at least 10 seconds
    • Only send motion start if motion stopped
    • No delays
    • Make it easy to add other sensors / remove excisting ones *
    • Enable / disable serial debug by define *

    I have made this sketch, hope it can be usefull to someone else. Have tried to document the code as good as possible. I'm planning to add defines in the future to be able to add / remove a temp sensor without altering the whole sketch. So just define light / temp / hum / dhtxx etc, and the sketch will work. The same goes for serial debugging,

    What i used: Dallas DS18b20 , PIR, LDR

    // Include libaries
    #include <SPI.h>
    #include <MySensor.h>  
    #include <DallasTemperature.h>    // For Dallas temp sensor
    #include <OneWire.h>              // For Dallas temp sensor
    
    // Define mysensors data
    #define CHILD_ID_LIGHT 0             // LDR child ID
    #define CHILD_ID_TEMP 1              // Temp child ID
    #define CHILD_ID_MOTION 2            // MOTION child ID
    
    #define LIGHT_SENSOR_ANALOG_PIN A2   // LDR PIN
    #define MOTION_INPUT_SENSOR 2        // Motion input pin
    #define ONE_WIRE_BUS 3               // DALLAS pin
    #define MAX_ATTACHED_DS18B20 16      // DALLAS max nr. of sensors
    
    // Initialize mysensor
    MySensor gw;
    
    // Initialize dallas
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    
    // Store variables
    long previousMillis = 0;        // last time the sensors are updated
    long sensorInterval = 5000;     // interval at which we will take a measurement ( 5 seconds)
    int lastLightLevel;             // Holds last light level
    float lastTemperature[MAX_ATTACHED_DS18B20]; // Holds DALLAS temperatures
    int numSensors=0;               // Holds number of sensors
    boolean metric = true;          // Celcius or fahrenheid
    int calibrationTime = 30;       // the time we give the sensor to calibrate (10-60 secs according to the datasheet)        
    long unsigned int lowIn;        // the time when the sensor outputs a low impulse
    long unsigned int pause = 10000;//the amount of milliseconds the sensor has to be low before we assume all motion has stopped
    boolean lockLow = true;
    boolean takeLowTime;  
    
    // Initialize childs
    MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    MyMessage msgTemp(CHILD_ID_TEMP,V_TEMP);
    MyMessage msgMot(CHILD_ID_MOTION, V_TRIPPED);
    
    void setup() {
      sensors.begin();
      gw.begin();
      // Send sketch info to controller
      gw.sendSketchInfo("Light sensor without delay", "1.0");
      // Register child sensors
      gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
      gw.present(CHILD_ID_MOTION, S_MOTION);
      // Set pinmode for motion sensor
      pinMode(MOTION_INPUT_SENSOR, INPUT);
      // Pull down motion pin
      digitalWrite(MOTION_INPUT_SENSOR, LOW);
      numSensors = sensors.getDeviceCount();
      // Present all sensors to controller
       for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
          gw.present(i, S_TEMP);
       }
      delay(calibrationTime); // Give pir time to calibrate
      
    }
    
    void loop()
    {
      // Check if sensors have changed
      sensorCheck();
      
      if(digitalRead(MOTION_INPUT_SENSOR) == HIGH){
        if(lockLow){  
          //makes sure we wait for a transition to LOW before any further output is made:
          lockLow = false;            
          Serial.print("motion detected at ");
          Serial.print(millis()/1000);
          Serial.println(" sec"); 
          gw.send(msgMot.set("1"));  // Send tripped value to gw
        }         
        takeLowTime = true;
      }
      if(digitalRead(MOTION_INPUT_SENSOR) == LOW){       
         if(takeLowTime){
          lowIn = millis();          //save the time of the transition from high to LOW
          takeLowTime = false;       //make sure this is only done at the start of a LOW phase
          }
         //if the sensor is low for more than the given pause, we assume that no more motion is going to happen
         if(!lockLow && millis() - lowIn > pause){  
             //makes sure this block of code is only executed again after new motion sequence has been detected
             lockLow = true;                        
             Serial.print("motion ended at ");      //output
             Serial.print((millis() - pause)/1000);
             Serial.println(" sec");
             gw.send(msgMot.set("0"));  // Send tripped value to gw
         }
       }
    }
    
    void sensorCheck(){
      unsigned long currentMillis = millis();
      if(currentMillis - previousMillis > sensorInterval) {
        // Save the current millis 
        previousMillis = currentMillis;   
        // take action here:
        
        // Begin light measurement
        int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
        Serial.print("Lightlevel: ");
        Serial.println(analogRead(LIGHT_SENSOR_ANALOG_PIN));
        if (lightLevel != lastLightLevel) {
          gw.send(msgLight.set(lightLevel));
          lastLightLevel = lightLevel;
        }
        // end light measurement
        
        // Begin dallas temperature
        // Fetch temperatures from Dallas sensors
        sensors.requestTemperatures();
         // Read temperatures and send them to controller 
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
          // Fetch and round temperature to one decimal
          float temperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
          Serial.print("Temperature ");
          Serial.print(i);
          Serial.print(" ");
          Serial.println(temperature);
         // Only send data if temperature has changed and no error
         if (lastTemperature[i] != temperature && temperature != -127.00) {
            // Send in the new temperature
            gw.send(msgTemp.setSensor(i).set(temperature,1));
            lastTemperature[i]=temperature;
          }
        } 
        // End dallas temperarures
      }
    }
    
    1 Reply Last reply
    1
    • V Offline
      V Offline
      velkrosmaak
      wrote on last edited by
      #2

      I just gave this a try and it works great! I can't believe nobody else has commented yet.

      The only issue I have is that there doesn't appear to be a Celsius reading, despite the fact that metric is set to true at the top of the code.

      This is what I see over the console:

      Temperature 0 65.30
      Lightlevel: 290
      Temperature 0 65.30
      Lightlevel: 324
      send: 0-0-0-0 s=10,c=1,t=23,pt=2,l=2,sg=0,st=fail:69
      Temperature 0 65.30
      

      I'm guessing the 0 before the 65.30 is where the Celsius reading is supposed to be, but I can't see in the code where the temperature is being calculated.

      Excuse a noob! Thanks for any help! :)

      1 Reply Last reply
      0
      • E Offline
        E Offline
        ericvdb
        wrote on last edited by
        #3

        The 0 before 65.30 is the index number of the temperature sensor.

        And to get Celsius, you should make the controller return true for gw.getConfig().isMetric or change

        float temperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
        

        to

        float temperature = static_cast<float>(static_cast<int>((metric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
        
        1 Reply Last reply
        0
        • V Offline
          V Offline
          velkrosmaak
          wrote on last edited by
          #4

          Perfect! Thank you!

          1 Reply Last reply
          0
          • V Offline
            V Offline
            velkrosmaak
            wrote on last edited by
            #5

            Actually - it gets weirder.

            Does the DS18b20 contain a barometer? Not according to the datasheet. But this node, using the sketch above, seems to create additional sensors, some with garbage data, and some with what appear to be barometric pressure readings. I have some other (BMP180) mysensors which report the same value for pressure as the sketch above.

            I can't understand what's causing the garbage data though. For example, MySensorsDevice#33 has a reading of 1149829168. Some are null, and there are a few other random integers there too. Each with their own MySensorsDevice#.

            Can anyone point me in the right direction as to what's going on? It's getting annoying having to remove all these fake sensors daily! :)

            1 Reply Last reply
            0
            • E Offline
              E Offline
              ericvdb
              wrote on last edited by
              #6

              Are you using a wifi gateway? Others reported strange values too: http://forum.mysensors.org/topic/2934/wifi-gateway-motion-sensor-value-1107296256-instead-of-tripped/2

              1 Reply Last reply
              0
              • V Offline
                V Offline
                velkrosmaak
                wrote on last edited by
                #7
                This post is deleted!
                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                14

                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