mysensors / MySensors

MySensors library and examples
https://www.mysensors.org
1.31k stars 891 forks source link

RFM69HW issues when sending messages (2.3.1 version) #1367

Open ricgyver opened 4 years ago

ricgyver commented 4 years ago

I have a problem with the latest release of the MySensors library. I have a RPI3 as a gateway and several sensors with RMF69 radios. With the old version (2.2.0) everything worked fine.

Now I've started the update process to have all the same version in all my nodes and gateway. So far the nodes with non RFM69HW are working ok. All messages are correctly sent and send return true.

The problems come out with the RFM69HW radios. I've a node with such a radio and when it sends any message, it reaches the gateway correctly, but send return false 90% of times. Since I've implemented a routine that tries 5 times to send a message if it returned false, it translates in many messages sent to the gateway.

Again, they are correctly delivered to to gateway but on the node the send routine returns false. This does not happen with RFM69CW radios.

I've read similar messages so far but not yet a clear solution. Someone (in particular @tekka007) could help me?

Thanks in advance!. bye

ricgyver commented 4 years ago

some debugging in these days. I moved to the latest development release. It seems that ACK is always requested even if I set false in the send() routine. Indeed, in MyTransport.cpp we have const bool noACK = _transportConfig.passiveMode || (to == BROADCAST_ADDRESS); So it seems the user choice is disregarded by such a line. By modifying the code as bool _messACK=message.getRequestEcho(); const bool noACK = !_messACK || _transportConfig.passiveMode || (to == BROADCAST_ADDRESS); I have that messages correctly sent to the gateway result in TRUE by the send() routine, as it should be.

So this seems to have solved my problems with messages correctly sent but returning false from send().

mfalkvidd commented 4 years ago

@ricmail85 I don't know about rfm radios, but the parameter to send() requests that the receiving node echoes back the same message. It has nothing to do with ack. Not for rfm, not for nrf, not for any transport method.

See https://github.com/mysensors/MySensors/issues/1103 for more information about the confusion between echo and ack.

ricgyver commented 4 years ago

@mfalkvidd Thanks for your answer. I understand your point. But looking at the MyTransport, it seems the user request (ask a reply to the GW or not) is bypassed currently in the code. That's why I've proposed to modify that line in the code. What do you think about? Thanks in advance

tekka007 commented 4 years ago

@ricmail85 As @mfalkvidd pointed out, you're confusing ECHO and ACK, which are two unrelated features:

But looking at the MyTransport, it seems the user request (ask a reply to the GW or not) is bypassed currently in the code.

