LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

OMG! I might have to use 'bytes at port'. How do I read EOT and ENQ serial transmission

Solved!
Go to solution

My current project is to communicate with a SIC dot marker. The comms are pretty simple and the marker uses CR & LF as termination characters for its responses to commands.

I send 'RUNcrlf'

It returns 'RUN OKcrlf'

When the marker finishes marking it then also sends EOT and ENQ control characters

 

There is no termination character following the last transmission so the code hangs until timeout.

I have attached an image of realterm performing the sequence above.

 

Either I change the termination character to ENQ when I know the marker is running (if its possible) or I go back to using 'bytes at port' to set the byte count. Responses are not always instant from the marker (for example when requested to load a file) so using a very short timeout would probably lead me into trouble somewhere down the line.

 

If anyone knows how to deal with the EOT and ENQ or what I use to set the termination character I would appreciate it. For now I will use 'bytes at port' to keep the job moving.

0 Kudos
Message 1 of 16
(2,117 Views)

It's always fun to emulate a terminal program.  So the flow is send a command with termination chars, get some running messages with termination chars, then it ends with EOT?  Sorry, I'm not familiar with this instrument.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
0 Kudos
Message 2 of 16
(2,079 Views)

This sounds like the protocol is inconsistent on the device side.

 

I would suggest splitting up the communication layers with a Producer/Consumer. Have the producer continuously read the raw data from the line into a buffer and use the consumer to sort out the communication protocol. In the consumer you can then check both for crlf and EOT/ENQ and treat them as termination signals and have it emit the complete messages from there.

0 Kudos
Message 3 of 16
(2,062 Views)
Solution
Accepted by topic author STTAndy

@STTAndy wrote:

Either I change the termination character to ENQ when I know the marker is running (if its possible)


Here are 3 ideas I just came up with (in no particular order):

 

1. You can change the termination character with a simple VISA Property Node (Message Based Settings->Termination Character).  So you send the command, you get the proper response (be sure to throw an error if you don't get the OK message back), set the termination character to ENQ, wait for the response to come in, and then set the termination character back to a Line Feed.

 

2. You could use the Bytes At Port to just see if data has come in in a loop (check every X ms for up to Y seconds).  If you are expecting the EOT and ENQ, then just read 2 bytes where there is anything in the port and verify what you read.

 

3. In one application, I had to tell my serial terminal to change to "Binary Mode" where it turned off the termination character and then just dumped everything to a file and my main loop (the device was sending me a ton of data on command that I then had to analyze).  The main loop could then search for the specific byte combination telling me the data was done and then tell the serial terminal to go back to "ASCII Mode".

 

I would need to know a lot more about your architecture before I could make and further recommendations.  Given the current state of my serial terminal library, I would probably go with changing to "Binary Mode" (would require the least amount of changes to my library).  For what I see most people have, I would probably recommend option 2.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 4 of 16
(2,056 Views)

@STTAndy wrote:

My current project is to communicate with a SIC dot marker. The comms are pretty simple and the marker uses CR & LF as termination characters for its responses to commands.

I send 'RUNcrlf'

It returns 'RUN OKcrlf'

When the marker finishes marking it then also sends EOT and ENQ control characters

 

There is no termination character following the last transmission so the code hangs until timeout.

I have attached an image of realterm performing the sequence above.

 

Either I change the termination character to ENQ when I know the marker is running (if its possible) or I go back to using 'bytes at port' to set the byte count. Responses are not always instant from the marker (for example when requested to load a file) so using a very short timeout would probably lead me into trouble somewhere down the line.

 

If anyone knows how to deal with the EOT and ENQ or what I use to set the termination character I would appreciate it. For now I will use 'bytes at port' to keep the job moving.


Oh,  after Googling SIC, reading their web pages and then trying to get their documentation (I hate it when they require an account to download manuals)  As an aside, next time add a link to the device pages.

 

I see what you have to contend with.  Essentially,  the Run command is followed by a properly terminated response then the SIC just starts marking.  EOT ENQ is then sent when operation is complete.

 

So, you simply need to treat this case like a Wait on OPC!  That is your Mark and Wait.vi should Query Run and if Run OK is seen enter a loop to read 1 byte (not bytes at port) with a short timeout ignoring timeout errors until 1 of 3 exit conditions exist; A) Normal: ENQ is seen "marking complete" success! B) some ungodly time elapsed Communications failure! Like some idiot pulled the USB cable or blew a fuse. C) User Aborted: like somebody closed the application (you never let them see the abort button though right?)


