views:

93

answers:

4

I have struggled with this for a long time, and I did get a solution working eventually but it wasn't pretty, and I am hoping to gain a little wisdom from the stackoverflow community about how this should be done.

Basically I am working with motors that connect to the computer using a daisychained USB connection and I have to communicate with them using the SerialPort class in .Net and it goes through some driver installed on the computer to talk with the motors over USB.

The problem is that the motors are daisy chained, and when I ask

for information from one, or tell it to do something, i have to wait on the result to come back before doing something else with that motor or with any of the others.

I've just had a generally hard time with it, and I'm sure there are better ways of working with serial communication that I've just never been exposed to. Are there any good guidelines or best practices for this kind of thing? Is this a fairly standard thing to do be doing (serial communication -> usb via a driver installed on computer)

I'm working with six of the MDrive23Plus Motion Control motors from IMS.

I can provide plenty more details, but I'm not really sure where this will lead. I hope this is specific enough for StackOverflow, though I know it is sort of vague. I just don't really know how to ask it any better.

Really what it comes down to is how do I synchronize communication effectively, and how do I wait and read the data coming back effectively? I know this is probably very simple to some people, but it just hasn't been working well for me.

+1  A: 

You might need multiple threads and/or asynchronous operations. In the past, when doing serial comms (not in .NET), we would queue up reads on the port(s). When a read would complete, the callback function (delegate) would fire, the processing of the read would be carried out, potentially changing the control state - our typical example was a barcode read, while simultaneously having a keyboard read and a timer. One of the events would complete, which would cause an action (potentially leaving the other queued reads in place or cancelling them, depending on what the state was moving to.)

You might want to look into using state machine(s). In this case, the state machine knows what operations are going on, which transitions are allowed and how to get between them and what actions the transitions cause.

Cade Roux
+2  A: 

this is the limit of working multi drop serial networks.....there is no magic to it, you can ease some of the pain

Generally the best approach is to put in an abstraction layer where you have a message queue of things you want to send, and each of those have a callback that gets called when it gets a response.

Keith Nicholas
+1  A: 

I work for Zaber Technologies, and I built a control library for our precision stepper motor controllers that communicate over a daisy-chained serial connection. I used three layers:

  1. The port - this layer is just concerned with the communication protocol. It exposes methods for sending a message, and it converts the message parameters into a byte stream. It also listens on the incoming line, converts the byte stream into a message structure, and raises an event when the complete message has been received.
  2. The device - this layer knows how to send messages to a specific device in the daisy chain and how to filter out responses from other devices in the daisy chain.
  3. The conversation - this layer coordinates requests and responses and lets calling code make a request that will block the thread until a response comes back.

Calling code then has the choice of whether to use synchronous requests with the conversation layer, or use asynchronous requests with the device layer.

If you're interested in more details, you can download the source code or look at the user documentation that talks about writing scripts against the library.

Don Kirkby
+1  A: 

Many devices are fickle on their serial comms. There are devices whose comms cannot behave properly with a line read at the baud rate they specified.

I find that I have to characterize the comms of a device. There are vendors where the comms characteristics of two devices of the same model are different. Characterization is a rather tedious affair. Characterization involves discovering various combination of situations and then think of the possibilities.

  1. the lowest threshold number of bytes read/written continuously before inserting a delay. The possibility is one character at a time.
  2. the safest least delay before resuming a read/write.
  3. the variation of minimum delay required from initialising comms till steady state comms.
  4. the variation of threshold number of bytes writable at specified baud before inserting a delay.

The worst case scenario is a proliferation of states/combinations of possibilities influencing the cleanliness of the read/write operations and you reduce the number of states by compromising to use the slowest common denominator among groups of read/write operations. There must be a science behind all this but I just try my voodooistic best using brute force testing.

Which, of course, would lead to having a read/write layer separating the routines needing communication from directly communicating with the port.

Alternatively, we all know the quick and lazy but inefficient way is inserting a 10 ms wait after every byte.

Blessed Geek