Click here to Skip to main content
15,905,229 members
Please Sign up or sign in to vote.
3.00/5 (3 votes)
See more:
Hi,
Application talks to a chip & pin terminal on serial port COM1. Sends commands from PC to terminal
& should display the encrypted responses back. However, I can capture the response to the 1st command only. All subsequent commands, although are transmitted to the terminal, fail to be
captured & hence cannot be displayed. There is definitely a response from the terminal as confirmed by a serial port monitor application running in the back ground.
So the question is what is wrong with the following code & how can I repair it so that I can capture all the responses to all the commands.


C#
        private void initialize_com_ports()
        {
            //let's assign the default parms to the output serial port structure          
            init_ip_serialport();       //initailize ip port setings - RX
            init_op_serialport();       //initailize op port setings - TX
        }

        private void init_op_serialport()
        {
            //let's assign the default parms to the input serial port structure
            op_serialport.PortName = def_ip_portname;
            op_serialport.BaudRate = def_baudrate;
            op_serialport.DataBits = def_databits;
            op_serialport.Handshake = def_handshake;
            op_serialport.Parity = def_parity;
            op_serialport.StopBits = def_stopbits;
        }

        private void init_ip_serialport()
        {
            //let's assign the default parms to the input serial port structure
            ip_serialport.PortName = def_ip_portname;
            ip_serialport.BaudRate = def_baudrate;
            ip_serialport.DataBits = def_databits;
            ip_serialport.Handshake = def_handshake;
            ip_serialport.Parity = def_parity;
            ip_serialport.StopBits = def_stopbits;
//            ip_serialport.ReadTimeout = 1000;
//            ip_serialport.WriteTimeout = 1000;
        }

        private void test_harness()     //we place our test script here
        {


            display_messages("Start Test Script.", 3);
            display_messages("Reset Device.", 3);
            byte[] op_data1 = new byte[] { 0x01, 0x00, 0x04, 0xD0, 0x00, 0x00, 0x00, 0xD5 };     //010004D0000000D5 -reset device
            op_serialport.Write(op_data1, 0, op_data1.Length);
            TX_Box.Items.Add(BitConverter.ToString(op_data1));
            op_serialport.Close();
            //            write_read_op(op_data1);
            MySerialReader();           //read the response from the terminal

            byte[] op_data2 = new byte[] { 0x01, 0x00, 0x04, 0xD2, 0x01, 0x01, 0x01, 0xD6 };            //010004D2010101D6 -reset display
            write_read_op(op_data2);
            display_messages("Reset Display.", 3);

            byte[] op_data3 = new byte[] { 0x01, 0x00, 0x04, 0xD0, 0x60, 0x1F, 0x00, 0xAA };            //010004D0601F00AA -Monitor card status
            write_read_op(op_data3);
            display_messages("Monitor Card status.", 3);

            byte[] op_data4 = new byte[] { 0x01, 0x00, 0x04, 0xD0, 0x61, 0x03, 0x00, 0xB7 };            //010004D0610300B7 -Monitor keyboard  status
            write_read_op(op_data4);
            display_messages("Monitor Keyboard status.", 3);

            byte[] op_data5 = new byte[] { 0x01, 0x00, 0x04, 0xD2, 0x01, 0x0D, 0x01, 0xDA };            //010004D2010D01DA -Prompt for card
            write_read_op(op_data5);
            display_messages("Insert Test Card.", 3);

            display_messages("Start Transaction Data.", 2);
            byte[] op_data = new byte[] { 0x01, 0x00, 0x37, 0xDE, 0xD1, 0x00, 0x00, 0x32,              //start transaction data 
                                   0xE0, 0x30, 0x9F, 0x02, 0x06, 0x00, 0x00, 0x00, 
                                   0x00, 0x00, 0x00, 0x9C, 0x01, 0x00, 0x9F, 0x21, 
                                   0x03, 0x01, 0x01, 0x01, 0x9A, 0x03, 0x11, 0x01, 
                                   0x01, 0x9F, 0x41, 0x02, 0x00, 0x01, 0xDF, 0xA2, 
                                   0x04, 0x01, 0x01, 0x5F, 0x2A, 0x02, 0x08, 0x26, 
                                   0xDF, 0xA2, 0x18, 0x01, 0x00, 0xDF, 0xA2, 0x04, 
                                   0x01, 0x01, 0x09};
            write_read_op(op_data);

            display_messages("Press Cancel", 3);
            op_data = new byte[] { 0x01, 0x00, 0x46, 0xDE, 0xD2, 0x00, 0x00, 0x41,              //continue Transaction
                                   0xE0, 0x3F, 0xC0, 0x01, 0x01, 0xC2, 0x02, 0x36, 
                                   0x35, 0xDF, 0xA2, 0x18, 0x01, 0x00, 0xDF, 0xA3, 
                                   0x07, 0x02, 0x03, 0xE8, 0x8A, 0x02, 0x59, 0x32, 
                                   0x91, 0x0A, 0x37, 0xDD, 0x29, 0x75, 0xC2, 0xB6,
                                   0x68, 0x2D, 0x00, 0x12, 0x9F, 0x1B, 0x04, 0x00, 
                                   0x00, 0x10, 0x00, 0x9F, 0x02, 0x06, 0x00, 0x00, 
                                   0x00, 0x04, 0x99, 0x99, 0x5F, 0x2A, 0x02, 0x09,
                                   0x78, 0x9F, 0x1A, 0x02, 0x09, 0x78, 0xC3, 0x01,
                                   0x01, 0xF1};
            write_read_op(op_data);

            //Wait for PIN Entry in progress
            //Wait for Online request
            display_messages("Enter PIN no.", 3);
            op_data = new byte[] { 0x01, 0x00, 0x0E, 0xDE, 0xD2, 0x00, 0x00, 0x09,      //Continue with NEGATIVE response
                                   0xE0, 0x07, 0xC0, 0x01, 0x00, 0x8A, 0x02, 0x30, 
                                   0x30, 0xA4 };
            write_read_op(op_data);

            display_messages("Remove Test Card", 3);
            op_data = new byte[] { 0x01, 0x00, 0x04, 0xD2, 0x01, 0x0E, 0x01, 0xD9 };     //Prompt for removal of card
            write_read_op(op_data);

            display_messages("Reset Display.", 2);
            op_data = new byte[] { 0x01, 0x00, 0x04, 0xD2, 0x01, 0x01, 0x01, 0xD6 };   //010004D2010101D6 -reset display
            write_read_op(op_data);

            display_messages("Reset Device.", 2);
            op_data = new byte[] { 0x01, 0x00, 0x04, 0xD0, 0x00, 0x00, 0x00, 0xD5 };   //010004D0000000D5 -reset device
            write_read_op(op_data);

            display_messages("End of Script.", 3);

        }


        private void write_read_op(byte[] command)
        {
            //write operation - TX command
            if (ip_serialport.IsOpen)
            {
                ip_serialport.Close();
            }
            op_serialport.Open();

            op_serialport.Write(command, 0, command.Length);
            TX_Box.Items.Add(BitConverter.ToString(command));
//            op_serialport.DiscardOutBuffer();

            op_serialport.Close();

            // let's stick in a delay here - just for fun 400mS
//            System.Threading.Thread.Sleep(400);

            //read operation - RX command
            MySerialReader();           //read the response from the terminal

        }

        private void display_messages(string message, int how_many)
        {
            if (how_many > 2)
            {
                MessageBox.Show(message);
            }
            RX_Box.Items.Add(message);
            TX_Box.Items.Add(message);
        }

        private void MySerialReader()
        {
            ip_serialport.Open();
            ip_serialport.DataReceived += serialPort_DataReceived;
//            ip_serialport.Close(); //This causes the problems
        }

        public string RxString;

        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            RxString = ip_serialport.ReadExisting();
            this.Invoke(new EventHandler(DisplayText_RX));         //<<-- ????!!! 
        }

        private void DisplayText_RX(object sender, EventArgs e)
        {
            RX_Box.Items.Add(RxString);
        }