"Should be" isn't "Is" -Jay
0 Kudos
Message 5 of 16
(2,033 Views)

Like JpB said, you don't actually need Bytes at Port. Just try to do a read of 1 character with a short timeout, then repeatedly poll it. If you call Read, it'll return whenever it gets the termchar OR times out OR fills the buffer, so you can just say Read and let it time out. Say your timeout is 100ms; you can let it try to read 1 character 30 times. If it returns no characters after 30 tries (or 3 seconds), then it's a "real" timeout.

 

Yes you could do the same with Bytes at Port, but then you just check characters, then if there are some, you still have to call Read. Doesn't save a lot of effort, but it might be a little clearer what the intent behind the code is.

 

To repeat, VISA Read will NOT return a timeout error if it's set to termchar/1 character and you receive that character. Termchars are not mandatory for reading when the port is set to Termchar mode.

 

(Also, sorry you're having to deal with a poorly-formatted serial stream. I've been there and it's no fun.)

0 Kudos
Message 6 of 16
(2,026 Views)

@BertMcMahan wrote:

Like JpB said, you don't actually need Bytes at port

 

(Also, sorry you're having to deal with a poorly-formatted serial stream. I've been there and it's no fun.)


Not really badly formatted.  The device marks parts from marking files in on-board memory.  So, the delay between Run OK and completion of marking is unknown.   Rather than whip itself into a frenzy like a Chatty Cathy the device simply starts marking.  Suppose the mark run contains three files to mark... call them, LOGO_SZx, FWID_MajMin, and DATE_Code.  Send Run and I'd bet a doughnut the response is

EOT <when the logo is marked> EOT <when the firmware version is marked> and EOT ENQ <when the date code is marked.>

 

Actually,  nicely done by SIC!

 

[And, it's a "Þ", alt+0222 win and LongPress T Android]  My Alias sounds like "Jay Thornby" 😀


"Should be" isn't "Is" -Jay
0 Kudos
Message 7 of 16
(2,018 Views)

Ah my apologies JÞB. Didn't know that the Þ symbol was a thing. I thought it was a stylized p that I couldn't type 🙂

 

Anyway, as someone with lots of time spent with designing various serial protocols, why is it a good thing that they send EOT and ENQ with no termchar? It seems to me that it's always better to terminate all messages with a termchar (like send EOT /r or whatever) but I'm willing to learn 🙂

0 Kudos
Message 8 of 16
(2,008 Views)

@BertMcMahan wrote:

 

 

Anyway, as someone with lots of time spent with designing various serial protocols, why is it a good thing that they send EOT and ENQ with no termchar? It seems to me that it's always better to terminate all messages with a termchar (like send EOT /r or whatever) but I'm willing to learn 🙂


Primarily because it is NOT

While (!OPC)

     print "/ BS | BS \ BS -- BS "

Like a Chatty Cathy.   And since the Operation Duration cannot be calculated the developer on the other end has some feedback about the total progress of each file to mark.

 

With either a dot head or a laser overmarking would be bad.

 

Getting away from the normal term char also allows an abort to be issued and acked independently of the mark progress.  So, a reasonable solution to this specific application. 


"Should be" isn't "Is" -Jay
0 Kudos
Message 9 of 16
(1,999 Views)

Ah, no, I agree sending constant "spinning bar" messages to a terminal program would be bad. I simply meant to keep it exactly the same as it is now, but add a termchar after each transmission.

 

As I understand it, the protocol you mentioned above is:

 

<Computer sends RUN to printer/marker>

Run OK [termchar]

<Logo gets marked>

Device sends EOT to computer

<Firmware version marked>

EOT

<Date code marked>

EOT

ENQ

 

Is that right? All I'm saying is it would seem better to me to do:

 

<Computer sends RUN to printer/marker>

Run OK [termchar]

<Logo gets marked>

Device sends EOT to computer, termchar

<Firmware version marked>

EOT [termchar]

<Date code marked>

EOT [termchar]

ENQ [termchar]

 

Basically the same as it works now, just send a termchar after each byte- not a termchar after the marking is done. I don't feel like that would slow things down too much, and would still allow for aborts at any time.

 

(PS: I really appreciate the discussion. My company has to implement custom PC-MCU serial protocols quite frequently, so any non-traditional tips or tricks are extremely relevant to my work :))

0 Kudos
Message 10 of 16
(1,993 Views)