B4J Question Send Hex Sequence to Serial Port

Pedro Caldeira

Active Member
Licensed User
Longtime User
Hello,
I am trying to send a sequence to a motorized magnetic card reader.
I have to send, for instance, to eject the card, the following sequence

0x02 0x00 0x02 0x32 0x30 0x03 0x01

The manual states that communication format is:

Eject Card Command = 0x30

STX Command ETX BCC

How can I convert this sequence to bytes to send via Asyncstreams ?
 

Daestrum

Expert
Licensed User
Longtime User
Possibly...

B4X:
Dim ejectCard() As Byte = Array(0x02,0x00,0x02,0x32,0x30,0x03,0x01)
...
'then write ejectCard to the stream
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
probably should be Array As Byte(...) not just Array(...)
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
maybe try
STX 0x30 ETX
which would be
B4X:
Array As Byte(0x02,0x30,0x03)
'             STX  CMD  ETX
 
Upvote 0

Pedro Caldeira

Active Member
Licensed User
Longtime User
nothing works
can't I send plain Hexadecimal values directly to the serial port
like :

B4X:
chr(02) & chr(03) & chr(04)

for instance ?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Couple of issues:

One, I'm gonna guess this (https://sensis.ru/files/CRT-310 _V3[1][1].0_ Card Reader Communication Protocol.pdf) is the protocol you're using (and I'm guessing here since you have not provided us with the specs).

Two, you're just sending the command, but if you look at the command flow (page 3 of the above linked file), then you should send this command, receive an acknowledgement that it has been received (ACK - 0x06), send ENQ (0x05), and receive another acknowledgement that it has been executed.

So you're never going to eject that card even if you sent the right sequence, since you're not checking for the ACK, nor sending the ENQ.

Of course I could be wrong since I'm guessing what protocol you're using in the first place.

but i dont know what 'BCC' is.
It stands for "block check character". According to the link above, it is a XOR value of command packet. XOR with what I have no clue (the result is 1).
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Upvote 0

OliverA

Expert
Licensed User
Longtime User
nothing works
can't I send plain Hexadecimal values directly to the serial port
You don't send the hex characters to the machine in character form. That's just for us humans to have something more readable/compact than

00000010 00000000 00000010 00110010 00110000 00000011 00000001

I think I can scan/search the hex codes easier (the card reader still wants its 0's and 1's).
 
Upvote 0

Pedro Caldeira

Active Member
Licensed User
Longtime User
I send hex sequences to printers, the reader could work the same.
But I see that it doesn't.
and Yes, OliverA , the Card Reader its just that one. (the 310).
So, using jSerial and AsyncStreams, How do I send the data and how do I read the Ack ?
 
Upvote 0

Pedro Caldeira

Active Member
Licensed User
Longtime User
Working
the only thing weird that now happens is that the received info sometimes is splited in several lines.
I use a timer to check the readers Status every second, to know when a user inserts a card.


Response in the log to a check Status


Waiting for debugger to connect...
Program started.
06
02000531304E4A4A
034B
06
02000531304E4A4A034B
06
02000531304E4A4A
034B
06
02000531304E4A4A034B
06
02000531304E4A4A034B
06
02000531304E4A4A
034B
06

info from the Reader's Demo App

SD: 02 00 02 31 30 03 02
RD: 06
SD: 05
RD: 02 00 05 31 30 4E 4A 4A 03 4B


B4X:
Sub AStreams_NewData (Buffer() As Byte)
 
    Private RawReply As String
    Private BtCvt As ByteConverter
     
    RawReply=BtCvt.HexFromBytes(Buffer)
 
    'Log (RawReply)
 
    If RawReply = "06" Then    AStreams.Write(Array As Byte(0x05))
 
    If CardOperation = "Status" Then
        Log (RawReply) '<- Log output from here, I have a button the ask the reader's status
        If RawReply.Length = 16 And SF.Mid(RawReply,1,10) ="0200053130" Then
            Select Case SF.Mid(RawReply,11,2)
                Case "4A" ' Card in Reader
                    TimerReader.Enabled = False
                    Talk2Reader ("Read")
            End Select
        End If
    End If
 
    If CardOperation = "Read" Then
        Log (RawReply)
    End If
     
End Sub
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
the only thing weird that now happens is that the received info sometimes is splited in several lines
It's not really weird. You're packet is framed with a start frame (STX) and a stop frame (ETX) followed by a simple error checking (BCC). AsyncStream is totally unaware of this protocol, it just takes in data. Since, according to the docs, the communication of the device is non-blocking (asynchronous), that data stream may not come over uninterrupted. If it has not been interrupted, AsyncStream seems to capture the response completely, otherwise it comes over as one or more junks. Please note that the packet includes a length field (bytes 2 and 3). It is this field that you need to use to determine when you received all the data (of STX ETX framed packet). You also need to calculate the BCC to ensure the packet came over undamaged. Technically, the first byte of any complete communication to you should start with STX, ACK or NAK. In the case of an STX, additional packets may arrive until you receive all data of the STX communication. Anything else is either corrupted data or noise on the line (that can happen).
 
Upvote 0

Pedro Caldeira

Active Member
Licensed User
Longtime User
how can I read the Buffer until the communication is complete.
I need to get all the data of thw package and test each byte to check for errors, but as you said, the data can arrive with noise.
I need to get the data equal to the demo APP, one single string from STX to ETX + BCC
I can do everything with the reader, now, except reading :(
 
Upvote 0
Top