Bit long, but hope the above makes some sense. Thanks in advance for all your assistance.
Regards
KM
Posted
Comments
gggustafson 25-Apr-14 15:57pm    
After reviewing your code, here are a few things that I think you might want to consider:

1. Declare the serial ports at the class level.
2. In an OnFormClosed event handler to insure that both serial ports are closed and disposed at the end of the application.
3. Declare a form load handler that creates, initializes, and opens both serial ports. Also in the form load handler, declare handlers for the DataReceived anf ErrorReceived events
4. After writing to the serial port, wait some amount of time.

If you have other questions, reply to this comment.

C#
this.Invoke(new EventHandler(DisplayText_RX));
each time you create a new eventhandler. Is this necessarry?

maybe you just need something like

C#
RX_Box.Invoke(new Action(()=> RX_Box.Items.Add(RxString)));
 
Share this answer
 
Comments
gggustafson 25-Apr-14 16:00pm    
I'm not sure that this is a soltion. I view it more of a comment or question. By responding to this question as if you were providing a solution, you have removed the question from the unanswered category.
Herman<T>.Instance 26-Apr-14 2:04am    
why you need a new eventhandler if 1 already exists?
gggustafson 26-Apr-14 17:04pm    
huh?
It is difficult to see where Your code is wrong and You can capture the response to the 1st command,
so probably it is the opening and closing of you port.
Also You use two names for the same port!!! , this can work but is confusing.

