In buttonStart_Click( ), we begin by setting the port name and baud rate. In our example PortName is COM1 but you can set it to any other port available on your computer. Notice the PortName is a string and must be in quotes. The baud rate must agree with the baud rate of whatever is on the other end of the serial connection. We then call the Open( ) function. If the port opened OK, we disable the Start button, enable the Stop button, and allow writing in textBox1.
private void buttonStart_Click(object sender, EventArgs e)
{
serialPort1.PortName = "COM1";
serialPort1.BaudRate = 9600;
serialPort1.Open();
if (serialPort1.IsOpen)
{
buttonStart.Enabled = false;
buttonStop.Enabled = true;
textBox1.ReadOnly = false;
}
}
Once the serialPort1 is open, any incoming serial characters will cause a DataReceived event to fire. Inside the event handler we read all existing characters from the internal serial receive buffer into string RxString. The next part is critical and not obvious. serialPort1 runs in it own separate thread behind the scenes. This thread cannot directly call any functions in the main thread of our application. However, a special function, Invoke( ), will allow it. So we use Invoke to call our DisplayText( ) function. RxString is the global string variable accessable by both threads.
private void serialPort1_DataReceived
(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
RxString = serialPort1.ReadExisting();
this.Invoke(new EventHandler(DisplayText));
}
Our DisplayText( ) function is simple. We just append the text in RxString to whatever is already in textBox1.
private void DisplayText(object sender, EventArgs e)
{
textBox1.AppendText(RxString);
}
The textbox1 KeyPress( ) function captures characters typed into textBox1 and writes them to serialPort1. Write( ) can only send characters from a char type array so we declare one with a length of [1] and assign the KeyChar value to it. With the arguments in Write( ), we tell it to send the characters in the buff, offset of 0 chars into the array, and a length of 1 char. We set the event to "Handled" to prevent the typed character from appearing in textBox1. If you want it to appear (local echo), omit the line.
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if(!serialPort1.IsOpen) return;
char[] buff = new char[1];
buff[0] = e.KeyChar;
serialPort1.Write(buff, 0, 1);
e.Handled = true;
}
Clicking the Stop button calls buttonStop_Click( ). If serialPort1 is open, we close the port and set the button enables and textBox1 ReadOnly state back to their previous value.
private void buttonStop_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
buttonStart.Enabled = true;
buttonStop.Enabled = false;
textBox1.ReadOnly = true;
}
}
Last but not least, if the application is closed while serialPort1 is open, the port must be closed first or the program will hang.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (serialPort1.IsOpen) serialPort1.Close();
}