RS485 transport ACK support
-
Hi all,
I see that there is no ACK functionality implemented for RS485 transport and I did first try to implement it. I'm wondering if there is someone on the forum that in some way is maintaining codebase for the RS485 transport and could look at it.
-
@rozpruwacz
Hi,- You can take a look into file history for all people which have maintained the file MyTransportRS485.cpp:
https://github.com/mysensors/MySensors/commits/development/hal/transport/RS485/MyTransportRS485.cpp - In addition, you will find in the header of this file the contact info of the original author:
- Copyright (c) 2013, Majenko Technologies and S.J.Hoeksma
- Copyright (c) 2015, LeoDesigner
- https://github.com/leodesigner/mysensors-serial-transport
- All rights reserved.
- There is a recent and still open pull request to improve the RS485 transport layer:
https://github.com/mysensors/MySensors/pull/1451
May be you contact this developer too.
- You can take a look into file history for all people which have maintained the file MyTransportRS485.cpp:
-
ACK response in implemented in RS485, I'm using it.
-
@gieemek If You are talking about ack parameter of the send function then it is not what I'm talking about. I'm talking about this:
https://github.com/mysensors/MySensors/blob/aa76d266159d87cd460597657ac7f669a706fad5/hal/transport/RS485/MyTransportRS485.cpp#L243
on line 245:(void)noACK; // not implemented
I newest API version 2.3.1 send function has parameter named echo instead of ack which makes easier to distinguish beetween transport level ack and protocol level echo request.
-
@gieemek Can you explain how do you using ACK on RS485? in my practice i see, that having no error, but lossing packets..
I mean that what construction don't working correctly:boolean MYS_send(MyMessage Msg) { boolean status = false; int counter = 3; do { status = send(Msg); if (status) { SendCount++; return status; } else { SendError++; counter--; wait(50); } } while (counter > 0); return status; }
-
@cabat, @rozpruwacz is right: I don't use the noACK function.
But I do use send(msg) function with an echo parameter set to true, which forces the gateway to send echo back to node.
How it works:- When the node starts sending message, the variable isSent is set to false.
- The node's send(msg) function runs in a loop for up to 5 repetitions unless the isSent variable changes to true. The function repeats sending message every 1 second.
- The receive() function on the node reads the messages from the gateway. If it is is.Echo() it sets the isSent variable to true. This interrupts the loop with send(msg) function.
Important ! you need to wait about 0,5 s after sending message to get echo back from gateway.
bool isSent; void loop() { // your other code in loop() function isSent = false; while ( ! isSent && i < 5 ) { send( message.set( value ), true ); wait( 500 ); if ( ! isSent ) { wait( 1000 ); } i++; } // your other code in loop() function } void receive( const MyMessage& message ) { if ( message.isEcho() ) isSent = true; else doSomething; }
-
@gieemek thanks, this is a good idea! I was thinking about something similar..
-
@gieemek Great thanks for you solution, it's work perfect!!
I just change the timeout for resend message to 250ms.
Using now in 6 my RS485 nodes.
-
Nice idea @gieemek, I will definitely implement something similar. But what about the gateway? I often experience problems when sending messages to multiple nodes at a time through Home Assistant.
-
I don't know how to add additional script to gateway sketch. Maybe someone else from MySensors community could help.