Humidity, temperature, motion and bunch of relays...



  • Hi everybody,
    I'm trying to have a sketch for my leaving room which should have 8 relays, humidity, temperature and motion sensors.
    I was able to merge few sketches to one and it works fine with 4 relays but i have problem with second "array" or sensors
    this is my working sketch

    #include <MySensor.h>
    #include <SPI.h>
    #include <Wire.h>
    #include <DHT.h>
    #include <SimpleTimer.h>
    #define CHILD_ID_HUM 20
    #define CHILD_ID_TEMP 21
    #define CHILD_ID_MOTION 22
    
    #define RELAY_1  14  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 4 // Total number of attached relays
    #define RELAY_ON 0  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 1 // GPIO value to write to turn off attached relay
    #define HUMIDITY_SENSOR_DIGITAL_PIN 19
    #define MOTION_SENSOR_DIGITAL_PIN 3
    #define INTERRUPT MOTION_SENSOR_DIGITAL_PIN-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    unsigned long SLEEP_TIME = 600000; // Sleep time between reads (in milliseconds) - 10mins
    
    MySensor gw;
    DHT dht;
    SimpleTimer timer;
    
    float lastTemp;
    float lastHum;
    boolean lastTripped;
    boolean metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msg(CHILD_ID_MOTION, V_TRIPPED);
    
    
    void setup()  
    {   
      // Initialize library and add callback for incoming messages
      gw.begin(incomingMessage, AUTO, true);
      
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("HumTempRelayMotion", "1.4");
       // Register all sensors to gw 
        gw.present(CHILD_ID_HUM, S_HUM);
        gw.present(CHILD_ID_TEMP, S_TEMP);
        gw.present(CHILD_ID_MOTION, S_MOTION);
      // Fetch relay status
       for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) {
        // Register all sensors to gw (they will be created as child devices)
        gw.present(sensor, S_LIGHT);
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);   
        // Set relay to last known state (using eeprom storage) 
        digitalWrite(pin, gw.loadState(sensor)?RELAY_ON:RELAY_OFF);
    
    }
      //Serial.begin(9600);
      timer.setInterval(30000, getMeasure);
      metric = gw.getConfig().isMetric;
    
    }
    
    void loop() 
    {
      // Alway process incoming messages whenever possible
      gw.process();
      timer.run();
    
      boolean tripped = digitalRead(MOTION_SENSOR_DIGITAL_PIN) == HIGH;    
      if (tripped != lastTripped) {
        lastTripped = tripped;
        Serial.print("M: ");
        Serial.println(tripped);
        gw.send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
       }
    }
    
    void incomingMessage(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_LIGHT) {
         // Change relay state
         digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
         // Store state in eeprom
         gw.saveState(message.sensor, message.getBool());
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    void getMeasure() {
      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("T: ");
        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("H: ");
          Serial.println(humidity);
            }
    }
    
    


  • @Tomasz-Pazio

    What is not working? The sensors (DHT & PIR) or the relays?

    You have a function "void getMeasure' but you don't specifically call for it in your main loop.

    What is the timer for?



  • Sorry I was to fast. I have problem with second "array" or sensors, first is working on pins 14-17 so analog. Second part should work on pins 5-8 but I have no idea how to make this. All works fine now but on 4 relays, I need to add 4 more.



  • @Tomasz-Pazio I read too fast as well, did not see 'timer.setInterval(30000, getMeasure);

    You could use an Array to link the relay pins to Relay 1-8.



  • @Dwalt think that I undersand the idea but no idea how to write this in code, google gives a lot of examples but hard for me to code this :(


  • Contest Winner

    @Tomasz-Pazio

    an approach with the relays would be like this bit of (untested) code:

    
    #include <MySigningNone.h>
    #include <MyTransportNRF24.h>
    #include <MyTransportRFM69.h>
    #include <MyHwATMega328.h>
    #include <MySensor.h>
    #include <SPI.h>
    
    #define NUMBER_OF_RELAYS 8
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    const int relayPin[NUMBER_OF_RELAYS] = {5,6,7,8,14,15,16,17};  //<<<<<<<pin numbers
    
    MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW);  
    
    MyHwATMega328 hw;
    
    MySensor gw(radio, hw);
    
    void setup()  
    {   
      gw.begin(incomingMessage, AUTO, true);
      gw.sendSketchInfo("multiRelay", "1.0");
      for (int i = 0; i < NUMBER_OF_RELAYS; i++) 
      {
        gw.present(i, S_LIGHT);
        pinMode(relayPin[i], OUTPUT);   
        digitalWrite(relayPin[i], LOW);
      }
    }
    
    void loop() 
    {
      gw.process();
    }
    
    void incomingMessage(const MyMessage &message) 
    {
      if (message.type == V_LIGHT) 
      {
         digitalWrite(relayPin[message.sensor], message.getBool()? RELAY_ON : RELAY_OFF);
       } 
    }
    


  • @BulldogLowell works fine with this :) thanks for support.



  • Hey !

    I'm trying to use your code to do a Motion/temp/humidity sensor, but I dont know why the motion sensor is sending 0/1/0/1... if there is nothing moving ?!

    Here is my code :

    #include <SPI.h>
    #include <MySensor.h>  
    #include <DHT.h>  
    #include <SimpleTimer.h>
    
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_MOT 2
    #define MOTION_SENSOR_DIGITAL_PIN 3
    #define HUMIDITY_SENSOR_DIGITAL_PIN 4
    //#define INTERRUPT MOTION_SENSOR_DIGITAL_PIN-2
    
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
    
    MySensor gw;
    DHT dht;
    SimpleTimer timer;
    float lastTemp;
    float lastHum;
    boolean lastTripped;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED);
    
    
    void setup()  
    { 
      gw.begin();
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
    
      // Send the Sketch Version Information to the Gateway
      gw.sendSketchInfo("Humidity/Motion", "1.0");
    
      pinMode(MOTION_SENSOR_DIGITAL_PIN, INPUT);
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID_HUM, S_HUM);
      gw.present(CHILD_ID_TEMP, S_TEMP);
      gw.present(CHILD_ID_MOT, S_MOTION);
    
      timer.setInterval(30000, getMeasure);
    }
    
    void loop()      
    {  
      timer.run();
    
      boolean tripped = digitalRead(MOTION_SENSOR_DIGITAL_PIN) == HIGH;    
      if (tripped != lastTripped) 
      {
        lastTripped = tripped;
        Serial.print("M: ");
        Serial.println(tripped);
        gw.send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw
       }
    }
    
    void getMeasure() 
    {
      delay(dht.getMinimumSamplingPeriod());
    
      float temperature = dht.getTemperature();
      if (isnan(temperature)) 
      {
          Serial.println("Failed reading temperature from DHT");
      } 
      else if (temperature != lastTemp) 
      {
        lastTemp = temperature;
        gw.send(msgTemp.set(temperature, 1));
        Serial.print("T: ");
        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("H: ");
          Serial.println(humidity);
       }
    }
    
    
    

    Do you have any idea what could be causing that ?

    Regards !


  • Hero Member

    @petoulachi it looks like your input pin for the sensor is floating. You can enable the internal pull-up to check ( INPUT_PULLUP i.s.o. INPUT)



  • I'm sorry I'm a newbie with arduino so I don't understand what you want me to test ?



  • If you were meaning that I have to do

    pinMode(MOTION_SENSOR_DIGITAL_PIN, INPUT_PULLUP);
    

    instead of

    pinMode(MOTION_SENSOR_DIGITAL_PIN, INPUT);
    

    It changes nothing !



  • I found where was the problem, I'm really a newbee... The motion sensor was plugged to the 3.3VCC, not 5V, doing this strange behaviour !


Log in to reply
 

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