The comment of gggustafson is spot on!

Here is an example to help you on the right path:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.IO;


namespace Terminal
{
    public partial class Form1 : Form
    {
        //Use only one serial port, change all ip_serialport to op_serialport

        private SerialPort op_serialport= new SerialPort();
        public string RxString;

        public Form1()
        {
            InitializeComponent();

            //Declare DataReceived_handler  here only once!

            op_serialport.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);

            //let's assign the default parms to the output serial port structure
            init_op_serialport();       //initailize op port setings -RX/TX

            // Open the port and keep it open until you close application!
            OpenPort();
        }


        private void init_op_serialport()
        {
            //let's assign the default parms to the input serial port structure
            op_serialport.PortName = def_ip_portname;
            op_serialport.BaudRate = def_baudrate;
            op_serialport.DataBits = def_databits;
            op_serialport.Handshake = def_handshake;
            op_serialport.Parity = def_parity;
            op_serialport.StopBits = def_stopbits;
        }

        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            RxString = op_serialport.ReadExisting();

            DisplayText_RX(RxString);
        }

        private void OpenPort()
        {
            bool error = false;

            // If the port is open, close it.
            if (op_serialport.IsOpen) op_serialport.Close();

            //Add some error_handling!
            try
            {
                // Open the port
                op_serialport.Open();
            }
            catch (UnauthorizedAccessException) { error = true; }
            catch (IOException) { error = true; }
            catch (ArgumentException) { error = true; }

            if (error) MessageBox.Show(this, "Could not open the COM port."+
                                             " Most likely it is already in use,"+
                                             "has been removed, or is unavailable.",
                                             "COM Port Unavalible", MessageBoxButtons.OK, MessageBoxIcon.Information);

        }

        // here RX_Box = Ritch textbox
        private void DisplayText_RX(string rxString)
        {
            RX_Box.Invoke(new EventHandler(delegate
            {
                RX_Box.AppendText(rxString);

            }));
        }
    }
}
 
Share this answer
 
Comments
Member 10632705 28-Apr-14 11:28am    
Hi Groover,
Many Thanks for your input. Unfortunately the following line: RX_Box.AppendText(RxString); - causes an error as follows: "System.Windows.Forms.ListBox does not contain a definition for 'AppendText' and no extension method could be found........" I'm very new to C# & connot resolve this error. Regards KM
GrooverFromHolland 28-Apr-14 12:02pm    
Hi KM,<br>
From Your code it was not possible to know what control Rx-_Box could be. So I commented: Here RX_Box is RitchTextBox, not Listbox. ListBox is not normally. used to display messages. If You want to use ListBox just change it to: ListBox.Add(RxString).
Member 10632705 29-Apr-14 6:45am    
Hi Groover,
Yes of course. I've used the ListBox method. Having followed your suggestions, I'm happy to report that my application is now working reasonably well. I can now manage to collect all responses to all command from my chip & pin terminal. So I'm very grateful to you for taking the time to review my code & of course your very helpful suggestions. Many Thanks.
Best Regards
Kishor Mistry

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900