Need some help with a Multi-Sensor Node



  • Hi,

    I'm working on making a multi-sensornode (PIR, Light, Temp and V_LIGHT (for night-light)), as well as a repeater node. So far though, I am having problems with the system reporting all the variables every second, instead of on change/every 10 seconds like I have in my sketch. I'm not sure where I am going wrong,. I need the device to only report changes, specifically on motion when it is detected, as well as to receive the V_STATUS message. Would someone please look over this and point me in the right direction? I've been looking at this off and on for a while now and I can't find anything that is majorly wrong.

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Derrick Rockwell (@Drock1985)
     * 
     * DESCRIPTION
     * 
     *
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_NODE_ID 21
    #include <SPI.h>
    #include <MySensors.h>
    #include <DallasTemperature.h>
    #include <OneWire.h>
    #include <BH1750.h>
    #include <Wire.h>
    
    
    unsigned long SLEEP_TIME = 120000;    // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 3        // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define COMPARE_TEMP 1                // Send temperature only if changed? 1 = Yes 0 = No
    #define ONE_WIRE_BUS 4                // Pin where dallase sensor is connected 
    #define LED_ARRAY_1 5                   // Pin that controls the LED Light array (does not need to be a PWM pin)
    #define LED_ARRAY_2 6
    #define MAX_ATTACHED_DS18B20 2
    // #define MY_REPEATER_FEATURE           //Enables Repeater feature for non-battery powered nodes. 
    OneWire oneWire(ONE_WIRE_BUS);        // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature sensors(&oneWire);  // Pass the oneWire reference to Dallas Temperature. 
    int lastTemperature = 0;
    int numSensors=0;
    boolean receivedConfig = false;
    boolean metric = true;
    
    
    #define CHILD_ID_MOTION 1   // ID of the sensor child
    #define CHILD_ID_TEMP 2     // ID of Temperature Sensor
    #define CHILD_ID_LUX 3      // ID of Lux Sensor
    #define CHILD_ID_LIGHT 4    // ID of LED light array
    
    #define LIGHT_ON 1
    #define LIGHT_OFF 0
    
    BH1750 lightSensor;
    
    // Initialize  messages
    MyMessage msgMotion(CHILD_ID_MOTION, V_TRIPPED);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgLux(CHILD_ID_LUX, V_LEVEL); //Sets up custom units (this case LUX for Light)
    MyMessage msgPrefix(CHILD_ID_LUX, V_UNIT_PREFIX); // Sends controller the LUX value instead of %
    MyMessage msgLight(CHILD_ID_LIGHT, V_STATUS);
    
    uint16_t lastlux = 0;
    int compareMotion = LOW;
    bool stateLight = 0; // Place holders for the loop function to register nodes in Home-Assistant
    bool initialValueSentLight = 0;
    
    void setup()  
    {  
      pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
      pinMode(LED_ARRAY_1, OUTPUT);                // sets the LED Array as an output
      pinMode(LED_ARRAY_2, OUTPUT);                // sets the LED Array as an output
      lightSensor.begin();
      // Startup up the OneWire library
      sensors.begin();
      // requestTemperatures() will not block current thread
      sensors.setWaitForConversion(false);
      send(msgPrefix.set("lux"));
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("LuxMotionTempSensor", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_MOTION, S_MOTION);
      wait(150);
      present(CHILD_ID_TEMP, S_TEMP);
      wait(150);
      present(CHILD_ID_LUX, S_LIGHT_LEVEL);
      wait(150);
      present(CHILD_ID_LIGHT, S_LIGHT);
    }
    
    void loop()     
    {     
     
      if (!initialValueSentLight) {
        Serial.println("Sending initial value");
        send(msgLight.set(stateLight?LIGHT_ON:LIGHT_OFF));
        Serial.println("Requesting initial value from controller");
        request(CHILD_ID_LIGHT, V_STATUS);
        wait(2000, C_SET, V_STATUS);
      }
     
     {     
      uint16_t lux = lightSensor.readLightLevel();// Get Lux value
       
      if (lux != lastlux) {
        Serial.println(lux);
        Serial.println("Sending lux value");
          send(msgLux.set(lux));
          send(msgPrefix.set("lux"));
          lastlux = lux;
            }
            
     }
            
    
       // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();
    
    
        // Fetch and round temperature to one decimal
        int temperature = (((sensors.getTempCByIndex(0)) * 10.)) / 10.;
        if (lastTemperature != temperature && temperature != -127.00 && temperature != 85.00) 
        Serial.println(temperature);
        Serial.println("Sending temperature");{
         // Send in the new temperature
          send(msgTemp.set(temperature));
          // Save new temperatures for next compare
          lastTemperature = temperature;
        }
       // Read digital motion value
      boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
    //  if (compareMotion != tripped)  {
      Serial.println("Sending motion status");
      Serial.println(tripped);
      send(msgMotion.set(tripped?"1":"0"));  // Send tripped value to gw   
    //  compareMotion = tripped;
    //  }
    
    // sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    
    }
    
    void receive(const MyMessage &message) {
      if (message.isAck()) {
         Serial.println("This is an ack from gateway");
      }
    
      if (message.type == V_STATUS && message.sensor == CHILD_ID_LIGHT) {
        if (!initialValueSentLight) {
          Serial.println("Receiving initial value from controller");
          initialValueSentLight = true;
        }
        // Change relay state
        stateLight = (bool)message.getInt();
        digitalWrite(LED_ARRAY_1, stateLight?LIGHT_ON:LIGHT_OFF);
        digitalWrite(LED_ARRAY_2, stateLight?LIGHT_ON:LIGHT_OFF);
        send(msgLight.set(stateLight?LIGHT_ON:LIGHT_OFF));
      }
    }
    

    Thanks,


  • Mod

    @drock1985 the comparison for the tripped check is commented out, so it will send values every time. Uncomment it 🙂

    If that doesn't help, please post the debug output of the node.


Log in to reply
 

Suggested Topics

20
Online

11.2k
Users

11.1k
Topics

112.5k
Posts