Node to Node ACK



  • Evenin' all. I'm using the following to confirm messages are successfully sent.

    void Resend(MyMessage &msg) {
      int repeatDelay = 1000;
      boolean sendOK = false;
      unsigned long lastWhile;
    
      while (sendOK == false) {
        if ((millis() - lastWhile) >= repeatDelay) {
          if (send(msg) == true) sendOK = true;
          else repeatDelay += 1000;
          lastWhile = millis();
        }
      }
    }
    

    Here's the full code.

    #define MY_DEBUG
    #define MY_RADIO_RF24
    #define MY_NODE_ID 22
    #define SENSOR_NAME "Master Bedroom Sensors"
    #define SENSOR_VERSION "2.1"
    #define DHT_DATA_PIN 3
    #define SENSOR_TEMP_OFFSET 0
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    
    #include <SPI.h>
    #include <DHT.h>
    #include <MySensors.h>
    #include <avr/wdt.h>
    
    DHT dht;
    
    int lastTemp, lastHum;
    unsigned long lastLoop;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    
    void presentation() {
      sendSketchInfo(SENSOR_NAME, SENSOR_VERSION);
      present(CHILD_ID_HUM, S_HUM, "Humidity");
      present(CHILD_ID_TEMP, S_TEMP, "Temperature");
    }
    
    void setup() {
      wdt_enable(WDTO_8S);
      dht.setup(DHT_DATA_PIN);
    }
    
    void loop() {
      if ((millis() - lastLoop) >= 10000) {
        dht.readSensor(true);
        int temperature = lrint(dht.toFahrenheit(dht.getTemperature()) + SENSOR_TEMP_OFFSET);
        if (temperature > 1 && temperature != lastTemp) {
          lastTemp = temperature;
          Resend(msgTemp.setDestination(26).setSensor(101).set(lastTemp));
          Resend(msgTemp.set(lastTemp));
        }
    
        int humidity = lrint(dht.getHumidity());
        if (!isnan(humidity) && humidity != lastHum) {
          lastHum = humidity;
          Resend(msgTemp.setDestination(26).setSensor(100).set(lastHum));
          Resend(msgHum.set(lastHum));
        }
        lastLoop = millis();
      }
      wdt_reset();
    }
    
    void Resend(MyMessage &msg) {
      int repeatDelay = 1000;
      boolean sendOK = false;
      unsigned long lastWhile;
    
      while (sendOK == false) {
        if ((millis() - lastWhile) >= repeatDelay) {
          if (send(msg) == true) sendOK = true;
          else repeatDelay += 1000;
          lastWhile = millis();
        }
      }
    }
    

    This works very well for messages sent to the gateway; however, it is not catching node-2-node failures.

    10041 !TSF:MSG:SEND,22-22-26-26,s=101,c=1,t=0,pt=2,l=2,sg=0,ft=0,st=NACK:70
    10048 !TSF:RTE:N2N FAIL
    10052 TSF:MSG:SEND,22-22-0-26,s=101,c=1,t=0,pt=2,l=2,sg=0,ft=0,st=OK:70
    10094 !TSF:MSG:SEND,22-22-26-26,s=100,c=1,t=1,pt=2,l=2,sg=0,ft=0,st=NACK:58
    10101 !TSF:RTE:N2N FAIL
    

    I shut down node 26 in order to reproduce the errors. Is there a way to catch these failures?

    Thanks!


  • Mod

    Welcome to the forum @anderBAKE

    Multiple people have tried, but I don't think anyone has been able to make it work.

    Some threads
    https://forum.mysensors.org/post/99252
    https://forum.mysensors.org/post/99485
    https://forum.mysensors.org/post/102134



  • @anderBAKE When a node to node communication fails, MySensors will automatically fall back to the default route via the node's parent, so that ultimately the gateway can try to reach the destination node. I'm not sure if you can change that behaviour without touching the library code. But if you don't mind, a small change in MyTransport.cpp should do the trick.

    Change the following starting on line 548...

    if (destination > GATEWAY_ADDRESS && destination < BROADCAST_ADDRESS) {
    	// node2node traffic: assume node is in vincinity. If transmission fails, hand over to parent
    	if (transportSendWrite(destination, message)) {
    		TRANSPORT_DEBUG(PSTR("TSF:RTE:N2N OK\n"));
    		return true;
    	}
    	TRANSPORT_DEBUG(PSTR("!TSF:RTE:N2N FAIL\n"));
    }
    

    to the following...

    if (destination > GATEWAY_ADDRESS && destination < BROADCAST_ADDRESS) {
    	// node2node traffic
    	if (transportSendWrite(destination, message)) {
    		TRANSPORT_DEBUG(PSTR("TSF:RTE:N2N OK\n"));
    		return true;
    	} else {
    		TRANSPORT_DEBUG(PSTR("!TSF:RTE:N2N FAIL\n"));
    		return false;
    	}
    }
    

    This will drop out of the transportRouteMessage() function returning false to the send() function if the N2N communication failed.

    Note that, after this change, the node will not fall back to the default transport route anymore.

    Maybe this could be made an optional feature by introducing something like #define MY_DISABLE_N2N_FALLBACK to MyConfig.h?



  • @mfalkvidd said in Node to Node ACK:

    Welcome to the forum @anderBAKE

    Multiple people have tried, but I don't think anyone has been able to make it work.

    Some threads
    https://forum.mysensors.org/post/99252
    https://forum.mysensors.org/post/99485
    https://forum.mysensors.org/post/102134

    @mfalkvidd thanks! The first link is where I got the inspiration for my resend loop. I'll look into the other links after work today.

    @BearWithBeard said in Node to Node ACK:

    @anderBAKE When a node to node communication fails, MySensors will automatically fall back to the default route via the node's parent, so that ultimately the gateway can try to reach the destination node. I'm not sure if you can change that behaviour without touching the library code. But if you don't mind, a small change in MyTransport.cpp should do the trick.

    Change the following starting on line 548...

    if (destination > GATEWAY_ADDRESS && destination < BROADCAST_ADDRESS) {
    	// node2node traffic: assume node is in vincinity. If transmission fails, hand over to parent
    	if (transportSendWrite(destination, message)) {
    		TRANSPORT_DEBUG(PSTR("TSF:RTE:N2N OK\n"));
    		return true;
    	}
    	TRANSPORT_DEBUG(PSTR("!TSF:RTE:N2N FAIL\n"));
    }
    

    to the following...

    if (destination > GATEWAY_ADDRESS && destination < BROADCAST_ADDRESS) {
    	// node2node traffic
    	if (transportSendWrite(destination, message)) {
    		TRANSPORT_DEBUG(PSTR("TSF:RTE:N2N OK\n"));
    		return true;
    	} else {
    		TRANSPORT_DEBUG(PSTR("!TSF:RTE:N2N FAIL\n"));
    		return false;
    	}
    }
    

    This will drop out of the transportRouteMessage() function returning false to the send() function if the N2N communication failed.

    Note that, after this change, the node will not fall back to the default transport route anymore.

    Maybe this could be made an optional feature by introducing something like #define MY_DISABLE_N2N_FALLBACK to MyConfig.h?

    @BearWithBeard very interesting. I'll definitely be looking into this this evening as well.

    Thank you both for the speedy replies!



  • @BearWithBeard Making the change that you suggested returns the expected results! Thanks for suggestion.


Log in to reply
 

Suggested Topics

0
Online

11.4k
Users

11.1k
Topics

112.6k
Posts