Molgan and Emengency Light



  • I started play with an ikea molgan to make a a motion sensor for domoticz I want also have the possibility to use the onboard led as emergency light in case of black out so i've started with the standard motion sensor sketch trying to add the funcionality but i encountred some problems.

    Basically what i want is

    Normal state (motion sensor)
    Emergency light triggered on and off by pir (if at first motion triggering if cannot contact the gateway or if in domoticz a switch status is on )

    for the hardware i've connected che gate control to a digital i/o of arduino, but for the software i sill have problem.

    Sometimes the status is not correctly recived from controller in an acceptable time and i didn't have at the moment an efficient method to know if the gateway is alive.
    any suggest ?

    here the sketch used

    *
     * 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 - Henrik Ekblad
     *
     * DESCRIPTION
     * Motion Sensor example using HC-SR501
     * http://www.mysensors.org/build/motion
     *
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_SIGNING_SOFT //Enable software Signing
    //#define MY_SIGNING_REQUEST_SIGNATURES //Enable signature on gateway
    //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 //Randomize pin leave unconnected
    
    #include <MySensors.h>
    
    
    #define SENSOR_SLEEP_TIME_MS (24UL*60UL*60UL*1000UL) // 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 1   // Id of motion sensor child
    
    #define DIGITAL_OUTPUT_LED 4 //Digital Output driving led mosfet
    #define LED_CHILD_ID 2 // Id of motion sensor child
    
    // define values for the battery measurement
    #define R1  1e6
    #define R2  470e3
    #define VMIN  3.5
    #define VMAX  4.5
    #define ADC_PRECISION  1024
    #define VREF 3.306
    
    
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point   
    int oldBatteryPcnt = 0;
    bool ledstatus = 0;
    bool response =0;
    bool tripped =0;
    
    
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    MyMessage led(LED_CHILD_ID,V_TEXT);
    
    
    
    void setup()
    {
        // use the 3.3 V  reference
    
        analogReference(DEFAULT);
       
     
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
        pinMode(DIGITAL_OUTPUT_LED, OUTPUT);
        
        digitalWrite(DIGITAL_OUTPUT_LED, 0);
        send(led.set(0));
     
    
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Motion Sensor and EMO Light", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION, "Motion Molgan ",true);
        wait(500);
        present(LED_CHILD_ID, S_INFO, "LED Molgan ",true);
        
        
    }
    
    void loop()
    {
        // Read digital motion value
        tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
        
        Serial.print("Motion State:");
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
       
        request(LED_CHILD_ID, V_TEXT);
        response=wait(5000, 2, V_TEXT);
        Serial.print("Controller Response:");
        Serial.println(response);
    
        int batteryPcnt=getBatteryPercentage();
    
            if (oldBatteryPcnt != batteryPcnt) {
            // Power up radio after sleep
            sendBatteryLevel(batteryPcnt);
            oldBatteryPcnt = batteryPcnt;
        }
    
        
         
        // Sleep until interrupt comes in on motion sensor if gateway is responsive othervise prevent to sleep adn turn on led
        //if (response==1)
        //{
        Serial.print("Going to sleep");
        sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SENSOR_SLEEP_TIME_MS);
        //return;
        //}
        //else  
        //        {
        //          if (response==0){
        //          digitalWrite(DIGITAL_OUTPUT_LED, 1);
        //          }
        //      return;
        //      }    
    }
    
    
    void receive(const MyMessage &message)
    {
        
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_TEXT) {
            // Change led state
            ledstatus=message.getBool();
            //tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
            if (ledstatus==1){
            digitalWrite(DIGITAL_OUTPUT_LED, tripped);
            }
            else {
              
                    if(ledstatus==0)
                      {
                          digitalWrite(DIGITAL_OUTPUT_LED, 0);
                      }
                  }
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(ledstatus);
        }
    
    
    
    }
    
    int getBatteryPercentage() {
    
      // read analog pin value
      int inputValue = analogRead(BATTERY_SENSE_PIN);
      
      // calculate the max possible value and therefore the range and steps
      float voltageDividerFactor = 3.225622776;
      float maxValue = voltageDividerFactor * VREF;
      float voltsPerBit = maxValue / ADC_PRECISION;
      
      int batteryVoltage = (voltsPerBit * inputValue)*1000;
      
      Serial.print("Battery Voltage:");
      Serial.println(batteryVoltage);
      
      //int batteryPercentage = ((batteryVoltage-VMIN)/(VMAX-VMIN))*100;
      int batteryPercentage = min(map(batteryVoltage, 3500, 4500, 0, 100),100);
    
      Serial.print("Battery Percentage:");
      Serial.println(batteryPercentage);
    
      return batteryPercentage;
    }
    

  • Hero Member

    @markcame I'm doing a similar thing with @Yveaux 's Molgan-Hack board. Interesting to see that you are using the wait() function in the extended version response=wait(5000, 2, V_TEXT); I never noticed that it existed 😊
    A few remarks:

    • Domoticz can handle requests for (light)V_STATUS which fits the purpose better (and is more efficient)
    • Using the extend version of wait the second parameter cmd should be the MySensors command type set (value = = 1) as the node will be receiving a set from the controller. You better use the constant name C_SET
      although not mentioned in the API (yet). In MyMessage.h :
    /// @brief The command field (message-type) defines the overall properties of a message
    typedef enum {
    	C_PRESENTATION			= 0,	//!< Sent by a node when they present attached sensors. This is usually done in presentation() at startup.
    	C_SET					= 1,	//!< This message is sent from or to a sensor when a sensor value should be updated.
    	C_REQ					= 2,	//!< Requests a variable value (usually from an actuator destined for controller).
    	C_INTERNAL				= 3,	//!< Internal MySensors messages (also include common messages provided/generated by the library).
    	C_STREAM				= 4		//!< For firmware and other larger chunks of data that need to be divided into pieces.
    } mysensor_command;
    


  • Ok i will try with the modification suggested.
    I have at the moment some comunication problems with th radio so i've rewired my ESP8266 gateway and adding some capacitors.
    what type use S-BINARY , i have had some problems retriving the status from domoticz , i don't know if it is related to the lastest beta...



  • I've tryed everything but seems that the request does not return a value, seems that domoticz does not expose the value but only send status update at the moment of the switch, request on V_VAR1... ecc. ec... instead always works but they are not exposed to the user...


  • Hero Member

    @markcame can you please post your sketch showing the request?



  • @AWI
    Sketch

    /**
     * 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 - Henrik Ekblad
     *
     * DESCRIPTION
     * Motion Sensor example using HC-SR501
     * http://www.mysensors.org/build/motion
     *
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_SIGNING_SOFT //Enable software Signing
    //#define MY_SIGNING_REQUEST_SIGNATURES //Enable signature on gateway
    //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 //Randomize pin leave unconnected
    
    #include <MySensors.h>
    
    
    #define SENSOR_SLEEP_TIME_MS (24UL*60UL*60UL*1000UL) // 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 1   // Id of motion sensor child
    
    #define DIGITAL_OUTPUT_LED 4 //Digital Output driving led mosfet
    #define LED_CHILD_ID 2 // Id of motion sensor child
    #define VOLTAGE_CHILD_ID 3
    
    // define values for the battery measurement
    #define R1  1e6
    #define R2  470e3
    #define VMIN  3.5
    #define VMAX  4.5
    #define ADC_PRECISION  1024
    #define VREF 3.3
    
    
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point   
    int oldBatteryPcnt = 200;
    bool ledstatus = 0;
    bool response =0;
    bool tripped =0;
    float batteryvoltreport=0;
    
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    MyMessage led(LED_CHILD_ID,V_STATUS);
    MyMessage voltageMsg(VOLTAGE_CHILD_ID, V_VOLTAGE);
    
    
    
    void setup()
    {
        // use the 3.3 V  reference
    
        analogReference(DEFAULT);
       
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
        pinMode(DIGITAL_OUTPUT_LED, OUTPUT);
        digitalWrite(DIGITAL_OUTPUT_LED, 0);
        send(led.set(0));
     
    
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Motion Sensor and EMO Light", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION, "Motion Molgan ",true);
        wait(500);
        present(LED_CHILD_ID, S_BINARY, "LED Molgan ",true);
        wait(500);
        present(VOLTAGE_CHILD_ID, S_MULTIMETER, "Battery level" );
        
    }
    
    void loop()
    {
        // Read digital motion value
        tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
        
        Serial.print("Motion State:");
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
       
        request(LED_CHILD_ID, V_STATUS);
        response=wait(5000, C_SET, V_STATUS);
        Serial.print("Controller Response:");
        Serial.println(response);
    
        int batteryPcnt=getBatteryPercentage();
    
            if (batteryPcnt < oldBatteryPcnt  ) {
            // Power up radio after sleep
            sendBatteryLevel(batteryPcnt);
            oldBatteryPcnt = batteryPcnt;
            send(voltageMsg.set(batteryvoltreport,2)); //send battery in Volt 2 decimal places
        }
    
        
         
        // Sleep until interrupt comes in on motion sensor if gateway is responsive othervise prevent to sleep adn turn on led
        //if (response==1)
        //{
        //Serial.print("Going to sleep");
        sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SENSOR_SLEEP_TIME_MS);
        //return;
        //}
        //else  
        //        {
        //          if (response==0){
        //          digitalWrite(DIGITAL_OUTPUT_LED, 1);
        //          }
        //      return;
        //      }    
    }
    
    
    void receive(const MyMessage &message)
    {
        
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_STATUS) {
            // Change led state
            ledstatus=message.getBool();
            //tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
            if (ledstatus==1){
            digitalWrite(DIGITAL_OUTPUT_LED, tripped);
            }
            else {
              
                    if(ledstatus==0)
                      {
                          digitalWrite(DIGITAL_OUTPUT_LED, 0);
                      }
                  }
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(ledstatus);
        }
    
    
    
    }
    
    int getBatteryPercentage() {
    
      // read analog pin value
      int inputValue = analogRead(BATTERY_SENSE_PIN);
      
      // calculate the max possible value and therefore the range and steps
      float voltageDividerFactor = 3.225622776;
      float maxValue = voltageDividerFactor * VREF;
      float voltsPerBit = maxValue / ADC_PRECISION;
      
      int batteryVoltage = (voltsPerBit * inputValue)*1000;
      batteryvoltreport=(voltsPerBit * inputValue);
      
      //Serial.print("Battery Voltage:");
      //Serial.println(batteryVoltage);
      
      //int batteryPercentage = ((batteryVoltage-VMIN)/(VMAX-VMIN))*100;
      int batteryPercentage = min(map(batteryVoltage, 3500, 4500, 0, 100),100);
    
      //Serial.print("Battery Percentage:");
      //Serial.println(batteryPercentage);
    
      return batteryPercentage;
    }
    

    Serial Debug

    4242 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100
    4371 TSF:MSG:READ,0-0-6,s=255,c=3,t=15,pt=6,l=2,sg=0:0100
    4378 TSF:MSG:SEND,6-6-0-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=OK:2.1.1
    4386 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:0
    5599 TSF:MSG:READ,0-0-6,s=255,c=3,t=6,pt=0,l=1,sg=0:M
    5609 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=11,pt=0,l=25,sg=0,ft=0,st=OK:Motion Sensor and EMO Lig
    5619 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=OK:1.0
    5628 TSF:MSG:SEND,6-6-0-0,s=1,c=0,t=1,pt=0,l=14,sg=0,ft=0,st=OK:Motion Molgan 
    5946 TSF:MSG:READ,0-0-6,s=1,c=0,t=1,pt=0,l=14,sg=0:Motion Molgan 
    5951 TSF:MSG:ACK
    6140 TSF:MSG:SEND,6-6-0-0,s=2,c=0,t=3,pt=0,l=11,sg=0,ft=0,st=OK:LED Molgan 
    6246 TSF:MSG:READ,0-0-6,s=2,c=0,t=3,pt=0,l=11,sg=0:LED Molgan 
    6252 TSF:MSG:ACK
    6652 TSF:MSG:SEND,6-6-0-0,s=3,c=0,t=30,pt=0,l=13,sg=0,ft=0,st=OK:Battery level
    6660 MCO:REG:REQ
    6666 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2
    6804 TSF:MSG:READ,0-0-6,s=255,c=3,t=27,pt=1,l=1,sg=0:1
    6808 MCO:PIM:NODE REG=1
    6811 MCO:BGN:STP
    6814 TSF:MSG:SEND,6-6-0-0,s=2,c=1,t=2,pt=2,l=2,sg=0,ft=0,st=OK:0
    6820 MCO:BGN:INIT OK,TSP=1
    Motion State:0
    6824 TSF:MSG:SEND,6-6-0-0,s=1,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=OK:0
    6865 !TSF:MSG:SEND,6-6-0-0,s=2,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=NACK:
    Controller Response:0
    11874 TSF:MSG:SEND,6-6-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=1,st=OK:100
    11891 TSF:MSG:SEND,6-6-0-0,s=3,c=1,t=38,pt=7,l=5,sg=0,ft=0,st=OK:4.88
    11897 MCO:SLP:MS=86400000,SMS=0,I1=1,M1=1,I2=255,M2=255
    11902 MCO:SLP:TPD
    11905 MCO:SLP:WUP=1
    Motion State:1
    11909 TSF:MSG:SEND,6-6-0-0,s=1,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=OK:1
    11916 TSF:MSG:SEND,6-6-0-0,s=2,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=OK:
    Controller Response:0
    16922 MCO:SLP:MS=86400000,SMS=0,I1=1,M1=1,I2=255,M2=255
    16928 MCO:SLP:TPD
    16930 MCO:SLP:WUP=1
    Motion State:0
    16936 TSF:MSG:SEND,6-6-0-0,s=1,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=OK:0
    16944 TSF:MSG:SEND,6-6-0-0,s=2,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=OK:
    Controller Response:0
    21950 MCO:SLP:MS=86400000,SMS=0,I1=1,M1=1,I2=255,M2=255
    21956 MCO:SLP:TPD```
    
    
    

    Gateway

    0;255;3;0;14;Gateway startup complete.
    0;255;0;0;18;2.1.1
    0;255;3;0;2;2.1.1
    0;255;3;0;22;188673920
    0;255;3;0;22;188683854
    6;255;0;0;17;2.1.1
    6;255;3;0;6;0
    6;255;3;0;11;Motion Sensor and EMO Lig
    6;255;3;0;12;1.0
    6;1;0;0;1;Motion Molgan 
    6;2;0;0;3;LED Molgan 
    6;3;0;0;30;Battery level
    6;2;1;0;2;0
    6;1;1;0;16;0
    6;2;2;0;2;
    0;255;3;0;22;188693888
    6;255;3;0;0;100
    6;3;1;0;38;4.88
    0;255;3;0;22;188703923
    6;1;1;0;16;1
    6;2;2;0;2;
    6;1;1;0;16;0
    6;2;2;0;2;
    

  • Hero Member

    @markcame apart from that there is some variable type mixing (bool, int, ) the sketch looks fine. Domoticz returns values for: V_STATUS, V_PERCENTAGE, V_RGB(W), V_VARx and V_TEXT (see code snippet below (github))
    You can try to have the sensor re-create in Domoticz with a fixed node Id. Experimenting could have caused Domoticz to mess up the database.

     if (message_type == MT_Req)
    	{
    		//Request a variable
    		std::string tmpstr;
    		switch (sub_type)
    		{
    		case V_STATUS:
    		case V_PERCENTAGE:
    		case V_RGB:
    		case V_RGBW:
    			if (GetSwitchValue(node_id, child_sensor_id, sub_type, tmpstr))
    				SendNodeCommand(node_id, child_sensor_id, message_type, sub_type, tmpstr);
    			break;
    		case V_VAR1:
    		case V_VAR2:
    		case V_VAR3:
    		case V_VAR4:
    		case V_VAR5:
    			//send back a previous stored custom variable
    			tmpstr = "";
    			GetVar(node_id, child_sensor_id, sub_type, tmpstr);
    			//SendNodeSetCommand(node_id, child_sensor_id, message_type, (_eSetType)sub_type, tmpstr, true, 1000);
    			SendNodeCommand(node_id, child_sensor_id, message_type, sub_type, tmpstr);
    			break;
    		case V_TEXT:
    			{
    				//Get Text sensor value from the database
    				bool bExits = false;
    				tmpstr = GetTextSensorText(node_id, child_sensor_id, bExits);
    				SendNodeCommand(node_id, child_sensor_id, message_type, sub_type, tmpstr);
    			}
    			break;
    		default:
    			while (1==0);
    			break;
    		}
    		while (1==0);
    	}
    


  • Ok, how can assign a fixed id ?


  • Hero Member

    @markcame #define MY_NODE_ID xxx in the start of your sketch


Log in to reply
 

Suggested Topics

  • 8
  • 3
  • 2
  • 1
  • 1
  • 44

0
Online

11.2k
Users

11.1k
Topics

112.5k
Posts