1

So, I have a card locking system device which connects through RS-232 DB9 serial port. This is my first time dealing with an external device using that. So I read the manual an it says that the transmission procedure text format is defined as follows:

-The text must consist of up to 500 characters between STX and ETC

-LRC computed area ranges from the first character from STX to ETX

there is also a list of control characters (STX, ETX, ACK, NAK) with their hex codes.

I have no idea about this. Please enlighten me. Oh and also, could I detect whether a device is connected or not to a specific port?

I've managed to connect to the comm port using this code below:

public class TwoWaySerialComm
{
    protected InputStream inputStream;
    protected OutputStream outputStream;

    public TwoWaySerialComm()
    {
        super();
    }

    void connect ( String portName ) throws Exception
    {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        if ( portIdentifier.isCurrentlyOwned() )
        {
            System.out.println("Error: Port is currently in use");
        }
        else
        {
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);

            if ( commPort instanceof SerialPort )
            {
                SerialPort serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(9600,SerialPort.DATABITS_7,SerialPort.STOPBITS_1,SerialPort.PARITY_ODD);

                inputStream = serialPort.getInputStream();
                outputStream = serialPort.getOutputStream();

                (new Thread(new SerialReader(inputStream))).start();
                (new Thread(new SerialWriter(outputStream))).start();

            }
            else
            {
                System.out.println("Error: Only serial ports are handled by this example.");
            }
        }
    }

    public InputStream getInputStream() {
        return inputStream;
    }

    public void setInputStream(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    public OutputStream getOutputStream() {
        return outputStream;
    }

    public void setOutputStream(OutputStream outputStream) {
        this.outputStream = outputStream;
    }

    /** */
    public static class SerialReader implements Runnable 
    {
        InputStream in;

        public SerialReader ( InputStream in )
        {
            this.in = in;
        }

        public void run ()
        {
            byte[] buffer = new byte[1024];
            int len = -1;
            try
            {
                while ( ( len = this.in.read(buffer)) > -1 )
                {
                    System.out.print(new String(buffer,0,len));
                }
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }            
        }
    }

    /** */
    public static class SerialWriter implements Runnable 
    {
        OutputStream out;

        public SerialWriter ( OutputStream out )
        {
            this.out = out;
        }

        public void run ()
        {
            try
            {
                int c = 0;
                while ( ( c = System.in.read()) > -1 )
                {
                    this.out.write(c);
                }                
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }            
        }
    }

    public static void main ( String[] args )
    {
        try
        {
            TwoWaySerialComm comm = new TwoWaySerialComm();
            comm.connect("COM3");
        }
        catch ( Exception e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

And this is the code I've found which is used to get LRC from an array of bytes:

    public byte calculateLRC(byte[] data)
    {
        byte checksum = 0;
        for (int i = 0; i <= data.length - 1; i++) {
            checksum = (byte) ((checksum + data[i]) & 0xFF);
        }

      checksum = (byte) (((checksum ^ 0xFF) + 1) & 0xFF);
        return checksum;
    }

Now supposedly I have to send text "CES01" properly to the device, how do I do that?

William Wino
  • 3,599
  • 7
  • 38
  • 61

3 Answers3

1
STX :start character 
ETX: end character 
ACK : Acknowledgement 

    char STX = 0x02;
char ETX = 0x03;
char EOT = 0x04;
char ENQ = 0x05;
char ACK = 0x06;

Also see the link for LIS/RIS message format

http://www.hl7standards.com/

sending Acknowledgement

public void sendAcknowledgement()throws IOException{
         String ack= ASCIITable.ACK + "";
         outputStream.write(ack.getBytes());
    }
Mohammod Hossain
  • 4,134
  • 2
  • 26
  • 37
1

If you have absolutely no experience with serial comms I would start out by studying some existing, known to work implementation. John Ellinwood's answer to this SO question contains the Java source to the XModem protocol, an old, simple modem file transfer protocol. This will show you how to handle the communication itself (you always have to be prepared for timeouts and other error conditions) and the control characters.

A pecularity of Java you must not forget is the absence of unsigned types in Java, almost always these low level protocols become a bit more complicated to program if the only variable types you have at your disposal are signed. But as the XModem code shows, it's perfectly doable.

Community
  • 1
  • 1
fvu
  • 32,488
  • 6
  • 61
  • 79
0

OutputStream writes bytes so you have to convert your string to a byte array first:

outputStream.write("CES01".getBytes());
Reimeus
  • 158,255
  • 15
  • 216
  • 276