My Multisensor Project



  • Introduction

    Hello everybody,

    my friend and I started to use MySensors about a year ago. We both use openHAB as a controller and were looking for a cheap and fun way to integrate new sensors to our homeautomation system. We first started to build a MQTT-Gateway and a motion sensor by using the documentation on the MySensors homepage. Having confirmed that everything worked like a charm (after some trouble like in every new project 😃) we wanted to build a multisensor that integrates a light, a motion, a temperature and a humidity sensor. Also we wanted to use parts that are easily acessible off the shelf thereby allowing new users to recreate this sensor.

    We are by no means experts in this field so there are probably better ways to create a multisensor, but this one works for us and we learned a lot by putting it together. We hope that this description of our project helps new users get into MySensors.


    Multisensor:

    So here is what you need:

    Bill of Materials:

    • Arduino nano
    • Radio Module: NRF24L01+
    • Temp & hum sensor: Si7021
    • Light sensor: BH1750
    • Motion sensor: HC-SR501
    • Cables
    • (optional: Decoupling-Capacitor -> see MySensors Website)

    To connect the cables you can either use a soldering iron or clamps.

    The Wiring

    As a Picture:
    0_1569416218470_MultiSensor_Steckplatine.png

    In a table:

    Arduino NRF24L01+ Si7021 BH1750 HC-SR501
    GND GND GND GND, ADDR GND
    3.3V VCC
    5V VIN VCC VCC
    D2 IRQ
    D3 OUT
    D9 CE
    D10 CSN/CS
    D11 MOSI
    D12 MISO
    D13 SCK
    A4 SDA SDA
    A5 SCL SCL

    The Code

    Note that you have to set the Node ID manually when using a MQTT-Gateway.

    /*
     * 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-2018 Sensnology AB
     * Full contributor list: https://github.com/mysensors/MySensors/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.
     *
     *******************************
     *
     *
     * DESCRIPTION
     *
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    //#define MY_RADIO_NRF5_ESB
    //#define MY_RADIO_RFM69
    //#define MY_RADIO_RFM95
    
    #define MY_NODE_ID 2
    
    #include <MySensors.h>
    #include <BH1750.h>
    #include <SI7021.h>
    static SI7021 sensor;
    BH1750 lightSensor; //TODO: maybe make static as well
    
    // Light
    #define CHILD_ID_LIGHT 0
    //unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
    
    // Motion
    uint32_t 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 CHILD_ID_MOT 1   // Id of the sensor child
    
    // Humidity & Temperature
    #define CHILD_ID_HUM  2
    #define CHILD_ID_TEMP 3
    static bool metric = true;
    
    // Sleep time between sensor updates (in milliseconds)
    static const uint64_t UPDATE_INTERVAL = 60000;
    
    // V_LIGHT_LEVEL should only be used for uncalibrated light level 0-100%.
    // If your controller supports the new V_LEVEL variable, use this instead for
    // transmitting LUX light level.
    // MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    MyMessage msgLight(CHILD_ID_LIGHT, V_LEVEL);  
    uint16_t lastlux;
    
    // Initialize motion message
    MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED);
    
    void setup()
    {
      lightSensor.begin();
      
      //sensor.begin();
      while (not sensor.begin())
      {
        Serial.println(F("Temp/Hum Sensor not detected!"));
        delay(5000);
      }
    	pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
    	sendSketchInfo("Multi Sensor", "1.0");
    
    	// Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_LIGHT, S_LIGHT_LEVEL, "Light");
    	present(CHILD_ID_MOT, S_MOTION, "Motion");
      present(CHILD_ID_HUM, S_HUM,   "Humidity");
      present(CHILD_ID_TEMP, S_TEMP, "Temperature");
    
      metric = getControllerConfig().isMetric;
    }
    
    void loop()
    {
    	// Read digital motion value
    	bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
    
    	Serial.println(tripped);
    	send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw
    
      uint16_t lux = lightSensor.readLightLevel();// Get Lux value
      if (lux != lastlux) {
          send(msgLight.set(lux));
          lastlux = lux;
      }
    
      // Read temperature & humidity from sensor.
      const float temperature = float( metric ? sensor.getCelsiusHundredths() : sensor.getFahrenheitHundredths() ) / 100.0;
      const float humidity    = float( sensor.getHumidityBasisPoints() ) / 100.0;
    
    #ifdef MY_DEBUG
      Serial.print(F("Light "));
      Serial.print(lux);
      Serial.print(F(" lux"));
      Serial.print(F("\tTemp "));
      Serial.print(temperature);
      Serial.print(metric ? " °C" : " °F");
      Serial.print(F("\tHum "));
      Serial.print(humidity);
      Serial.println(F(" %"));
    #endif
    
      static MyMessage msgHum(CHILD_ID_HUM,  V_HUM); //TODO: Maybe put outside loop 
      static MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); //TODO: Maybe put outside loop 
    
      send(msgTemp.set(temperature, 2));
      send(msgHum.set(humidity, 2));
    
      // Sleep until next update to save energy
      //sleep(UPDATE_INTERVAL); 
    
      // Sleep until interrupt comes in on motion sensor. Send update every two minute.
      sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    }
    

    Common Problems

    We have multiple sensors with the above described setup running perfectly so it should work for everybdody else too.
    When building the sensor make sure to doublecheck the connections of your cables (correct pin and conductive connection) since this is the most common source for "its not working 😉 " errors.


 

Suggested Topics

176
Online

8.8k
Users

9.6k
Topics

100.3k
Posts