Click here to Skip to main content
16,020,622 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello, I have a question. I am making a very general application wherein I need to receive data from a hardware device serially. The device is made by me using very basic AT89C51. I am designing the software in C#. What I want is that whenever I send data to my PC through serial port, it is displayed directly on the screen. My strategy up till now is to use Application.Idle event. I have made something like this.

C#
private void btnStart_Click(object sender, EventArgs e)
{
    int Number;
    bool isValid;
    isValid = Int32.TryParse(txtBaudRate.Text, out Number);
    if(!isValid)
    {
        MessageBox.Show("Use only Integer for Baud Rate", "Error", MessageBoxButtons.Ok, MessageBoxIcon.Error);
    }
    else
    {
        try
        {
            sp = new SerialPort(txtPort.Text,Number);
            sp.Open();
            buffer_write = new byte[1];
            buffer_read = new byte[1];
            Application.Idle += Application_Idle;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.Ok, MessageBoxIcon.Error);
        }
    }
}


Now I am unable to figure out how to write the Application_Idle method, so that When I hit a key on keyboard while in application, That keypress character is sent serially to port and whenever I send some data serially through my device, it gets echoed on the screen on a label.

Please Help me regarding this.
Posted
Updated 30-May-12 23:10pm
v2
Comments
Herman<T>.Instance 31-May-12 5:15am    
Have you tried pressing tha TAB key twice after typing Application.Idle += ?
Er. Tushar Srivastava 31-May-12 5:17am    
Oh... I think you get me wrong, sorry I mean I am trying to figure out the algorithm, :-D Anyways thank you.

I don't think that Application.Idle is meant to be used like this. If I got it correctly, you want a listener on the serial port.
This could help you out: Basic serial port listening application[^]
 
Share this answer
 
I have solved it myself.
I added a Background Worker.
When you will initialize the Serial Port on Clicking the Start Button, the background worker will start another thread where it will check the value stored in read buffer, if value stored here changes, it will display that value on the TextBox ... Here's My Program, I am posting it for others... so that it may help them.

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;

namespace Serial_Communication
{
    public partial class frmMain : Form
    {
        SerialPort sp;
        byte[] buffer_write,buffer_read;
        bool set = false;
        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            txtPort.MaxLength = 5;
            txtBaudRate.MaxLength = 5;
            txtPort.Text = "COM1";
            txtBaudRate.Text = "9600";
            this.FormClosing += new FormClosingEventHandler(frmMain_FormClosing);
        }

        void consoleBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            buffer_write = BitConverter.GetBytes(e.KeyChar);
            sp.Write(buffer_write, 0, 1);
        }

        void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            MessageBox.Show("Exiting Application");
            try
            {
                backgroundWorker.CancelAsync();
                sp.Close();
            }
            catch (Exception)
            {
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                backgroundWorker.CancelAsync();
                sp.Close();
            }
            catch (Exception)
            {
            }
            Application.Exit();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            int Number;
            bool isValid;
            isValid = Int32.TryParse(txtBaudRate.Text, out Number);
            if (!isValid)
            {
                MessageBox.Show("Use only Integer for Baud Rate", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else if (!set)
            {
                try
                {
                    sp = new SerialPort(txtPort.Text, Number);
                    sp.Open();
                    buffer_write = new byte[2];
                    buffer_read = new byte[2];
                    set = true;
                    backgroundWorker.RunWorkerAsync(sp);
                    btnStart.Text = "Stop";
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                backgroundWorker.CancelAsync();
                sp.Close();
                btnStart.Text = "Start";
            }
        }

        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            SerialPort sm = e.Argument as SerialPort;

            while (set)
            {
                if (backgroundWorker.CancellationPending == true)
                {
                    sm.Close();
                    e.Cancel = true;
                    break;
                }
                else
                {
                    try
                    {
                        sm.Read(buffer_read, 0, 1);
                        if (buffer_read[0].ToString() != "")
                        {
                            e.Result = sm;
                            backgroundWorker.ReportProgress(1);
                        }
                    }
                    catch (Exception) { }
                }
            }
        }

        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.consoleBox.Text += BitConverter.ToChar(buffer_read,0).ToString();
            buffer_read[0] = 0x00;
        }

        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                backgroundWorker.Dispose();
                backgroundWorker = null;
                GC.Collect();
            }
        }
    }
}


This is complete Program created by me. Now I also want to ask a question here, I have setup many exception handlers. Now I am facing a problem while disposing the background worker safely, So, I have added exception handler here. But I doubt it seriously, why these unhandled exceptions are occurring while disposing off the background worker. Please help me regarding this.
 
Share this answer
 

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