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. My Project
  3. Combined Sensor RepeaterNode and sleep(SLEEP_TIME) in MySensors 2.0.0

Combined Sensor RepeaterNode and sleep(SLEEP_TIME) in MySensors 2.0.0

Scheduled Pinned Locked Moved My Project
10 Posts 2 Posters 3.0k Views 2 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.
  • sinczeS Offline
    sinczeS Offline
    sincze
    MySensors Evangelist
    wrote on last edited by
    #1

    Just a question. To cover the distance of my sensors to the Gateway I need a repeater!
    Maybe even 2....

    As I always want things to be 'helpfull' I currently have a lightmeter and repeater running on 1 Arduino fine (1.5.4).

    I am currently migrating all sketches to 2.0.0.
    As I've read that things should be backwards compatible ,,,, advised is to move everything to 2.0.0
    So that means rewrtiting all my sketches. A well keeps you off the street for some time.

    I've studied the MySensors 2.0.0 sketches examples of repeater and lightmeter.
    However is it safe to use sleep(SLEEP_TIME) from the lightmeter sketch if the same device has to be a repeater?

    In 1.5.4 sleep was not advised I believe.. To avoid package loss.

    At the moment to avoid the sleep routine I use a counter .....

     if (sleepTimer == SLEEP_TIME) {
        read light from lightmeter;
        sleepTimer = 0;
       }
     else sleepTimer++;
    [/code] 
    

    Seems to do the trick.
    I am not operating the sensors on batteries but I believe there is always room for improvement.

    Please advise :smile:

    TheoLT 2 Replies Last reply
    0
    • sinczeS sincze

      Just a question. To cover the distance of my sensors to the Gateway I need a repeater!
      Maybe even 2....

      As I always want things to be 'helpfull' I currently have a lightmeter and repeater running on 1 Arduino fine (1.5.4).

      I am currently migrating all sketches to 2.0.0.
      As I've read that things should be backwards compatible ,,,, advised is to move everything to 2.0.0
      So that means rewrtiting all my sketches. A well keeps you off the street for some time.

      I've studied the MySensors 2.0.0 sketches examples of repeater and lightmeter.
      However is it safe to use sleep(SLEEP_TIME) from the lightmeter sketch if the same device has to be a repeater?

      In 1.5.4 sleep was not advised I believe.. To avoid package loss.

      At the moment to avoid the sleep routine I use a counter .....

       if (sleepTimer == SLEEP_TIME) {
          read light from lightmeter;
          sleepTimer = 0;
         }
       else sleepTimer++;
      [/code] 
      

      Seems to do the trick.
      I am not operating the sensors on batteries but I believe there is always room for improvement.

      Please advise :smile:

      TheoLT Offline
      TheoLT Offline
      TheoL
      Contest Winner
      wrote on last edited by
      #2

      @sincze Since sleep will put your Arduino to sleep, it will not be able to receive messages. So you shouldn't use sleep on a repeater node. You should use wait instead.

      1 Reply Last reply
      2
      • sinczeS sincze

        Just a question. To cover the distance of my sensors to the Gateway I need a repeater!
        Maybe even 2....

        As I always want things to be 'helpfull' I currently have a lightmeter and repeater running on 1 Arduino fine (1.5.4).

        I am currently migrating all sketches to 2.0.0.
        As I've read that things should be backwards compatible ,,,, advised is to move everything to 2.0.0
        So that means rewrtiting all my sketches. A well keeps you off the street for some time.

        I've studied the MySensors 2.0.0 sketches examples of repeater and lightmeter.
        However is it safe to use sleep(SLEEP_TIME) from the lightmeter sketch if the same device has to be a repeater?

        In 1.5.4 sleep was not advised I believe.. To avoid package loss.

        At the moment to avoid the sleep routine I use a counter .....

         if (sleepTimer == SLEEP_TIME) {
            read light from lightmeter;
            sleepTimer = 0;
           }
         else sleepTimer++;
        [/code] 
        

        Seems to do the trick.
        I am not operating the sensors on batteries but I believe there is always room for improvement.

        Please advise :smile:

        TheoLT Offline
        TheoLT Offline
        TheoL
        Contest Winner
        wrote on last edited by
        #3

        @sincze If you post your sketch, I can give you more advice. It'll save you the walk across the street next monday ;-)

        sinczeS 1 Reply Last reply
        0
        • TheoLT TheoL

          @sincze If you post your sketch, I can give you more advice. It'll save you the walk across the street next monday ;-)

          sinczeS Offline
          sinczeS Offline
          sincze
          MySensors Evangelist
          wrote on last edited by
          #4

          tnx @TheoL

          Don't posted my repeater sketch on github yet (for my own reference and backup).

          However the sketch that resembles my repeaternode is stored here:
          https://github.com/sincze/mysensors-2..0.x-temperature-humidity/commit/5824defa434c750bf706351562c3ee0dfc8ab4ea

          I want to capture the door being opened however... don't want to have the temperature readings measured every second or so ;-)

          I think repeater mode is only one extra line in the code ;-0

          // Enabled repeater feature for this node
          #define MY_REPEATER_FEATURE
          

          Your help is appreciated ;-)

          TheoLT 2 Replies Last reply
          0
          • sinczeS sincze

            tnx @TheoL

            Don't posted my repeater sketch on github yet (for my own reference and backup).

            However the sketch that resembles my repeaternode is stored here:
            https://github.com/sincze/mysensors-2..0.x-temperature-humidity/commit/5824defa434c750bf706351562c3ee0dfc8ab4ea

            I want to capture the door being opened however... don't want to have the temperature readings measured every second or so ;-)

            I think repeater mode is only one extra line in the code ;-0

            // Enabled repeater feature for this node
            #define MY_REPEATER_FEATURE
            

            Your help is appreciated ;-)

            TheoLT Offline
            TheoLT Offline
            TheoL
            Contest Winner
            wrote on last edited by
            #5

            @sincze I've created a library for this purpose. It's not completely tested, so there might be some bugs in it. It's a sort of buy me a beer if you like it library ;-). And yeah I know implementation code should be put in .cpp. Will do that when I'm done testing.

            /**
             * Library ThresholdUtil.h 
             * 
             * Copyright (c) ByTheo
             * 
             * Description:
             *   This library handles all interval based reading of simpels who's values you want to send on a periodical basis. This means that at least every given interval number of readings
             *   the callback handler for that sensor is being called. If howver the value of the sensors goes past the defined threshold value of that sensor, it will call the callbackhandler
             *   the soon as it detects the threshold. This library was based upon the Sensbender Micro example Sketch.
             * 
             * Useage:
             *   1. register each individual sensor to the library with the registerThresholdedSensor() function in your Sketchs setup() function. See comments in code.
             *   2. implement a SensorValueRequestedCallback() function in your Sketch
             *   3. Implement a SensorValueTransmission() function in your sketch 
             *   4. Call checkThresholdedSensors from within your loop as much as you can.
             * 
             * History
             *   August 1st 2016 - Initial version
             * 
             * Design decisions:
             * - don't put sensro specific code into this library (separation of concern). The main sketch is responsible for the retrieval of sensor values.
             * - Don't use C++ is absorps too much resources. PLain old C is more resource efficient
             * - Don't implement memory management. Freeing up is unnecessary because we don't need to support it. Sensors shouldn't be dynamic in a Sketch
             * 
             * 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.
             *
             *******************************
            */
            
            #ifndef THRESHHOLD_UTIL_H
            #define THRESHHOLD_UTIL_H
            
            /**
             * Declartion of the type definition used by the library
             */
            typedef enum { TEMPERATURE_SENSOR, HUMIDTY_SENSOR, LIGHTLEVEL_SENSOR, CUSTOM_SENSOR } ThreshHoldedSensorType; // The different kind of sensor type for which you can store values. You can extend this enum to your likings or do a pus request on GITHUB
            typedef void (*SensorValueRequestedCallback)( uint8_t aSensorId, ThreshHoldedSensorType aType, float *value ); // Callback handler which is called whenever the library needs a new value for a specific sensor
            typedef void (*SensorValueTransmission)( uint8_t child_id, uint8_t sensor_id, ThreshHoldedSensorType sensor_type, float value ); // Callback handler called whenever the library notices that the value of a specific sensor has to be send to the gateway
            
            /**
             * Structure used by the library for administrating the variabels for a specific sensor. The library uses a linked list of structures.
             */
            typedef struct ThresholdedSensorStruct {
              uint8_t child_id;
              uint8_t sensor_id; // unique id for the sensors for which we hold the values
              ThreshHoldedSensorType sensor_type;
              float      threshHold;
              uint8_t    forcedTransmissionInterval;
              uint8_t    measureCounter;
              float      lastValue;
              unsigned long lastChecked;
              uint8_t    readingInterval;
              ThresholdedSensorStruct *nextNode;
            } *thssPtr;
            
            /**
             * The root node of the linked list of ThresholdedSensorStructs
             */
            thssPtr thresHoldedSensorsrootNode = NULL;
            
            /**
             * Mehthod for adding a sensor who's value needs to be monitored.
             * child_id: The id of child for which the sensor is monitored. It's only for the convenience of the main sketch and isn't used by the library 
             * sensor_id: An id of a sensor. You can use this to group different sensor values if they come from the same sensor. Some sensors like the HDT11 or the BMP180 report multiple sensor types
             *            The main sketch should use this to request the values of such kind of sensors just once and not multiple times for each request for value made by the library
             * sensor_type: Indicates what kind of values are being monitored. Use this to determine what kind of value is required when dealing with multi purpose sensors
             * theshHold: The value of threshold is indicates how much the new value needs to differ from the last send value before it triggers a resend.
             * readingInterval: The amount of seconds the library waits before it request a new value for this sensor
             * forcedTransmissionInterval: The amount of measurements without retransmissions, before a retransmission is triggered. In other words of the values of a sensor don't extend the threshold, a retransmission
             *            is triggered of this given amount of readings.
             */
            void registerThresholdedSensor(   uint8_t child_id, uint8_t sensor_id, ThreshHoldedSensorType sensor_type, float threshHold, uint8_t readingInterval, uint8_t forcedTransmissionInterval ) { // single sensor
              thssPtr aSensor = (ThresholdedSensorStruct*)malloc(sizeof(struct ThresholdedSensorStruct));
              aSensor->sensor_id = sensor_id;
              aSensor->child_id = child_id;
              aSensor->sensor_type = sensor_type;
              aSensor->threshHold = threshHold;
              aSensor->forcedTransmissionInterval = forcedTransmissionInterval;
              aSensor->measureCounter = forcedTransmissionInterval - 1; // correct initialzation
              aSensor->lastValue = 0;
              aSensor->readingInterval = readingInterval;
              aSensor->lastChecked = millis(); // not checked
              aSensor->nextNode = NULL;
              if ( thresHoldedSensorsrootNode == NULL ) {
                thresHoldedSensorsrootNode = aSensor;
              }
              else {
                thssPtr node = thresHoldedSensorsrootNode;
                while ( node->nextNode != NULL ) {
                  node = node->nextNode;
                }
                node->nextNode = aSensor;
              }
            }
            
            /**
             * Supportive method for the checkThresholdedSensors routine. It checks if the value of the given sensors needs to be read according to the given timeStamp.
             * The given SensorValueRequestedCallback is used to query the values of a sensor. The given SensorValueTransmission is called when a (re)transmisson for the value
             * of the given Sensor is required.
             * This method contains the actual logic of the library.
             */
            void checkIndividualThreshHoldedSensor( thssPtr aSensor, unsigned long timeStamp, SensorValueRequestedCallback aCallBack, SensorValueTransmission transmissionCallback ) {
              // determine whether node should be checked in first place!!!
              if ( aSensor->lastChecked <= timeStamp ) {
                aSensor->measureCounter++;
                float value;
                aCallBack( aSensor->sensor_id, aSensor->sensor_type, &value );
                aSensor->lastChecked = timeStamp + ( (unsigned long)aSensor->readingInterval * 1000 );
            
                float diffMeasurement = abs( aSensor->lastValue - value );
            
                bool sendValues = false;
            
                if ( diffMeasurement >= aSensor->threshHold || aSensor->measureCounter == aSensor->forcedTransmissionInterval ) { // transmit value
                  aSensor->lastValue = value;
                  aSensor->measureCounter = 0;
                  transmissionCallback(  aSensor->child_id,  aSensor->sensor_id, aSensor->sensor_type, aSensor->lastValue );
                }
              }
            }
            
            /**
             * Checks all defined sensors on: if they need to be checked and if their value needs to be send to the gateway:
             * aCallBack: pointer to a function that can determine the sensors current value (logic should be implemented in the main sketch, separation of concern)
             * transmissionCallback: pointer to the function the deals with sending a value of a sensor to the gateway (logic should be implemnted by the main sketch, separation of concern)
             */
            void checkThresholdedSensors( SensorValueRequestedCallback aCallBack, SensorValueTransmission transmissionCallback ) {
              unsigned long timeStamp = millis();
              if ( thresHoldedSensorsrootNode != NULL ) {
                thssPtr node = thresHoldedSensorsrootNode;
                checkIndividualThreshHoldedSensor( node, timeStamp, aCallBack, transmissionCallback );
                while ( node->nextNode != NULL ) {
                  node = node->nextNode;
                  checkIndividualThreshHoldedSensor( node, timeStamp, aCallBack, transmissionCallback );
                }
              }
            }
            
            #endif
            

            In your setup code you add:

              registerThresholdedSensor( CHILD_ID_TEMP, DHT_SENSOR, TEMPERATURE_SENSOR, 0.5, 30, 20 ); // every 30 seconds report at least every 10 minutes
              registerThresholdedSensor( CHILD_ID_HUMIDITY, DHT_SENSOR, HUMIDTY_SENSOR, 1.0, 60, 10 ); // every 60 seconds
            

            Add this line in the presentation method:

              checkThresholdedSensors( checkThrsedSensor, reportSensorValue ); // Necessary call for intializing ThresholdUtil
            

            Now implement the call back function's.

            float lastHumidity;
            
            /**
             * Callback method called by the Threshold util library whenever the library needs a new value for a specific sensor
             */
            void checkThrsedSensor( uint8_t aSensorId, ThreshHoldedSensorType aType, float *value ) {
              if ( aSensorId == DHT_SENSOR  ) {
                if ( aType == TEMPERATURE_SENSOR ) {
                  lastHumidity = dht.readHumidity();
                  *value = dht.readTemperature();;
                }
                else {
                  // no need to read Humidity. We just read it when we read temp value. Haven't found a decent solution to support this from within the library
                  *value = lastHumidity;
                }
              }
            }
            /**
             * Threshholded sensor's value needs to be reported to the gateway.
             */
            void reportSensorValue( uint8_t child_id, uint8_t sensor_id, ThreshHoldedSensorType sensor_type, float value ) {
              if ( child_id == CHILD_ID_TEMP ) {
                send( TemperatureMsg.set( value, 1), true );
              }
              else {
                send( HumidityMsg.set( value, 1), true );
              }
            

            And add this into your sketches main loop:

                checkThresholdedSensors( checkThrsedSensor, reportSensorValue );
            

            The library will only report changes when temperature differs 0.5 degrees from last send values. Or if the threshold isn't reached it sends the temperature every 5 minutes. It's the same for humidity, but that has a threshold of 1 %.

            Hope this helps. I will put the code on my github with examples when I've tested it enough.

            1 Reply Last reply
            1
            • sinczeS sincze

              tnx @TheoL

              Don't posted my repeater sketch on github yet (for my own reference and backup).

              However the sketch that resembles my repeaternode is stored here:
              https://github.com/sincze/mysensors-2..0.x-temperature-humidity/commit/5824defa434c750bf706351562c3ee0dfc8ab4ea

              I want to capture the door being opened however... don't want to have the temperature readings measured every second or so ;-)

              I think repeater mode is only one extra line in the code ;-0

              // Enabled repeater feature for this node
              #define MY_REPEATER_FEATURE
              

              Your help is appreciated ;-)

              TheoLT Offline
              TheoLT Offline
              TheoL
              Contest Winner
              wrote on last edited by
              #6

              @sincze it's on my github with a non MySensors example, that should explain how you use the library

              sinczeS 1 Reply Last reply
              0
              • TheoLT TheoL

                @sincze it's on my github with a non MySensors example, that should explain how you use the library

                sinczeS Offline
                sinczeS Offline
                sincze
                MySensors Evangelist
                wrote on last edited by sincze
                #7

                @TheoL tnx. looks pretty straight forward. and indeed... cheap sensors.... hahaha. Well I've used some calibration variables in my script to keep the sensor in line with my crestra 320tx.
                So what I can do is remove the sleep thing from my sketch and just implement your library in the loop and we are all good to go. excellent. Just one question. As this is a repeater node... would leaving the delay( 5000 ); (mentioned in your example sketch on github) in the void loop a good idea??

                TheoLT 2 Replies Last reply
                0
                • sinczeS sincze

                  @TheoL tnx. looks pretty straight forward. and indeed... cheap sensors.... hahaha. Well I've used some calibration variables in my script to keep the sensor in line with my crestra 320tx.
                  So what I can do is remove the sleep thing from my sketch and just implement your library in the loop and we are all good to go. excellent. Just one question. As this is a repeater node... would leaving the delay( 5000 ); (mentioned in your example sketch on github) in the void loop a good idea??

                  TheoLT Offline
                  TheoLT Offline
                  TheoL
                  Contest Winner
                  wrote on last edited by
                  #8

                  @sincze You shouldn't use delay with MySensors. Just use a wait instead. A delay will stall the execution of an Arduino. Causing the node to miss messages. A wait will stall the sketch but still handles incomming requests. This is the same for all node's regarding if they're a repeater or not.

                  1 Reply Last reply
                  0
                  • sinczeS sincze

                    @TheoL tnx. looks pretty straight forward. and indeed... cheap sensors.... hahaha. Well I've used some calibration variables in my script to keep the sensor in line with my crestra 320tx.
                    So what I can do is remove the sleep thing from my sketch and just implement your library in the loop and we are all good to go. excellent. Just one question. As this is a repeater node... would leaving the delay( 5000 ); (mentioned in your example sketch on github) in the void loop a good idea??

                    TheoLT Offline
                    TheoLT Offline
                    TheoL
                    Contest Winner
                    wrote on last edited by
                    #9

                    @sincze What's really important is adding the * in front of the value. Otherwise the library won't be able to get your values. It's in this part:

                    void checkThrsedSensor( uint8_t aSensorId, ThreshHoldedSensorType aType, float *value ) {
                      if ( aSensorId == DHT_SENSOR  ) {
                        if ( aType == TEMPERATURE_SENSOR ) {
                          lastHumidity = dht.readHumidity();
                          *value = dht.readTemperature();;
                        }
                        else {
                          // no need to read Humidity. We just read it when we read temp value. Haven't found a decent solution to support this from within the library
                          *value = lastHumidity;
                        }
                      }
                    }
                    
                    1 Reply Last reply
                    0
                    • sinczeS Offline
                      sinczeS Offline
                      sincze
                      MySensors Evangelist
                      wrote on last edited by
                      #10

                      Thanks. I did not know for sure if this was still the case in 2.0.0.
                      wait(sleepTimer); added at the bottom of loop() function.

                      now lets rewrite the sketch with your library.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      20

                      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