I’ve set up an RS485 network to control a number of remote Arduino devices. The RS485 coms line with terminators and a couple of Arduino Mega 2560’s attached are programed as slaves along the RS485 line. All of the hardware and slaves have been working fine but I noticed the packets are not always getting sent to the Slaves as expected. Open further investigation I determined the XOJO serial port being used seems to be storing up send requests and then sending them out very close together. Sometimes they get sent as expected and are fine. I tried a number of pauses and closing the port after receiving data and reopening the port before a send. The problem is very obvious when watching the serial monitor at the Arduino slaves. In the System debug log I can see data send requests and returns. One request may send 3 times several seconds apart and then finally I see them at the slave almost together. I can also send out packets with CoolTerm very quickly and receive data back as expected. I’m running out of ideas to try, any suggestions.
Have you tried calling the Flush method?
Noting special about the Code:
Public Sub SendDataToArduinoDevices(Data as string)
Try
ArduinoSerial.connect
ArduinoSerial.flush
pause(5)
ArduinoSerial.write Data + Chr(13) // Chr(13) = Carriage return. Data includes device "H," or "S,"
ArduinoSerial.XmitWait
Pause(20)
#If debugbuild Then // Removes from build
System.DebugLog("Data Out: " + Data)
#EndIf
//ArduinoSerial.Poll // Enables Arduino Serial Port to Receive
Catch error As IOException
MessageBox(“The serial connection could not be opened.”)
End Try
End Sub
So data being sent and receive may be in this order:
7:37:20 PM : Data Out: S,3,
7:37:31 PM : Data Out: S,3,
7:37:32 PM : Data In: = S,0,0,55.76,18.11,
7:37:35 PM : Data In: = S,0,0,55.76,18.09,
7:37:36 PM : Data In: = S,0,0,55.78,18.09,
7:37:42 PM : Data Out: S,3,
7:37:44 PM : Data In: = S,0,0,55.74,18.09,
7:37:54 PM : Data Out: H,0,0,2
7:38:05 PM : Data Out: S,3,
7:38:06 PM : Data In: = S,0,0,55.75,18.09,
7:38:16 PM : Data Out: S,3,
Data In: = S,0,0,55.78,18.09,
7:38:17 PM : Data In: = H,0.00,15.38,-15.38,-1,Off,Off,Off,Off,Off,Off,Off,Off,0,Valve Okay,
7:38:27 PM : Data Out: S,3,
7:38:38 PM : Data Out: S,3,
7:38:50 PM : Data Out: H,0,0,2
Data In: = S,0,0,55.78,18.08,
7:38:52 PM : Data In: = S,0,0,55.75,18.09,
7:38:53 PM : Data In: = H,0.00,15.38,-15.38,-1,Off,Off,Off,Off,Off,Off,Off,Off,0,Valve Okay,
7:39:01 PM : Data Out: S,3,
7:39:12 PM : Data Out: S,3,
7:39:23 PM : Data Out: S,3,
7:39:26 PM : Data In: = S,0,0,55.73,18.08,
7:39:28 PM : Data In: = S,0,0,55.75,18.09,
7:39:29 PM : Data In: = S,0,0,55.77,18.08,
Um… what does your Pause
method do?
Oh… call Flush
after you call Write
.
Still looks like this:
7:49:32 PM : Data Out: S,3,
Data In: = S,0,0,55.75,18.08,
7:49:48 PM : Data Out: H,0,25,1
7:49:51 PM : Data In: = H,25.00,15.31,-15.31,-1,Off,Off,Off,Off,Off,Off,Off,Off,0,Valve Okay,
Data Out: H,1,36.1,2
7:49:54 PM : Data In: = H,36.10,15.31,9.69,-1,Off,Off,Off,Off,Off,On,On,Off,96,Valve Okay,
7:50:03 PM : Data Out: H,1,36,2
7:50:05 PM : Data In: = H,36.00,15.38,20.73,-1,Off,Off,Off,Off,Off,On,On,Off,96,Valve Okay,
7:50:14 PM : Data Out: S,3,
7:50:25 PM : Data Out: S,3,
7:50:36 PM : Data Out: S,3,
7:50:38 PM : Data In: = S,0,0,55.73,18.05,
7:50:40 PM : Data In: = S,0,0,55.72,18.08,
7:50:41 PM : Data In: = S,0,0,55.74,18.05,
7:50:48 PM : Data Out: H,0,0,2
The “Pause” was nothing other than experimenting with more time after a send.
Assuming that “Pause” is Thread.Pause, it may just be stopping your port from doing anything, e.g. completing the flush.
If that pause is being done on the main thread, then that is very likely.
I believe you should do
Write, Flush, XmitWait in that order. And forgo the Pause, or use a timer instead of the Pause.
I worked a day on this issue and removed all pauses and placed the flush after the XmitWait and still had the same issue. Thinking DataReceived processing returned data may be hanging things up I remove all code from it, but didn’t help. I can watch the time stamp for data being sent and monitor it at the Arduino on the RS485 bus and it shows up 3-9 seconds later. Thinking it could be a hardware issue I went back to CoolTerm and sent the same data. Almost instantaneous send and receive. Not sure what to try next but it seems ArduinoSerial is not cooperating. Any Ideas how to divide and conquer this issue.
Current send code:
Try
ArduinoSerial.connect
ArduinoSerial.write Data + Chr(13)
ArduinoSerial.XmitWait
ArduinoSerial.flush
#If debugbuild Then // Removes from build
System.DebugLog("Data Out: " + Data)
#EndIf
ArduinoSerial.Poll
Catch error As IOException
MessageBox("The serial connection could not be opened.")
End Try
Are you using the following command every time you write anything out from Xojo.
ArduinoSerial.connect
You normally would only connect once a “session”. This command will attempt to open the port, set it up, and then make it ready to use. If the port was previously opened and not closed, then it may try to close it and then reopen it. Point is you may want to use that command only once.
Good suggestion. I placed the ArduinoSerial.connect in the open event to only open it once. Still yields a 5-9 sec delay. ???
So what I have: Data severely delayed going out on the RS485 bus but when the data is eventually received by the slave its response and XOJO receive sides acknowledgment is almost instantaneous.
I’m down to this Code for sending:
ArduinoSerial.write Data + Chr(13)
ArduinoSerial.XmitWait
ArduinoSerial.flush
#If debugbuild Then // Removes from build
System.DebugLog("Data Out: " + Data)
#EndIf
ArduinoSerial.Poll
Shouldn’t Flush be before XmitWait? And wouldn’t that make XmitWait unnecessary?
Hi Tim, Thanks for chiming in. But no change. I’m not understanding way a terminal program has no issue sending and receiving quickly but XOJO does. Could a terminal program be different in some way?
ArduinoSerial.flush
ArduinoSerial.write Data + Chr(13) // Chr(13) = Carriage return. Data incluedes device "H," or "S,"
//ArduinoSerial.XmitWait
//ArduinoSerial.flush
#If debugbuild Then // Removes from build
System.DebugLog("Data Out: " + Data)
#EndIf
ArduinoSerial.Poll // Enables Arduino Serial Port to Receive
The flush must go immediately after the write. You write something, it’ll go into tthe internal buffer, to be sent when the system feels like it. The flush causes that sending to be done NOW.
It’s useful to remember that Socket.Flush works just like Toilet.Flush: you need to do your business and then flush it.
You could try an older version of Xojo (e.g. 2019r3, 2020r2, 2021r1.1).
CoolTerm is written in Xojo
Is your RS-485 half-duplex or full-duplex? Maybe it is a hardware issue and CoolTerm’s handshaking lines are configured differently than yours.
I believe you may be on to the issue. The network is half duplex and after putting an oscilloscope on the line last night I noticed the data was leaving immediately but not registering at the slave right away. The Arduino may be buffering data for some reason. This morning I’ll see if I can echo back raw data being received by the Arduino.