Jump to content

Writing multiple commands to serial


Kubo

Recommended Posts

Ill try to explain this as best as I can.

This is probably real simple...

I need to enter about 20-30 commands into the serial (rs-232). I am able to have 1 command issued and have it display the way I want it to and when I want it. But when I try to do more than that doesnt work right. Is there an easier way to do this?

Thank you

Link to comment

What is controlling the flow or sequencing between your writing to the serial port and reading from it? From the looks of your diagram you are continually reading from the serial port. This will prevent your from writing to it at the same time. You should allow your application a chance to write data. You could put logic in your read loop which will only read data when data is available. Also, do you really need to read your data every 10 ms? I suspect that that loop is starving out the rest of your application and preventing you from writing data when you want.

Link to comment

QUOTE (Mark Yedinak @ Feb 27 2009, 05:23 PM)

What is controlling the flow or sequencing between your writing to the serial port and reading from it? From the looks of your diagram you are continually reading from the serial port. This will prevent your from writing to it at the same time. You should allow your application a chance to write data. You could put logic in your read loop which will only read data when data is available. Also, do you really need to read your data every 10 ms? I suspect that that loop is starving out the rest of your application and preventing you from writing data when you want.

Thank you, but this does't answer my question at all.

Like I said, I am just trying to write multiple commands. It works otherwise.

Yes I would like it to stay at 10ms for now, until I figure out the timing thing later

Link to comment

We cant answer when we dont have all the information, you have to narrow it down for us to provide you with an accurate answer.

As Mark requested, what is controlling the flow on the serial port. When you write once, do you get an acknowledge then data, or does the data just come back right away. Is there a delay in sending the data back?

It would also help to move the serial configure port to outside the loop or at least out of your read/write state. This MIGHT bog down the reading/writing, and is not necessary to do each loop.

Link to comment

When I write a command to the port (in this case "nc") I get a network configurations display instantly out of the same port.

I could do the same with different commands and it will display instantly.

Normally when we do this manually we use hyperterminal or Teraterm and say for instance we enter "nc d1", it will display the network configurations for device 1, or when we enter "ncs" it will display "network configurations saved". The commands that we are changing will be in the network configurations, so we will need to enter a series of commands... i.e. "nc d1 e 00:00:00:00:00:01" or "nc d6 i 123.456.789.000". After entering each command it will display that device with the setting that it was changed to.

Not really sure I know what you mean by controling the flow.

Link to comment

It looks to me like you are reading back too fast. I don't think you're giving the other unit time to respond. I normally poll the bytes at port until it is non-zero and then read everything there. It's kind of lame that NI doesn't include this in their library. Some instruments can't accept the next command until the first reply is sent out. You don't mention what the symptoms are except that it "doesn't work right" and you say how it should work. Anyway, if you don't feel like adding a polling loop, just add a half-second delay between the write and the read and see if that helps.

Good luck.

Link to comment

You just described it. Your situation is basically a command/response system. However, your code is not written that way. Your code (the original picture you posted) has a loop continually reading at a very high frequency and a parallel loop that is trying to write data. What you need to do is sequence your actions such that you send a command and then read the response. After the response is read you should then send the next command, read its response and so on. There are different ways you can use to terminate your read. It really depends on the data you are getting back. If the data has some unique "end of data" marker you can read until you see this marker. Or your responses may always be a specific length. In which case you need to read the specific number of bytes before continuing. Another way that might work is that you know your device will always send the complete response in a certain amount of time. If this is the case, and the time is short enough you could attempt to read a large number of bytes, a number larger than your biggest response, and set a timeout value slightly longer than the maximum response time. Your worst case is when you can receive a variable amount of data with no termination value in an unspecified or long response time. In this case you need to read a single character with timeout value. Once you read a single character you begin reading as much data as you can and stop reading data once you have some specified period with no data. This timeout is relatively short compared to the overall data timeout. It also assumes that once the device responds it will send all of the response with no significant delays between the characters.

Parallel processing is a great thing but just because you can do it doesn't mean that you should. Based on your last post I don't think your architecture is the right one for your task. You can still use the producer/consumer model for handling events but the basic operations of your task could occur in a single state machine. This state machine would correctly sequence your applications writing and reading from the devices. Currently you have no flow control between your writing and reading of the serial port and I believe this is what is causing you your problems.

Not to sound nasty or anything but based on many of the questions you have been posted I would highly recommend that you try to take some formal LabVIEW training classes. For example I think you could benefit greatly from taking the Basics I and II classes.

Link to comment

No offence taken at all. I am extremely new at this and I am just trying to learn, so I am taking all the pointers I can take. I have scheduled a couple training classes but they start next month.

I guess I should have specified exactly what was not working correctly, I applologize.

The reason why I have done it this way was because the characters in this terminal act as a tracker to the units activities during the process. What this is ulimately going to be doing is loading software. It streams data out of the serial port extremely fast, so that is why the timing to that loop is set very low. If it was set any higher the data recieved would start backing up... when I turn off the unit, it will still display an output for some time... depending on how long I had the power on.

Ill send a few examples of what I have tried but these are to better explain what I am trying to do, I thought when I was doing it that it wouldnt work but I thought I would give it a shot.

Link to comment

