How to work effectively with devices through a serial connection?

I struggled with this for a long time, and eventually I got a solution, but it was ugly, and I hope to get a little wisdom from the stackoverflow community on how this should be done.

Basically, I work with motors that connect to a computer using the built-in USB connection, and I have to communicate with them using the SerialPort class in .Net, and through some driver installed on the computer, it talks to the motors via USB.

The problem is that the motors are connected in series, and when I ask

for information from one or tell him to do something, I need to wait until the result returns before doing anything else with this engine or with any other.

I just did not have enough time, and I am sure that there are more effective ways to work with serial communication, which I have never encountered. Are there any good recommendations or recommendations for this kind of thing? This is a pretty standard thing to do (serial communication β†’ usb through the driver installed on the computer).

I work with six IMS MDrive23Plus Motion Control engines .

I can provide more details, but I'm not sure if this will result. Hope this is specific enough for StackOverflow, although I know this is kind of vague. I just don’t know how best to ask.

In fact, what does this apply to, how to synchronize communication efficiently and how can I wait and read data efficiently? I know this is probably very simple for some people, but it just doesn't work well for me.

+6
serial-port
source share
5 answers

You may need multiple threads and / or asynchronous operations. Previously, when you ran serial commands (and not in .NET), we stopped reading in the queue on the ports. When the reading is completed, a callback function (delegate) will be executed, the reading processing will be performed, which could potentially change the control state - our typical example was read by a barcode, simultaneously with reading the keyboard and a timer. One of the events will end, which will lead to action (potentially leaving the other queued reads in place or canceling them, depending on what the state is headed for.)

You might want to explore the use of state machines. In this case, the state machine knows what operations are performed, what transitions are allowed, and how between them and what actions cause transitions.

+1
source share

this is the limit of working multi-channel serial networks ..... no magic, you can alleviate some of the pain

Typically, the best approach is to add an abstraction layer, where you have a queue of messages about the things you want to send, and each of them has a callback that gets called when it receives a response.

+2
source share

I work for Zaber Technologies , and I built a control library for our precision step controllers that exchange serial connection data with serial connection, I used three layers:

  • Port - this layer is simply connected to the communication protocol. It provides methods for sending a message and converts the message parameters to a stream of bytes. It also listens for the incoming string, converts the byte stream into a message structure, and raises an event when a full message is received.
  • Device - this level knows how to send messages to a specific device in the sequence chain and how to filter responses from other devices in the chain.
  • Conversation - this layer coordinates requests and responses and allows the calling code to make a request that will block the flow until the response returns.

Then the call code has a choice: whether to use synchronous requests at the conversation level or to use asynchronous requests at the device level.

If you are interested in more detailed information, you can download the source code or see the user documentation that says about writing scripts in the library.

+1
source share

Many devices are intermittent in their serial communications. There are devices whose messages cannot behave correctly with a string read at the baud rate indicated by them.

I find that I need to characterize the communication of the device. There are suppliers in which the communication characteristics of two devices of the same model are different. Characterization is a rather tedious affair. Characterization involves finding different combinations of situations, and then thinking about opportunities.

  • smallest threshold number of bytes that is read / written continuously before inserting a delay. Opportunity - one character at a time.
  • safest least delay before resuming read / write.
  • changing the minimum delay required from initializing the comm to a steady state.
  • changing the threshold number of bytes written to a given baud before inserting a delay.

The worst-case scenario is the propagation of states / combinations of features that affect the readability of read / write operations, and you reduce the number of conditions by jeopardizing the use of the slowest common denominator among groups of read / write operations. There should be a science behind all this, but I'm just trying my best to use voodooistic, using brute force testing.

Which, of course, will lead to the fact that the read / write level will be separated by routines requiring communication from direct communication with the port.

Alternatively, we all know that a quick and lazy but inefficient way is to insert 10 ms after each byte.

+1
source share

I have also been using the .net serial port class since 2004, I agree that machines with state machines probably go here, that together with sending a command, then wait for the corresponding answer in a handshake (the device will answer when it is ready to answer).

Consider your serialPort.DataReceived() event handler as your interface. then DataReceived to do BeginInvoke() , not Invoke (), since the serial port is an asynchronous interface to the method, AddReceive() next, in AddReceive() count the number of bytes that it sees if more than 0, then add data to the container stringbuilder, say, sbReceived finally starts a timer handler to collect any "remaining" data in the stream, where it also executes the beginInvoke method according to the method, ReadData() we are now ready to analyze the data and proceed to display the terminal (it is best to use the richtext field here) color code - various cod Key to specify β†’ output data <<data, configuration, error, status because you have different ports for monitoring and I / O on each of them, you can do it within the same terminal.

I agree that the state machine is a good idea, the process is very large anyway; you expect serial1 output processed according to what you need before sending serial port commands to other ports. doing it this way will be organized, and the various serial port operations will be well separated. in another case, when you may have several subsequent commands / requests and device response cycles, it may be better to do while(serial1.ByteCount==0){}; between them to allow the device to control the response time in a handshake. It can also be useful to plug in a digital debug I / O device so that you can switch the line to track latency and monitor DSOs to make sure synchronization requirements are met.

finally, make sure you clear your port every time you write / read so that there are no problems with overflow, as well as reinitializing data buffers, builder containers, etc.

To have a good day

+1
source share

All Articles