Gateway sends NACK to node



  • Hi
    I am new to mysensors. I don't think I understand enough to get going so any help will be appreciated.
    I am running HA on a RPI3 with a Serial Gateway. I use the RFM95 radios on the Gateway and the node.
    I can see the node message is received at the GW but I get a NACK back. I am not sure why or where to look for the issue.
    Here is the message from the DEBUG output on the node

    !TSF:MSG:SEND,0-0-1-1,s=255,c=3,t=8,pt=1,l=1,sg=0,ft=0,st=NACK:0
    

    This is copied from the HA log file.
    Some of the traffic

    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.transport] Receiving 0;255;3;0;0;0
    2022-07-23 13:15:23 DEBUG (MainThread) [homeassistant.components.mysensors.gateway] Node update: node 0 child 255
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.transport] Receiving 0;255;3;0;9;1618933 TSF:MSG:READ,1-1-255,s=255,c=3,t=7,pt=0,l=0,sg=0:
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.handler] n:0 c:255 t:3 s:9 p:1618933 TSF:MSG:READ,1-1-255,s=255,c=3,t=7,pt=0,l=0,sg=0:
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.transport] Receiving 0;255;3;0;9;1618954 TSF:MSG:BC
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.handler] n:0 c:255 t:3 s:9 p:1618954 TSF:MSG:BC
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.transport] Receiving 0;255;3;0;9;1618962 TSF:MSG:FPAR REQ,ID=1
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.handler] n:0 c:255 t:3 s:9 p:1618962 TSF:MSG:FPAR REQ,ID=1
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.transport] Receiving 0;255;3;0;9;1618974 TSF:PNG:SEND,TO=0
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.handler] n:0 c:255 t:3 s:9 p:1618974 TSF:PNG:SEND,TO=0
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.transport] Receiving 0;255;3;0;9;1618984 TSF:CKU:OK
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.handler] n:0 c:255 t:3 s:9 p:1618984 TSF:CKU:OK
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.transport] Receiving 0;255;3;0;9;1618993 TSF:MSG:GWL OK
    2022-07-23 13:15:23 DEBUG (MainThread) [mysensors.handler] n:0 c:255 t:3 s:9 p:1618993 TSF:MSG:GWL OK
    2022-07-23 13:15:23 DEBUG (SyncWorker_7) [mysensors.persistence] Saving sensors to persistence file /config/mysensors/mysensors1.json
    


  • Can you paste the code for the node please?
    Just a hint: Have you set the node ID manually? HA does not assign node ID automatically as far as I know. You have to set it manually in the code using:

    #define MY_NODE_ID 23
    

    Node-ID is a number between 1 and 254, unique to each node. The default is AUTO which requests an ID from the controller. HA does not assign node ID.



  • Hi
    I did set the nodeid. Just to mention, I have a sensor in the gateway as well to monitor the gateway battery level. I don't know if that is normal.

    /*
     Name:		TankSensorLora.ino
     Created:	6/6/2022 4:13:02 PM
     Author:	mariu
    */
    
    /*
    Sketch to read level of water in a round tank and  then send data back to controller
    uses MySensors V2 .
    
    Libraries used
    MySensors          https://www.mysensors.org/
    NewPing            https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home
    SPI                 installed with arduino IDE
    
    */
    
    // Enable debug prints to serial monitor
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    #define MY_SENSOR_NETWORK
    #define MY_REPEATER_FEATURE
    
    //#include <SPI.h>
    #include <NewPing.h>
    
    // 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_DEBUG_VERBOSE_RFM95
    #define MY_RFM95_FREQUENCY (RFM95_868MHZ)
    #define MY_TRANSPORT_STATE_TIMEOUT_MS  (5*1000ul)
    #define RFM95_RETRY_TIMEOUT_MS  (3000ul) 
    #define MY_RFM95_MAX_POWER_LEVEL_DBM (1) //1mW = 0dBm 10mW = 10dBm 25mW = 14dBm 100mW = 20dBm
    //#define MY_RFM95_TX_POWER_DBM (13u)
    //#define MY_RFM95_MODEM_CONFIGRUATION RFM95_BW125CR45SF1288
    #define MY_RFM95_MODEM_CONFIGRUATION  RFM95_BW125CR48SF4096
    #define MY_RFM95_RST_PIN (9)
    //#define MY_RFM95_POWER_PIN (3)
    //#define DEFAULT_RFM95_IRQ_PIN
    #define DEFAULT_RFM95_CS_PIN (10)
    #define MY_NODE_ID 10
    
    #include <MySensors.h>
    #include <MyConfig.h>
    
    #define CHILD_ID_BATTERY 0
    #define CHILD_ID_WATER 1
    #define CHILD_ID_PERCENT 2
    
    
    // newping settings
    #define TRIGGER_PIN  6                  // Arduino pin 6 connected to trigger pin on the ultrasonic sensor.
    #define ECHO_PIN     5                  // Arduino pin 7 connected to echo pin on the ultrasonic sensor.
    #define MAX_DISTANCE 240                // Maximum distance we want to ping for (in centimeters). you should set this to be 
                                            // a bit more than fullHeight + sensHeight.
    
    /*------change these to suit your tank setup-----*/
    const int tankRad = 170;                // Radius of tank in cm
    const int fullHeight = 198;             // Height of water when tank full in cm
    const int sensHeight = 30;              // height of sensor above full water mark in cm
    const int outletHeight = 10;            // height of water when tank reading will show empty in cm
    /*----------------------------------------------*/
    
    unsigned long lastSent;
    unsigned long heartbeatDelay = 15;     // how often the heartbeat will be sent, in minutes
    //unsigned long lastHeartbeat = millis(); // holder for last time heartbeat was sent
    unsigned long waitTime = 15000;          // delay in milliseconds to set time between data readings 
    unsigned long pingHeight;               // holds total height from ultrasonic sender to current water height
    unsigned int waterAvail;                // holds current water available in litres
    unsigned int batteryLevel;
    unsigned int batteryPercent;
    
    byte oldWaterPercent;
    byte waterPercent = 0;                 // used to hold the tank water level percentage
    
    // NewPing setup of pins and maximum distance.
    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
    
    MyMessage msgBattery(CHILD_ID_BATTERY, V_LEVEL);
    MyMessage msgVolume(CHILD_ID_WATER, V_LEVEL);              //water availble in liters
    MyMessage msgPercent(CHILD_ID_PERCENT, V_LEVEL);           // water percentsge available
    
    void setup() {
    
    }
    
    
    void presentation() {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Tank Level", "1.0");
    
        // Register all sensors to gateway (they will be created as child devices)
        present(CHILD_ID_BATTERY, S_DUST, "Battery Level");
        send(msgBattery.set(batteryPercent), 1);
        present(CHILD_ID_WATER, S_DUST, "Water Available");
        send(msgVolume.set(waterAvail));
        present(CHILD_ID_PERCENT, S_DUST, "Water Percentage Available");
        send(msgPercent.set(waterPercent));
    }
    
    
    void loop()
    {
    
    
        data_calc();      // perform calculations to get water remaining etc.
    
    
       // if (oldWaterPercent != waterPercent) 
        {         //check to see if new water data is available  
            send(msgVolume.set(waterAvail));
            send(msgPercent.set(waterPercent));
            oldWaterPercent = waterPercent;
            lastSent = millis();
        }
    
       // heartbeatCheck();                                    // call heartbeat function
    
        wait(waitTime);  //Wait then back to loop
    
    }
    
    /*-------------------------start of functions-------------------*/
    
    void heartbeatCheck() {
        unsigned long millisNow = millis();           // get the current time
        if ((millisNow - lastSent) > (heartbeatDelay * 60000)) {
            send(msgBattery.set(batteryPercent), 1);
            send(msgVolume.set(waterAvail));
            send(msgPercent.set(waterPercent));
            lastSent = millisNow;
        }
    
        /*if ((millisNow - lastHeartbeat) > (heartbeatDelay*60000)) {
          sendHeartbeat();
          wait(5);
         // sendBatteryLevel(100);
          lastHeartbeat = millis();
          #ifdef MY_DEBUG
            Serial.println("Heartbeat Sent" );
          #endif
        } */
    }
    
    void data_calc() {
    #ifdef MY_DEBUG
        Serial.println("Pinging Height");
        //Serial.println(pingHeight);
    #endif
        pingHeight = sonar.ping_median(5);             //- Do multiple (5) pings and return median
        pingHeight = sonar.convert_cm(pingHeight);     // then convert to cm
    #ifdef MY_DEBUG
        Serial.print("Ping Height raw in cm: ");
        Serial.println(pingHeight);
    #endif
        pingHeight = constrain(pingHeight, sensHeight, (fullHeight - outletHeight) + sensHeight);     // keep pingHeight within the expected values
        waterPercent = map(pingHeight, sensHeight, (fullHeight - outletHeight) + sensHeight, 100, 0);           // calculate the percentage of water available
        waterAvail = PI * pow(tankRad, 2) * (((fullHeight - outletHeight) + sensHeight) - pingHeight) / 1000;    // calculate water available in litres
    
       // Write some debug info
    #ifdef MY_DEBUG
        Serial.print("Ping Height constrained in cm: ");
        Serial.println(pingHeight);
        Serial.print("Percentage Available: ");
        Serial.println(waterPercent);
        Serial.print("Litres Available: ");
        Serial.println(waterAvail);
    #endif
    }
    
    
    


  • This is the gateway code as well.

    /*
     Name:		GatewaySerialLora.ino
     Created:	6/6/2022 11:10:17 AM
     Author:	mariu
    */
    
    /**
    * 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-2020 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
    * The ArduinoGateway prints data received from sensors on the serial link.
    * The gateway accepts input on serial which will be sent out on radio network.
    *
    * The GW code is designed for Arduino Nano 328p / 16MHz
    *
    * Wire connections (OPTIONAL):
    * - Inclusion button should be connected between digital pin 3 and GND
    * - RX/TX/ERR leds need to be connected between +5V (anode) and digital pin 6/5/4 with resistor 270-330R in a series
    *
    * LEDs (OPTIONAL):
    * - To use the feature, uncomment any of the MY_DEFAULT_xx_LED_PINs
    * - RX (green) - blink fast on radio message received. In inclusion mode will blink fast only on presentation received
    * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
    * - ERR (red) - fast blink on error during transmission error or receive crc error
    *
    */
    
    
    
    // Enable debug prints to serial monitor
    #include <SPI.h>
    #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_DEBUG_VERBOSE_RFM95
    #define MY_RFM95_FREQUENCY (RFM95_868MHZ)
    #define MY_TRANSPORT_STATE_TIMEOUT_MS  (5*1000ul)
    #define RFM95_RETRY_TIMEOUT_MS  (3000ul) 
    #define MY_RFM95_MAX_POWER_LEVEL_DBM (1) //1mW = 0dBm 10mW = 10dBm 25mW = 14dBm 100mW = 20dBm
    //#define MY_RFM95_TX_POWER_DBM (13u)
    //#define MY_RFM95_MODEM_CONFIGRUATION RFM95_BW125CR45SF1288
    #define MY_RFM95_MODEM_CONFIGRUATION  RFM95_BW125CR48SF4096
    #define MY_RFM95_RST_PIN (9)
    //#define MY_RFM95_POWER_PIN (3)
    //#define DEFAULT_RFM95_IRQ_PIN
    #define DEFAULT_RFM95_CS_PIN (10)
    
    // Enable serial gateway
    #define MY_GATEWAY_SERIAL
    
    // Define a lower baud rate for Arduinos running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
    #if F_CPU == 8000000L
    #define MY_BAUD_RATE 38400
    #endif
    
    // Enable inclusion mode
    #define MY_INCLUSION_MODE_FEATURE
    // Enable Inclusion mode button on gateway
    //#define MY_INCLUSION_BUTTON_FEATURE
    
    // Inverses behavior of inclusion button (if using external pullup)
    //#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP
    
    // Set inclusion mode duration (in seconds)
    #define MY_INCLUSION_MODE_DURATION 60
    // Digital pin used for inclusion mode button
    //#define MY_INCLUSION_MODE_BUTTON_PIN  3
    
    // Set blinking period
    #define MY_DEFAULT_LED_BLINK_PERIOD 300
    
    // Inverses the behavior of leds
    //#define MY_WITH_LEDS_BLINKING_INVERSE
    
    // Flash leds on rx/tx/err
    // Uncomment to override default HW configurations
    //#define MY_DEFAULT_ERR_LED_PIN 4  // Error led pin
    //#define MY_DEFAULT_RX_LED_PIN  6  // Receive led pin
    //#define MY_DEFAULT_TX_LED_PIN  5  // the PCB, on board LED
    
    #include <MySensors.h>
    #include <MyConfig.h>
    
    #define SLEEP_TIME_MS (24ul*60ul*60ul*1000ul) // Sleep time between battery reports (24h, in milliseconds)
    #define CHILD_ID 1   // Id of the sensor child
    
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    const float VccMin = 2.8;      // Minimum expected Vcc level, in Volts: Brownout at 1.8V    -> 0%
    const float VccMax = 3.8;  // Maximum expected Vcc level, in Volts: 2xAA fresh Alkaline -> 100%
    const float VccCorrection = 1.0;      // Measured Vcc by multimeter divided by reported Vcc
    int BATTERY_SENSE_PIN = A6;  // select the input pin for the battery sense point
    
    
    void setup()
    {
    	// Setup locally attached sensors
    	analogReference(INTERNAL);
    }
    
    void presentation()
    {
    	sendSketchInfo(F("Serial Gateway"), F("1.0"));
    
    	// Register all sensors to gw (they will be created as child devices)
    	present(CHILD_ID, S_CUSTOM, F("Gateway Battery Level"));
    	// Present locally attached sensors
    }
    
    void loop()
    {
    	delay(10000);
    	// Send locally attached sensor data here
    	uint16_t res = analogRead(A6);
    	const uint8_t batteryPcnt = map(res, 0, 4096, 0, 100);
    	//
    	//const uint8_t batteryPcnt = static_cast<uint8_t>(0.5 + vcc.Read_Perc(VccMin, VccMax));
    	sendBatteryLevel(batteryPcnt);
    
    	//sendBatteryLevel();
    
    #ifdef MY_DEBUG
    	float batteryV = res * 0.003363075;
    	Serial.print("Battery Voltage: ");
    	Serial.print(batteryV);
    	Serial.println(" V");
    
    	Serial.print("Battery percent: ");
    	Serial.print(batteryPcnt);
    	Serial.println(" %");
    #endif
    
    	//if (oldBatteryPcnt != batteryPcnt) {
    	//	// Power up radio after sleep
    	//	sendBatteryLevel(batteryPcnt);
    	//	oldBatteryPcnt = batteryPcnt;
    	//}
    
    
    }
    


  • You have a delay(10000); in the loop() function. To start I would comment that out and see if the issue is solved.
    During the delay() nothing can be done. You should use the millis() function to perform time based tasks, that won't block the loop.



  • Thanks I will give that a try.



  • This is very strange but could indicate where to look for similar problems. I dumped the mysensors gateway and node and programed the arduinos with the standard arduino Lora libary to establish a serial device on HA. This worked first time and I could get messages through, no problem. This means that the radios was at least working. Then I reprogramed the gateway and the node with mysensors serial GW and node options. The radios connected first time and I don't think I received a single NACK for two days now.
    So I can only think that there must be some radio setup parameters that are stuck in memory or something like that.

    Any ideas from someone on this?



  • same issue here. i can not pair a gw and a node.
    there are a lot of "open issues" regarding gw/node paring => something is wrong in this design, it tries to cover too many platorms but it doesn t do it in simple/good way for neither one



  • I think what is required is maybe an option to erase all memory or config if a flag is set. This will make sure that the chosen radio config will be correct.



  • @mariusl said in Gateway sends NACK to node:

    Any ideas from someone on this?

    #define MY_TRANSPORT_STATE_TIMEOUT_MS (5*1000ul)

    //#define MY_RFM95_MODEM_CONFIGRUATION RFM95_BW125CR45SF1288
    #define MY_RFM95_MODEM_CONFIGRUATION RFM95_BW125CR48SF4096

    These lines can affect. the TRANSPORT_STATE_TIMEOUT may be less than a actual message sending time. you will get constant NACK's.



  • @yury said in Gateway sends NACK to node:

    These lines can affect. the TRANSPORT_STATE_TIMEOUT may be less than a actual message sending time. you will get constant NACK's.

    I have it working fine now but I would like to make it as robust as possible. What would you suggest as a good value for the timeout?



  • @mariusl said in Gateway sends NACK to node:

    good value for the timeout?

    here are the delay examples in the docs
    https://www.mysensors.org/apidocs/group__RFM95grp.html#ga23a30185cbd40984e65d5269983bf840

    for yours #define MY_RFM95_MODEM_CONFIGRUATION RFM95_BW125CR48SF4096

    I would use #define RFM95_RETRY_TIMEOUT_MS (2000ul)

    any reason for the Spread factor SF4096 ?



  • @yury said in Gateway sends NACK to node:

    any reason for the Spread factor SF4096 ?

    Not at all. It is from example code that I found online. I don't really know what it does to be honest.



  • @mariusl said in Gateway sends NACK to node:

    what it does

    SF number is chips (chirps) needed to code each bit. SF4096 is maximum range especially in urban area, but very long delay . I tried different combinations and found below MY_RFM95_MODEM_CONFIGRUATION is pretty much good. 20 - 30% less in terms of distance and delay #define RFM95_RETRY_TIMEOUT_MS (300ul) is enoght. Much faster.

    #define MY_RFM95_MODEM_CONFIGRUATION RFM95_BW_500KHZ | RFM95_CODING_RATE_4_5, RFM95_SPREADING_FACTOR_2048CPS | RFM95_RX_PAYLOAD_CRC_ON, RFM95_AGC_AUTO_ON



  • Aah ok that makes sense. My application is for rural use and I need the max distance possible. The slow response will not be a problem as the sensors don't send a lot of data at all. So maybe I will stay with the SF4096 for now but I will do some experimenting with the settings. Just to understand them a bit better.


Log in to reply
 

Suggested Topics

7
Online

11.4k
Users

11.1k
Topics

112.7k
Posts