What appears to be missing in the above picture is what controls the completion of your read. The code that you have now is only going to read the number of bytes reported by the VISA connection that are available at that one specific point in time. So, you say that your device will be sending lots of data back and what is probably happening is that the VISA connection is reporting some number lower than the total data that should be returned. In essence you haven't read all of the data that you want. As jdunham mentioned your device may not be capable of taking another command until all of the data from the previous one has been read. You need to know when and how to finish reading data before going onto the next step.

Link to comment

QUOTE (Mark Yedinak @ Feb 27 2009, 01:01 PM)

What appears to be missing in the above picture is what controls the completion of your read. The code that you have now is only going to read the number of bytes reported by the VISA connection that are available at that one specific point in time. So, you say that your device will be sending lots of data back and what is probably happening is that the VISA connection is reporting some number lower than the total data that should be returned. In essence you haven't read all of the data that you want. As jdunham mentioned your device may not be capable of taking another command until all of the data from the previous one has been read. You need to know when and how to finish reading data before going onto the next step.

Right. Your code checks the number of bytes right after the write. Note that that Write does not guarantee that those bytes have reached your instrument. In fact all that happens is that the bytes are delivered to the serial hardware driver running under windows, which delivers them to the UART chip attached to your motherboard which puts the bits out on the serial TX pin. Your outbound message is about 20 characters, and it's 10 or 11 bit-times per character, so at 38400, it's going to take 5ms just to send out the message on the TX pin, not including the driver stuff before that (which is probably plenty fast). So then your target device has to receive that data, be sure that it's over, process the command, and send some response. If all of that happens within 25ms, then it's a pretty fast device. No way it is going to be faster than 10ms.

So your code checks the number of bytes answering right away, long before the message is even starting to transmit, much less getting a response back. try to add a 100-500ms delay in a sequence structure right between the read and the NumBytesAtPort and see if you get some improvement

Good luck.

Link to comment
  • 5 weeks later...

If you were previously using hyper-terminal then your messages are probably line feed terminated.

Make sure that the serial init is set to use a terminator and the term char is 0xA. Don't bother with the bytes at serial port property node and wire a huge number (say 1024) to the bytes to read of the Visa read.vi. The number has to be big enough to receive your longest message and don't worry......the read will automagically return on the term char if its less.

There is a serial example in Labview. "National Instruments\LabVIEW 8.2\examples\instr\smplserl.llb". Notice they don't use the bytes at serial port!

Link to comment
  • 2 weeks later...

Sorry to hijack, but just a question on serial termination characters.

I have a device which I have to communicate with over a serial interface. The messages (both sent to and recieved from) the device are framed with the byte 0xC0 (i.e. I send/recieve a byte array that looks like C0010101010101C0, where 010101010101 is my message). Is there a way to Labview to automatically read back only the one message? i.e. something similar to using the "term char" method ShaunR mentions above?

At the moment, I read back byte by byte until I've seen both the start and stop 0xC0 bytes... but my code would be neater and possibly more efficient if I didn't have to....

Just a thought.

Thanks for any info.

Paul

Link to comment

QUOTE (Ic3Knight @ Apr 10 2009, 10:26 AM)

Sorry to hijack, but just a question on serial termination characters.

I have a device which I have to communicate with over a serial interface. The messages (both sent to and recieved from) the device are framed with the byte 0xC0 (i.e. I send/recieve a byte array that looks like C0010101010101C0, where 010101010101 is my message). Is there a way to Labview to automatically read back only the one message? i.e. something similar to using the "term char" method ShaunR mentions above?

At the moment, I read back byte by byte until I've seen both the start and stop 0xC0 bytes... but my code would be neater and possibly more efficient if I didn't have to....

Just a thought.

Thanks for any info.

Paul

You could read the data in chunks and then add that to a buffer of data to be processed in a separate task. This task could then parse the data using regular expressions to pick off the messages from the beginning of the buffer. Once it gets a complete message it could either process it immediately or pass that off to your message handler. It can continually do this as long as data is available.

Link to comment

QUOTE (Ic3Knight @ Apr 10 2009, 07:26 AM)

At the moment, I read back byte by byte until I've seen both the start and stop 0xC0 bytes... but my code would be neater and possibly more efficient if I didn't have to....

Seems like you could set 0xC0 as the termination character, and then every other message would be empty, and you would ignore them.

Link to comment

QUOTE (jdunham @ Apr 10 2009, 06:01 PM)

Seems like you could set 0xC0 as the termination character, and then every other message would be empty, and you would ignore them.

Would that affect my writing to the device? If I send 0xC0 and that's the termination character, does it still get sent (my device is expecting a message framed with the byte 0xC0...)?

Cheers

Paul

Link to comment

QUOTE (Ic3Knight @ Apr 11 2009, 09:11 AM)

Would that affect my writing to the device? If I send 0xC0 and that's the termination character, does it still get sent (my device is expecting a message framed with the byte 0xC0...)?

Cheers

Paul

Using termination characters requires that a received message doesn't contain the character (otherwise you would return 1/2 way through a message). From your example, you only send 0x01's and 0x00's so jdunham is correct in that you can safely use 0xC0 as a term char for reading.

Sending is different in that when you initialise using the VISA Configure Serial port vi, it does not set the termination char for writing (take a look inside, you could change that if you wanted to), rather, it sends the string you wire to it and terminates immediately once sent regardless of the characters in the string.

So the short answer is yes 0xC0 would still get sent if you wired the term char 0xC0 to VISA Configure Serial port vi since the term char only affects reading.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.