Click here to Skip to main content
11,429,382 members (68,966 online)
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# SerialPorts
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.

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 31-May-12 0:08am
Edited 31-May-12 0:10am
v2
Comments
digimanus at 31-May-12 5:15am
   
Have you tried pressing tha TAB key twice after typing Application.Idle += ?
Tushar Sriv at 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.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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[^]
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

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.

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.
  Permalink  

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



Advertise | Privacy | Mobile
Web02 | 2.8.150428.2 | Last Updated 3 Jun 2012
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100