Help with serial data display
-
Hi Luc, Here is what it looks like with the OE program, so it is working correctly. There has to be something I'm missing here? <
> http://img221.imageshack.us/img221/4316/serialterminal.png[^] Here is my code after all kinds of tweaks or attempts to get this to work, if you'd like anything else just let me know. Thanks!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;namespace SimpleSerial
{
public partial class Form1 : Form
{
// Add this variablestring RxString; public Form1() { InitializeComponent(); string\[\] theSerialPortNames = System.IO.Ports.SerialPort.GetPortNames(); /\*MessageBox.Show(theSerialPortNames\[0\]); MessageBox.Show(theSerialPortNames\[1\]); MessageBox.Show(theSerialPortNames\[2\]); MessageBox.Show(theSerialPortNames\[3\]);\*/ //MessageBox.Show(theSerialPortNames\[4\]); //MessageBox.Show(theSerialPortNames\[5\]); } private void buttonStart\_Click(object sender, EventArgs e) { serialPort1.PortName = "COM7"; serialPort1.BaudRate = 115200; serialPort1.Handshake = Handshake.None; serialPort1.Open(); if (serialPort1.IsOpen) { buttonStart.Enabled = false; buttonStop.Enabled = true; textBox1.ReadOnly = false; } } private void buttonStop\_Click(object sender, EventArgs e) { if (serialPort1.IsOpen) { serialPort1.Close(); buttonStart.Enabled = true; buttonStop.Enabled = false; textBox1.ReadOnly = true; } } private void Form1\_FormClosing(object sender, FormClosingEventArgs e) { if (serialPort1.IsOpen) serialPort1.Close();
Hi, some comments: 1. as your terminal emulator is working, it would be time to try the binary mode I have shown earlier. It has the advantage of (a) showing the exact bytes you're getting, and (b) you're using your own code (as opposed to the terminal emulator). 2. you should set the port's properties right when you open it, and not in its DataReceived handler, i.e. after having gotten some data already. 3.
turbosupramk3 wrote:
serialPort1.NewLine = "(13)";
that is non-sense. You need a CR character, which is represented by \r in C-like languages. cfr my first reply. 4. I wouldn't use a single TextBox for both input and output, at least until everything works well. I also wouldn't spend all that effort in the GUI stuff until such moment that the serial comm is working fine. I think you're getting closer to the solution! :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.
-
I am trying to read serial data from a microchip. Using the simple serial c# project I am able to read the characters being sent, but I am not able to delineate carriage returns and so the correct data will stream across the screen until the programs input box end and then it will wrap around to the next line and continue to stream, an example would be
seveneightnineteneleventwelvethirteen
fourteenfifteensixteenseventeeneighteeninstead of
seven
eight
nine
ten
eleven
twelve
thirteen
fourteen
fifteen
sixteen
seventeen
eighteenDoes anyone know how I can recognize the carriage returns? They should come through as an ascii character "13" and the serial data protocol is 8 databits no paraty one stopbit (8N1) at a baudrate between 9600 and 115200 baud. Thanks!
-
Hi, Here is the guts of it
private void Form1\_FormClosing(object sender, FormClosingEventArgs e) { if (serialPort1.IsOpen) serialPort1.Close(); } 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; } private void DisplayText(object sender, EventArgs e) { textBox1.AppendText(RxString); } private void serialPort1\_DataReceived (object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { RxString = serialPort1.ReadExisting(); this.Invoke(new EventHandler(DisplayText)); }
I suspect your problem is with how ReadExisting() handles the carriage returns; it may well be expecting a carriage return line feed pair of characters, to indicate a new line. If I am using Serial port for text data, I get the data as a byte array; and then convert it to a string, either using Encoding - Encoding.ASCII.GetString(myByteArrray) or manually processing each character if I need to handle specific bytes individually. Off the top of my head, I can't remember if GetString will convert a striaght carriage return to a new line; but if not you can process each byue of the array in turn, detecting the carriage return and adding Environment.NewLine in it's place to the string. Hope this helps.
-
I suspect your problem is with how ReadExisting() handles the carriage returns; it may well be expecting a carriage return line feed pair of characters, to indicate a new line. If I am using Serial port for text data, I get the data as a byte array; and then convert it to a string, either using Encoding - Encoding.ASCII.GetString(myByteArrray) or manually processing each character if I need to handle specific bytes individually. Off the top of my head, I can't remember if GetString will convert a striaght carriage return to a new line; but if not you can process each byue of the array in turn, detecting the carriage return and adding Environment.NewLine in it's place to the string. Hope this helps.
Hi Colin, Maybe I can send it different characters for a line feed ... do you happen to know what pair of characters is it expecting? With the byte array, are you just filling it up with 8 bits, and then at the stop bit converting it to a string?
-
Hi Luc, Here is what it looks like with the OE program, so it is working correctly. There has to be something I'm missing here? <
> http://img221.imageshack.us/img221/4316/serialterminal.png[^] Here is my code after all kinds of tweaks or attempts to get this to work, if you'd like anything else just let me know. Thanks!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;namespace SimpleSerial
{
public partial class Form1 : Form
{
// Add this variablestring RxString; public Form1() { InitializeComponent(); string\[\] theSerialPortNames = System.IO.Ports.SerialPort.GetPortNames(); /\*MessageBox.Show(theSerialPortNames\[0\]); MessageBox.Show(theSerialPortNames\[1\]); MessageBox.Show(theSerialPortNames\[2\]); MessageBox.Show(theSerialPortNames\[3\]);\*/ //MessageBox.Show(theSerialPortNames\[4\]); //MessageBox.Show(theSerialPortNames\[5\]); } private void buttonStart\_Click(object sender, EventArgs e) { serialPort1.PortName = "COM7"; serialPort1.BaudRate = 115200; serialPort1.Handshake = Handshake.None; serialPort1.Open(); if (serialPort1.IsOpen) { buttonStart.Enabled = false; buttonStop.Enabled = true; textBox1.ReadOnly = false; } } private void buttonStop\_Click(object sender, EventArgs e) { if (serialPort1.IsOpen) { serialPort1.Close(); buttonStart.Enabled = true; buttonStop.Enabled = false; textBox1.ReadOnly = true; } } private void Form1\_FormClosing(object sender, FormClosingEventArgs e) { if (serialPort1.IsOpen) serialPort1.Close();
I have had luck writing serial data from a PIC microcontroller to a textbox using the following code in C#:
private void serialPort1_DataReceived_1(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
txtToDisplay = serialPort1.ReadExisting();
DisplayText();
}public void DisplayText()
{
if (txtIn.InvokeRequired)
{
this.BeginInvoke(new MethodInvoker(DisplayText));
}
else
{
txtIn.AppendText(txtToDisplay);
}
}Also, I set the comm port parameters in the same place I open the port, rather than the receive event:
private void GetComPorts() //populate the comm port list with the available system ports
{
foreach (string s in SerialPort.GetPortNames() )
{
lbPort.Items.Add(s);
}
}private void btnOpen_Click(object sender, EventArgs e)
{this.lbPort.SelectedIndex = this.lbPort.TopIndex; // which port? this.lbRate.SelectedIndex = this.lbRate.TopIndex; // baud rate? this.lbProtocol.SelectedIndex = this.lbProtocol.TopIndex; // N,8,1 or N,7,1 (strings in a collection) string crlf = Environment.NewLine; // this might be the real trick... serialPort1.BaudRate = Int32.Parse(lbRate.Text); serialPort1.PortName = lbPort.Text; serialPort1.Open(); if (serialPort1.IsOpen) { btnOpen.Enabled = false; btnClose.Enabled = true; txtIn.AppendText(string.Format("Port {0} opened successfully." + crlf, serialPort1.PortName)); }
}
Anyway, this seems to work in my situation. Also, my PIC code is using "\r\n" so I am actually sending a {10} and a {13} pair. Hope this helps, Adam
-
Hi, some comments: 1. as your terminal emulator is working, it would be time to try the binary mode I have shown earlier. It has the advantage of (a) showing the exact bytes you're getting, and (b) you're using your own code (as opposed to the terminal emulator). 2. you should set the port's properties right when you open it, and not in its DataReceived handler, i.e. after having gotten some data already. 3.
turbosupramk3 wrote:
serialPort1.NewLine = "(13)";
that is non-sense. You need a CR character, which is represented by \r in C-like languages. cfr my first reply. 4. I wouldn't use a single TextBox for both input and output, at least until everything works well. I also wouldn't spend all that effort in the GUI stuff until such moment that the serial comm is working fine. I think you're getting closer to the solution! :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.
Hey Luc, I tried \r and \n too :) with no luck then I was trying the string value and I tried Chr(13) as well with no luck. I will try the binary thing tonight and see what bits I am getting
-
I have had luck writing serial data from a PIC microcontroller to a textbox using the following code in C#:
private void serialPort1_DataReceived_1(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
txtToDisplay = serialPort1.ReadExisting();
DisplayText();
}public void DisplayText()
{
if (txtIn.InvokeRequired)
{
this.BeginInvoke(new MethodInvoker(DisplayText));
}
else
{
txtIn.AppendText(txtToDisplay);
}
}Also, I set the comm port parameters in the same place I open the port, rather than the receive event:
private void GetComPorts() //populate the comm port list with the available system ports
{
foreach (string s in SerialPort.GetPortNames() )
{
lbPort.Items.Add(s);
}
}private void btnOpen_Click(object sender, EventArgs e)
{this.lbPort.SelectedIndex = this.lbPort.TopIndex; // which port? this.lbRate.SelectedIndex = this.lbRate.TopIndex; // baud rate? this.lbProtocol.SelectedIndex = this.lbProtocol.TopIndex; // N,8,1 or N,7,1 (strings in a collection) string crlf = Environment.NewLine; // this might be the real trick... serialPort1.BaudRate = Int32.Parse(lbRate.Text); serialPort1.PortName = lbPort.Text; serialPort1.Open(); if (serialPort1.IsOpen) { btnOpen.Enabled = false; btnClose.Enabled = true; txtIn.AppendText(string.Format("Port {0} opened successfully." + crlf, serialPort1.PortName)); }
}
Anyway, this seems to work in my situation. Also, my PIC code is using "\r\n" so I am actually sending a {10} and a {13} pair. Hope this helps, Adam
Hi Adam, Thanks! I will try that at home and see how it works with my uC. I did not try sending a 10 and 13, that might be worth a try as well!
-
I am trying to read serial data from a microchip. Using the simple serial c# project I am able to read the characters being sent, but I am not able to delineate carriage returns and so the correct data will stream across the screen until the programs input box end and then it will wrap around to the next line and continue to stream, an example would be
seveneightnineteneleventwelvethirteen
fourteenfifteensixteenseventeeneighteeninstead of
seven
eight
nine
ten
eleven
twelve
thirteen
fourteen
fifteen
sixteen
seventeen
eighteenDoes anyone know how I can recognize the carriage returns? They should come through as an ascii character "13" and the serial data protocol is 8 databits no paraty one stopbit (8N1) at a baudrate between 9600 and 115200 baud. Thanks!
-
I have had luck writing serial data from a PIC microcontroller to a textbox using the following code in C#:
private void serialPort1_DataReceived_1(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
txtToDisplay = serialPort1.ReadExisting();
DisplayText();
}public void DisplayText()
{
if (txtIn.InvokeRequired)
{
this.BeginInvoke(new MethodInvoker(DisplayText));
}
else
{
txtIn.AppendText(txtToDisplay);
}
}Also, I set the comm port parameters in the same place I open the port, rather than the receive event:
private void GetComPorts() //populate the comm port list with the available system ports
{
foreach (string s in SerialPort.GetPortNames() )
{
lbPort.Items.Add(s);
}
}private void btnOpen_Click(object sender, EventArgs e)
{this.lbPort.SelectedIndex = this.lbPort.TopIndex; // which port? this.lbRate.SelectedIndex = this.lbRate.TopIndex; // baud rate? this.lbProtocol.SelectedIndex = this.lbProtocol.TopIndex; // N,8,1 or N,7,1 (strings in a collection) string crlf = Environment.NewLine; // this might be the real trick... serialPort1.BaudRate = Int32.Parse(lbRate.Text); serialPort1.PortName = lbPort.Text; serialPort1.Open(); if (serialPort1.IsOpen) { btnOpen.Enabled = false; btnClose.Enabled = true; txtIn.AppendText(string.Format("Port {0} opened successfully." + crlf, serialPort1.PortName)); }
}
Anyway, this seems to work in my situation. Also, my PIC code is using "\r\n" so I am actually sending a {10} and a {13} pair. Hope this helps, Adam
Hey Adam, Looks like it was searching for a 10 and 13, but it wanted them as a 13, then a 10. Thanks to everyone who was kind enough to respond and offer help to me. I'll probably have more questions as time goes on and now that I have a baseline I can start to implement the other good pieces of advice in this thread :)
-
Hey Luc, I tried \r and \n too :) with no luck then I was trying the string value and I tried Chr(13) as well with no luck. I will try the binary thing tonight and see what bits I am getting
-
Hi Colin, Maybe I can send it different characters for a line feed ... do you happen to know what pair of characters is it expecting? With the byte array, are you just filling it up with 8 bits, and then at the stop bit converting it to a string?
I expect it wants a carriage return followed by a line feed - 0x0d 0x0a Reading a byte array is not that low a level; the SerialPort class gives you a method to read byte data - SerialPort.Read Method (Byte[], Int32, Int32). You can use the BytesToRead property to see how many bytes there are in the buffer.