• Welcome to PlanetSquires Forums.
 

XOR & Com ports

Started by Petrus Vorster, October 12, 2023, 08:09:43 AM

Previous topic - Next topic

Petrus Vorster

Hi All

I have obtained a better printer (Datamax o'Neil) with a programmer guide which is much more understandable.

I need to send info via a com port in TEXT and will receive info back in TEXT.
It says the port should be opened XOR.

Port communications I have never touched before.

How do one read incoming messages on a com port? It seems to be an input like from a file, but how do you "wait" until such a response arrives?
Must be small loop of sorts, but if anyone has some examples on data in and out on com ports, I will appreciate any advice.

-Peter
-Regards
Peter

philbar

Hi Peter,

Using COM: ports lies on the spectrum between "dead easy" and "nightmarish." Most of the time, they're "pretty easy." Here's what "dead easy" looks like:
Open Com "COM5:9600,N,8,1" As 17
Print #17, "Hello",x,y,z
Input #17, Astring,a,b
Close #17

The printer manual will tell you what values it expects for baud rate, parity, data bits, and stop bits or the printer may have switches so you can choose yourself.

See the instructions for Open Com in the FB manual: https://www.freebasic.net/wiki/KeyPgOpenCom

The Input # will block until its list is satisfied, so the question is not how do you wait for a response, but how do you make it give up when there's no response. As it turns out, the Loc(filenum) function, when used with a serial port, gives the number of bytes waiting in the input buffer. The example on that page shows a program that sends a command to a device, sleeps for a moment while the response comes back, and then retrieves the response one byte at a time using Loc(filenum) to tell it when the buffer is empty. There's a useful thread about that on the FB forum at https://freebasic.net/forum/viewtopic.php?t=31435. The thread at https://freebasic.net/forum/viewtopic.php?p=213079#p213079 also helps.

No matter what people say, there's no such thing as a standard serial cable. Thanks mostly to Microsoft, the connector at the computer end is well-defined, but how the wires get interchanged, jumpered, or omitted going to the device is, uh, individualistic. I've spent many happy hours with a voltmeter and patch cables figuring out which pins are inputs or outputs and which are logically paired and which are unnecessary. The only right way is to get a serial cable from the manufacturer.

I don't know what they mean by opening the port XOR. It might mean that the printer expects each command line to end with a check byte which is the XOR of all the preceding bytes in the command. Or it might mean that it wants to use software flow control instead of hardware. I googled "XOR com port," and that was a rabbit hole.

Not trying to scare you off; I'm just anticipating. Like I said, it's usually pretty easy.

Phil


SeaVipe

#2
Hi Peter,

Here are a few code snippets from a very old C, FireFly, and finally WinFBE app that may trigger some ideas:
' // Open the serial port
' // This string, this way, worked perfectly after endless testing!
Dim as String cp = "Com10:57600,N,8,1,DT,CS,DS,BIN"
' // Although hard coded here, it was a param from the calling module
' // Variable to hold the Com Port "File" number
Dim as Long     fh      = 10
' // Default = Open Com( "Com9:57600,N,8,1,DT,CS,DS,BIN" as fh)   
Dim as Long     l_open  = Open Com( cp as fh)

' // Variable to hold the LOC return value
Dim as LongInt  l   = -1                   
' // Variable to hold the CLOSE port return value
Dim as Long     c   = -1                   
' // When used with a serial device, LOC returns the number of bytes waiting
' // to be read from the serial device's input buffer.
l = LOC( fh )
If l > 0 then proceed...

' // Main loop RX buffer
' // The serial device was 8-bit and could never send or receive more than 244 bytes.
' // The original C code was an Int. The old industrial PC this ran on only had a 10 MB HDD.
Dim as UByte buf( 1 )

' // The first byte dictates the number
' // of remaining bytes in the Request Command.
' // The format of Get is critical especially the space between Get( and #.
Dim as Long g = Get( #fh, , buf(0), , bytesRead )

' // Echo first byte
' // The device triggered a TX command if it recognized the first byte echoed back.
p = Put( #fh, , Chr( buf( 0 ) ) ) ' Echo byte
' // Get data
g = Get( #fh, , buf( 0 ), , bytesRead ) '' R Val
' // buf() now contains the remaining bytes or data block
' // Success.  c = Close( #fh ) the # throws an error so use:
c = Close( fh )

' // a basic checksum
If chksum( ub_rval_TX_buffer( BYTES_R_V_CHKSUM1 ), _
   ub_rval_TX_buffer( BYTES_R_V_CHKSUM2 ), _
   BYTES_R_VAL, _
   ub_rval_TX_buffer() _
) = VV_NO_ERROR Then

Option Action
'CSn'   Set the CTS duration (in ms) (n>=0), 0 = turn off, default = 1000
'DSn'   Set the DSR duration (in ms) (n>=0), 0 = turn off, default = 1000
'BIN'   The opposite of LF and it'll always work
'DT'     Keep DTR enabled after CLOSE

I hope this helps.
Clive
Clive Richey

Petrus Vorster

Hi Everyone

Thank you for the reponses.
I am going to play with this a bit and see if I can get it working.

This IPL and other direct printer communications is such a big field one wonders why there are so little material available. There are millions of Companies, Postal systems, couriers, banks, shipping companies etc all using Direct IPL/ZPL printing, and yet not a single developer I spoke to had the vaguest idea what I was talking about. They say for that they just get a specialist for that bit of code and nobody bothers to learn how.

Weird.

Regards, Peter
-Regards
Peter