The echo request (=what you refer to as "user request (ask a reply to the GW or not)" is set in the message header and remains unaltered thereafter: https://github.com/mysensors/MySensors/blob/development/core/MySensorsCore.cpp#L337

The ack request (=hardware ACK request) is set by default, unless the passive mode is enabled or the message is broadcasted: https://github.com/mysensors/MySensors/blob/development/core/MyTransport.cpp#L981

The modification you suggested

bool _messACK=message.getRequestEcho(); const bool noACK = !_messACK || _transportConfig.passiveMode || (to == BROADCAST_ADDRESS);

most probably masks the hw ACK reception problem you encountered, i.e. send() returns false. If you enable the RFM69 verbose debug output, you may see hints pointing to that.

ricgyver commented 4 years ago

@tekka007 thanks for your explanation. I didn't get the difference between echo and ack. So I need further debugging to understand why with RFM69H(C)W I don't get ack by the gateway (although the message correctly reached it) while with non RFM69(C)W radios everything works good...

tekka007 commented 4 years ago

@ricmail85 Maybe you forgot to enable MY_IS_RFM69HW, this is necessary for correct radio power settings when using HW models. See the documentation: https://www.mysensors.org/apidocs-beta/group__RFM69SettingGrpPub.html#gab5f5a149775157120286e21c4cd2b770

ricgyver commented 4 years ago

@tekka007 thanks for your reply. This statement was already included because it was a sketch already working with the old library version.

I had to go back to the 2.2.0 version with all my nodes and gateway. This is the only way to get everything working well. I saw there are many differences (between 2.2.0 and 2.3.2) in the new Rfm69 drivers so probably the cause of malfunctioning is there. At least in my case. With 2.2.0 no problems at all both with HW and non HW versions of the radio.

dekiesel commented 4 years ago

I am experiencing the same issue I think.

I have one arduino+rfm69hw as a Node and two gateways.

The Node runs a signal scanner sketch and reports rssi and TXPowerLevel.

Gateway A is a raspberry pi 4+rfm69hw. Gateway B is a serial gateway (pro mini 3v + rfm69hw).

The node has no problems sending to Gateway B: The rssi is good and the power level is 0.

When the node tries to send to Gateway A (the pi) then the rssi goes up to 80-90 and the power level climbs to 100.

This is how I compiled Gateway A (mysensors 2.4 alpha)

./configure --my-transport=rfm69 --my-rfm69-frequency=868 --my-gateway=mqtt --my-is-rfm69hw --extra-cxxflags="-DMY_DEBUG_VERBOSE_RFM69 -DMY_DEBUG_VERBOSE_RFM69_REGISTERS" --my-controller-ip-address=127.0.0.1 --my-mqtt-publish-topic-prefix=mysensors-out --my-mqtt-subscribe-topic-prefix=mysensors-in --my-mqtt-client-id=mysensorsgateway1 --my-mqtt-user=mysensors --my-mqtt-password=redacted --my-port=1883

This is the log of Gateway A: mysgw.log

And this is the log of the Node when sending to gateway A: node.log

For completeness sake: here is the sketch of Node A:

// Enable debug prints
#define MY_DEBUG
#define MY_DEBUG_VERBOSE_RFM69 
//#define MY_DEBUG_VERBOSE_RFM69_REGISTERS
#define MY_SIGNAL_REPORT_ENABLED

#define MY_NODE_ID 3

// Enable and select radio type attached

// RFM69
#define MY_RADIO_RFM69
#define MY_RFM69_NEW_DRIVER   // ATC on RFM69 works only with the new driver (not compatible with old=default driver)
#define MY_IS_RFM69HW
//#define MY_RFM69_ATC_TARGET_RSSI_DBM (-70)  // target RSSI -70dBm
//#define MY_RFM69_MAX_POWER_LEVEL_DBM (10)   // max. TX power 10dBm = 10mW

// RFM95
//#define MY_RADIO_RFM95
//#define MY_RFM95_ATC_TARGET_RSSI_DBM (-70)  // target RSSI -70dBm
//#define MY_RFM95_MAX_POWER_LEVEL_DBM (10)   // max. TX power 10dBm = 10mW

#include <MySensors.h>

// ID of the sensor child
#define CHILD_ID_UPLINK_QUALITY (0)
#define CHILD_ID_TX_LEVEL       (1)
#define CHILD_ID_TX_PERCENT     (2)
#define CHILD_ID_TX_RSSI        (3)
#define CHILD_ID_RX_RSSI        (4)
#define CHILD_ID_TX_SNR         (5)
#define CHILD_ID_RX_SNR         (6)

// Initialize general message
MyMessage msgTxRSSI(CHILD_ID_TX_RSSI, V_CUSTOM);
MyMessage msgRxRSSI(CHILD_ID_RX_RSSI, V_CUSTOM);
MyMessage msgTxSNR(CHILD_ID_TX_SNR, V_CUSTOM);
MyMessage msgRxSNR(CHILD_ID_RX_SNR, V_CUSTOM);
MyMessage msgTxLevel(CHILD_ID_TX_LEVEL, V_CUSTOM);
MyMessage msgTxPercent(CHILD_ID_TX_PERCENT, V_CUSTOM);
MyMessage msgUplinkQuality(CHILD_ID_UPLINK_QUALITY, V_CUSTOM);

void setup()
{
}

void presentation()
{
  // Send the sketch version information to the gateway and controller
  sendSketchInfo("ATC", "1.0");

  // Register all sensors to gw (they will be created as child devices)
  present(CHILD_ID_UPLINK_QUALITY, S_CUSTOM, "UPLINK QUALITY RSSI");
  present(CHILD_ID_TX_LEVEL, S_CUSTOM, "TX LEVEL DBM");
  present(CHILD_ID_TX_PERCENT, S_CUSTOM, "TX LEVEL PERCENT");
  present(CHILD_ID_TX_RSSI, S_CUSTOM, "TX RSSI");
  present(CHILD_ID_RX_RSSI, S_CUSTOM, "RX RSSI");
  present(CHILD_ID_TX_SNR, S_CUSTOM, "TX SNR");
  present(CHILD_ID_RX_SNR, S_CUSTOM, "RX SNR");
}

void loop()
{
  // send messages to GW
  send(msgUplinkQuality.set(transportInternalToRSSI(_transportSM.uplinkQualityRSSI)));
  send(msgTxLevel.set(transportGetTxPowerLevel()));
  send(msgTxPercent.set(transportGetTxPowerPercent()));
  // retrieve RSSI / SNR reports from incoming ACK
  send(msgTxRSSI.set(transportGetSendingRSSI()));
  send(msgRxRSSI.set(transportGetReceivingRSSI()));
  send(msgTxSNR.set(transportGetSendingSNR()));
  send(msgRxSNR.set(transportGetReceivingSNR()));
 //to serial
 Serial.print("transportInternalToRSSI(_transportSM.uplinkQualityRSSI): "); Serial.println(transportInternalToRSSI(_transportSM.uplinkQualityRSSI));
 Serial.print("transportGetTxPowerLevel(): "); Serial.println(transportGetTxPowerLevel());
 Serial.print("transportGetTxPowerPercent(): "); Serial.println(transportGetTxPowerPercent());
 Serial.print("transportGetSendingRSSI(): "); Serial.println(transportGetSendingRSSI());
 Serial.print("transportGetReceivingRSSI(): "); Serial.println(transportGetReceivingRSSI());
 Serial.print("transportGetSendingSNR(): "); Serial.println(transportGetSendingSNR());
 Serial.print("transportGetReceivingSNR(): "); Serial.println(transportGetReceivingSNR());
 Serial.println("Waiting");
  // wait a bit
  wait(10000);
}

I am sure it's not the rfm69hw module because I used the same module on both gateways.

Let me know if I can help debug this any further.

ricgyver commented 4 years ago

I have a raspberry as gateway. But problems happen only with the latest version of the MySensors code. With 2.2.0 everything works fine

SimoneBnc commented 4 years ago

Could it be another timing issue like there was on 2.2 when I was updating FW OTA?

ricgyver commented 4 years ago

I cannot answer. For sure I've seen many differences in the driver files of the Rfm69 radios with respect to the 2.2.0. I've tried to debug as much as I could but without success