Reduce overhead with multiple sensors?

  • Hello,

    I noticed that for every sensors I want to send to my controller there has to be an separate message:

    • Send VCC of node
    • Send Sensorvalue1
    • Send Sensorvalue2
    • Send Sensorvalue3

    Assuming my node sleeps for 60 seconds and then sends the current batch of values .. that means that I have to send 4 separate Messages over the air with 7byte Overhead for the MySensorPacket + the overhead of my RF-Module.

    Are there any plans to send more values in one message? The RF24 for example allows 32byte of payload (-7byte overhead) .. there seems to be plenty of room to fit the other sensor-values.

    ofc I understand that might need mayor rewrite of the library .. does it? Or maybe changing mymessage would be enough. Still I would like to see this feature in long term on some kind of agenda.

    I would like to hear your comments on this.

  • Hardware Contributor

    and this could help battery powered nodes, coincell for instance, not doing multiple tx. and manage only one signing session for a wakeup period.
    I guess that has been done for a good reason (faster transmit time and power for less bytes one msg, i don't know..)
    Not sure, I think this feature implies multiple aspect for the moment.. protocol and controllers..

    I'm interested too. To know what are the solution/ future plan on this, even for the moment it's not the hurry-est optmization feature for me.

  • Mod

    Longer messages would weaken signaures, which already are slightly weakened due to the small (32 byte) maximum payload.

    Coalescing messages would be cool, but I am not sure it would make a real difference on battery life. I have a battery powered node that has been sending every 5 minutes since November last year and it is still at 3.134V being powered by 2xAA. That node only has one sensor, so if it had very many sensors the battery life would be lower, but I think powering thise sensors might be more expensive (power-wise) than sending the values.

    So, while a cool idea, would it really solve an existing problem?

  • Thanks for your input. It was more of a "tought" then some real problem I ran into.

    As I am currently in the setup phase I am thinking of sending some more debug values. For example some raw sensor readings along with the calculated and corrected value.

    My thought was just .. does a Sensor with 5 send Values really only last 1/5 of the time? This is ofc. exaggerated but herefore I am looking for some inputs from the community if somebody else ran into similar thoughts.

  • Hardware Contributor

    @mfalkvidd good point πŸ™‚

    Not really a problem, at least for me, I think if i would need this I would use a string type message.

    A usecase for instance, that's very specific in fact but can happens:

    • coincell, lifetime conditioned by how you do your tx (chain or not) and mostly the number of tx. If you consider sensors does not take much power. wake up time can be short only if tx time is short.
    • temp/hum sensor, light, pir, battery, and says why not reed. all low power.
    • i don't remember if signing is global on the node or msg specific but i think it's the node.
    • so if at a moment, multiple value needs to be sent, that will give multiple tx with their signing stuff. so more power compared to only one.

    but i agree with you. for me a node which can last 2-3 years min, even without this feature, is ok for me, and AAA/AA are great πŸ™‚

  • Hardware Contributor

    I have to agree.
    I got this feature implemented a year ago by @Meister_Petz here. Cool but not neccessary and worth the hassle when battery life already is as good as it is.

  • @m26872 I like the idea but this would still break compability with most controllers. Some improvement to concatenating the values and sending them would be to split them at the gateways before submitting them to the controller.

    Still impressive to see that the battery impact is negleactable ..

    Nevertheless I would still like to share my observation on congestion and delay induced by sending sensor values in succession:

    Look at this output, sending

    • BatteryPercent
    • Wait 15ms
    • Send LightSensorValue

    resulting in this:

    Ignore the longer retrys for now .. ~3,2ms to send a message and receive the result from gateway.

    SketchInfo: Aug 14 2016 | 21:33:49
     | millis:     4073 | vcc: 3280 | Light: 21 #
     | success | time:   **3632uS**| retr.:  0 | rpd: 1 | 
     | millis:    12108 | vcc: 3280 | Light: 20 #
     | success | time:   **3216uS**| retr.:  0 | rpd: 1 | 
     | millis:    20141 | vcc: 3280 | Light: 21 #
     | success | time:  27792uS | retr.:  1 | rpd: 1 | 
    # | millis:    28198 | vcc: 3280 | Light: 21 #
     | success | time:   3224uS | retr.:  0 | rpd: 1 | 
     | millis:    36231 | vcc: 3280 | Light: 21 #
     | success | time:  28152uS | retr.:  1 | rpd: 1 | 
     | millis:    44288 | vcc: 3280 | Light: 21 #
     | success | time:   3216uS | retr.:  0 | rpd: 1 | 
     | millis:    52321 | vcc: 3280 | Light: 21 #
     | success | time:   3216uS | retr.:  0 | rpd: 1 | 
     | millis:    60354zZz

    Omitting the 15ms delay the values look something like this ...

     | millis:   196474zZz
    SketchInfo: Aug 14 2016 | 21:37:20
     | millis:     4079 | vcc: 3280 | Light: 21 #
     | success | time:   **9752uS**| retr.:  0 | rpd: 1 | 
     | millis:    12106 | vcc: 3280 | Light: 22 #
     | success | time:   **8448uS**| retr.:  0 | rpd: 1 | 
     | millis:    20128 | vcc: 3280 | Light: 21 #
     | success | time:  39576uS | retr.:  2 | rpd: 1 | 
    # | millis:    28182 | vcc: 3280 | Light: 22 #
     | success | time:   **8024uS**| retr.:  0 | rpd: 1 | 
     | millis:    36204 | vcc: 3280 | Light: 21 #
     | success | time:  75200uS | retr.:  4 | rpd: 1 | 
    # | millis:    44292 | vcc: 3280 | Light: 21 #
     | success | time:   7744uS | retr.:  0 | rpd: 1 | 
     | millis:    52315 | vcc: 3280 | Light: 21 #
     | success | time:   9592uS | retr.:  0 | rpd: 1 | 

    So for now I have 2 options ..

    • BatteryPercent (I guess 1,6ms)
    • Wait 15ms
    • Send LightSensorValue (3,2ms)
      = 19,8ms


    • BatteryPercent (I guess 1,6ms)
    • Send LightSensorValue (8,2ms)
      = 9,8ms

    Just a simple example that sending multiple values in "rapid" succession will anyway result in a congestion at the gateway.

    Assuming sending only one message (including 2 values) would take 3,2ms+X in contrast to 9,8ms.

    I know most of you won't be impressed by crunching numbers but I still want to point out the there is just some potential in improving battery life with multiple sensor values.

    PS: As I am using an esp8266 (2) mqtt gateway it might be enough for my needs to assemble one message containing all sensor values and split it here .. sending separate values to the mqtt-broker .. thus staying compatible with the controller:

    bool gatewayTransportSend(MyMessage &message) {
    	if (!_MQTT_client.connected())
    		return false;
    	char _fmtBuffer[MY_GATEWAY_MAX_SEND_LENGTH];
    	char _convBuffer[MAX_PAYLOAD * 2 + 1];
            // **Somewhere** here might be a good place to split the payload of MyMessage and publish separate publications to the gateway
    	snprintf_P(_fmtBuffer, MY_GATEWAY_MAX_SEND_LENGTH, PSTR(MY_MQTT_PUBLISH_TOPIC_PREFIX "/%d/%d/%d/%d/%d"), message.sender, message.sensor, mGetCommand(message), mGetAck(message), message.type);
    	debug(PSTR("Sending message on topic: %s\n"), _fmtBuffer);
    	return _MQTT_client.publish(_fmtBuffer, message.getString(_convBuffer));

    Had some quick look at MyMessage-Definition .. to make packaging different SensorValues with relevant information into a single packet (type,subid,value) reasonable .. well .. just concatenating doesn't cut it:

    Type + Sensor + Payload = 12 chars only for a small float .. and implementing a packet format like mysensor is using would require some deeper C-knowledge ..


    In addition to that the datatype is embedded in the mymessage header .. and not in the payload .. puh .. some serious work here if it should be done "right".

  • Admin


    I think better control over when to transmit could be a better way to save power with the current state of the library.

    For example, only transmit a sensor value, if it has changed by a certain amount.

    I have multiple sensebender nodes running for more than a year on 2xAA batteries, they all report about 2.6v battery voltage

  • @m26872

    I am currently implementing a little wrapper around the MyMessage object to check for things like "Is it time to send again?!".
    I use 8000ms Sleep Cycle and then run a bunch of these functions:

        bool MySensorChild::timeok()
          if(mymillis() - _lastsend > _interval || mymillis() < 60000)
            return true;
            return false;  

    _lastsend is the time the sensor last updated its value. In addition to that I am planning to save the last value too to send only if necessary or after an defined "Minimum send" interval.

    Using sleep I had to use a little wrapper for millis()

    unsigned long static millis_offset = 0;
    unsigned long static mymillis()
      return millis()+millis_offset;

    and adding the offset myself:

      sleep(8000); // If powersaving is desired (8s, 4s, 2s, 1s, 500ms, 250ms, 125ms, 64ms, 32ms, 16ms
      millis_offset += 8000;

    In addition to that I implemented software ack, retrycount .. and display of RPD Signal Strength indicator.

    PS: Saving the "lastvalue" seems to be tough. At least if it should be done in a generic ways as the valuetype could be different each time .. int, float etc...

Log in to reply

Suggested Topics