Serial Port Connection, Readline/ReadExisting Does Not Work - c#

I'm trying to make a serial connection to another machine. I'm using a Virtual Serial Port Emulator to try this. The settings that I use on hyperterminal are like the ones below. I can see the portopen is true, but I can't check whether I can write or read. When I try the ReadLine method it gives TimeoutException and when it's readExisting command it does nothing. DataReceived is never triggered too. Can you help me out with that ?
private void Page1_Load(object sender, EventArgs e)
{
//Port name can be identified by checking the ports
// section in Device Manager after connecting your device
serialPort1.PortName = "COM14"; // that one works for me
//Provide the name of port to which device is connected
//default values of hardware[check with device specification document]
serialPort1.BaudRate = 115200;
serialPort1.Parity = Parity.None;
serialPort1.DataBits = 8;
serialPort1.StopBits = StopBits.One;
serialPort1.Handshake = Handshake.None;
serialPort1.RtsEnable = true;
serialPort1.DtrEnable = true;
serialPort1.ReceivedBytesThreshold = 8;
serialPort1.ReadTimeout = 2000;
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived); //
// Writes data to the Serial Port output buffer
//opens the port
serialPort1.Open();
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
inputData = serialPort1.ReadExisting();
this.Invoke((MethodInvoker)delegate { DoUpdate(); });
}
public void DoUpdate()
{
textOutput.Text = (textOutput.Text + inputData);
}
private void btnReadExist_Click(object sender, EventArgs e)
{
if ((serialPort1.IsOpen == true))
{
serialPort1.WriteLine("something");
string read= serialPort1.ReadExisting();
//string output = serialPort1.ReadLine();
textOutput.Text += read;
}
}
private void Page1_FormClosed(object sender,System.Windows.Forms.FormClosedEventArgs e)
{
// Close the Serial Port
serialPort1.Close();
}

The problem seems to be that you're reading in two code blocks: first, directly after sending the text in the button's event. Secondly you have an event assigned that reads data when called asynchronously. You should decide which one to use and remove the other.

Related

How to save incoming data from serial port to a text file in C#

I have two buttons on my window.
By clicking the start button I want to open the port and
see the data in the textbox and at the same time i want to save this data in Another empty text file line by line.
And by clicking the stop button the program just stops saving the data but still shows the incoming data from serial port in the textbox. Can someone help? My code for start and stop button looks like:
private void buttonStart_Click(object sender, EventArgs e)
{
serialPort1.PortName = pp.get_text();
string Brate = pp.get_rate();
serialPort1.BaudRate = Convert.ToInt32(Brate);
serialPort1.Open();
if (serialPort1.IsOpen)
{
buttonStart.Enabled = false;
buttonStop.Enabled = true;
textBox1.ReadOnly = false;
}
}
private void buttonStop_Click(object sender, EventArgs e)
{
string Fname = pp.get_filename();
System.IO.File.WriteAllText(Fname, this.textBox1.Text);
}
1) You need to register to DataRecieved event of serial port to receive response from SerialPort instance.
sp = new SerialPort();
sp.DataReceived += sp_DataReceived;
Then, in sp_DataRecieved:
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// this the read buffer
byte[] buff = new byte[9600];
int readByteCount = sp.BaseStream.Read(buff, 0, sp.BytesToRead);
// you can specify other encodings, or use default
string response = System.Text.Encoding.UTF8.GetString(buff);
// you need to implement AppendToFile ;)
AppendToFile(String.Format("response :{0}",response));
// Or, just send sp.ReadExisting();
AppendToFile(sp.ReadExisting());
}
2) You will receive data if there is still data in read buffer of SerialPort instance. After closing port, you need to deregister from DataReceived event.
sp -= sp_DataRecieved;
UPDATE
You can use this method to append to file
private void AppendToFile(string toAppend)
{
string myFilePath = #"C:\Test.txt";
File.AppendAllText(myFilePath, toAppend + Environment.NewLine);
}

c# Serial comms Read data and add to an array

I have got myself a little lost with this Windows forms application:(
I have a stream of data arriving at a serial port in the format of \W0987654321\L555666444\W3456789900\L9842429009 and so it repeats with different values for \L and \W
I need to split out the \W and \L values and add them to an array which is to expand as needed. and then plot them on a graph in real time.
Where i'm lost is how to read the port to get each complete value once it has arrived and not truncate it. I just can't get my brain around this so any help would be great...
I open the port thus:
port.PortName = "COM9";
port.BaudRate = 38400;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.DtrEnable = false;
port.Handshake = Handshake.None;
port.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(port_DataReceived_1);
port.Open();
textBox1.Clear();
port.DiscardInBuffer();
port.DtrEnable = true;
Currently i have it all writing to a text box:
private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
InputData = port.ReadExisting();
if (InputData != String.Empty)
{
this.BeginInvoke(new SetTextCallback(SetText), new object[] { InputData });
}
}
private void SetText(string text)
{
this.textBox1.AppendText(text);
}
which shows all the data OK
var readQueue = string.Empty;
private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
readQueue += port.ReadExisting();
while (readQueue.Substring(1).Contains(#"\"))
{
var slashPos = readQueue.IndexOf(#"\",1);
var completeEntry = readQueue.Substring(0, slashPos);
Console.WriteLine(completeEntry);
readQueue = readQueue.Substring(slashPos);
}
}

C# serial connection not working

I am trying to send ASCII caracters to a VideoJet Excel 170i printer, via a RS-232 cable (Serial)
When I am using the test program, i have no problem getting a response from the printer, i can change the status of the printer.
This is the code i've made
public partial class Form1 : Form
{
private SerialPort port = new SerialPort("COM1");
private delegate void SetTextDeleg(string data);
public Form1()
{
InitializeComponent();
}
private void addtoText(string text)
{
this.richTextBox1.Text = this.richTextBox1.Text + "\n" + text;
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
port.BaudRate = 9600;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.DataBits = 8;
port.Handshake = Handshake.None;
port.ReadTimeout = 2000;
port.WriteTimeout = 500;
port.DtrEnable = true;
port.RtsEnable = true;
port.Open();
port.DataReceived += DataReceivedHandler;
addtoText("Port is ready");
}
catch (Exception ex)
{
//Console.WriteLine("Error opening my port: {0}", ex.Message);
addtoText("Error opening my port: {0}" + ex.Message);
}
}
public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
System.Threading.Thread.Sleep(500);
string indata = sp.ReadExisting();
this.BeginInvoke(new SetTextDeleg(DisplayToUI), new object[] { indata });
}
private void DisplayToUI(string displayData)
{
addtoText(displayData);
}
private void button1_Click(object sender, EventArgs e)
{
port.Write(tbxAscii.Text);
}
private void Form1_Leave(object sender, EventArgs e)
{
port.Close();
}
}
I need to sent ASCII caracters to the printer, like
[1B][01][09]
To turn the printer to Print Mode.
The printer is supposed to respond, i get no response, and the printer doesn't change its status.
I have a program made to test the serial connection made by the printer, and i can see that all the settings are OK (Baud rate, Parity... port), and indeed on port COM1.
So i think that my port.write is not sending any info to the printer... or maybe i'm sending corrup info and i'm not reading the response of the printer.
are you sure that you want to send [1B][01][09] or do you want to send that byte sequence 0x1b,0x01,0x09
just to see if this works, send the following in you click handler
private void button1_Click(object sender, EventArgs e)
{
var bytes = new byte[] { 0x1b, 0x01, 0x09 };
port.Write(bytes, 0, bytes.Length);
port.Flush(); // make sure everything is written
}
reading has to be changed, to handle bytes
SerialPort sp = (SerialPort)sender;
System.Threading.Thread.Sleep(500);
var available = sp.BytesToRead; // check how many bytes are ready to be read
if (available < 1)
return;
var buffer = new byte[available];
sp.Read(buffer, 0, available);
var indata = BitConverter.ToString(buffer); // convert bytes to a hex representation
this.BeginInvoke(new SetTextDeleg(DisplayToUI), new object[] { indata });

DataReceived EventHandler works only once

I am new to stackoverflow. I am having a problem with VC# Serial Communication. I need t receive data conyinuously from serial port but my code works only once. That is if I send "This is a Serial Comm Project". The data is received as expected but if I send the data again it doesn't work. Please provide a solution.
private void button1_Click(object sender, EventArgs e)
{
mySerialPort.PortName = cbxCOMPort.Text;
mySerialPort.BaudRate = int.Parse(cbxBaudrate.Text);
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.RequestToSend;
mySerialPort.ReadTimeout = int.Parse(cbxTimeout.Text);
mySerialPort.WriteTimeout = 2000;
mySerialPort.DtrEnable = true;
mySerialPort.RtsEnable = true;
mySerialPort.Encoding = Encoding.ASCII;
mySerialPort.NewLine = "\r\n";
mySerialPort.ReadBufferSize = 512;
mySerialPort.DataReceived += port_DataReceived;
mySerialPort.Open();
button1.Enabled = false;
button2.Enabled = true;
gbxMsgDel.Enabled = true;
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{// Event for receiving data
// Read the buffer to text box.
this.Invoke(new EventHandler(DoUpdate));
}
private void DoUpdate(object s, EventArgs e)
{
receivedMessage += mySerialPort.ReadExisting();
}
receivedMessage is a private string type. It is private to the class.
I had a similar problem before...
From MSDN
"The DataReceived event is not guaranteed to be raised for every byte
received"
One option is to use a timer to check available data instead of the event, something like this:
private void checkPortDataTimer_Tick(object sender, EventArgs e)
{
//You may want to check available bytes instead of this.
string recievedData = comPort.ReadExisting();
if (!string.IsNullOrEmpty(recievedData))
someTextBox.Text += recievedData;
}
Cheers

Reading from SerialPort; Error when I close and then open application

I created application for reading from Serial Port and it works just fine. But the problem occure when I close the application and run it again. Suddenly reading from Serial port stops working. I have to disconnect and connect USB to fix that.
This is my code:
namespace Serial
{
public partial class Main : Form
{
SerialPort mainSerialPort = new SerialPort();
public Main()
{
InitializeComponent();
}
delegate void SetTextCallback(string text);
private void buttonOpen_Click(object sender, EventArgs e)
{
mainSerialPort.PortName = "COM" + numericPort.Value.ToString();
mainSerialPort.BaudRate = 115200;
mainSerialPort.Parity = Parity.None;
mainSerialPort.StopBits = StopBits.One;
mainSerialPort.DataBits = 8;
mainSerialPort.Handshake = Handshake.None;
mainSerialPort.DataReceived += DataReceived_Read;
try{
mainSerialPort.Open();
}catch (Exception ex){
labelStatus.Text = ex.GetType().ToString();
}
if (mainSerialPort.IsOpen == true){
numericPort.BackColor = Color.Green;
labelStatus.Text = "Port je otevřen!";
}else{
numericPort.BackColor = Color.Red;
}
}
private void DataReceived_Read(object sender, SerialDataReceivedEventArgs e)
{
SerialPort mySerial = (SerialPort)sender;
if (this.InvokeRequired){
listBoxRead.Invoke(new MethodInvoker(delegate {
listBoxRead.Items.Add(mySerial.ReadExisting());
listBoxRead.SelectedIndex = listBoxRead.Items.Count - 1;
}));
}
}
private void Main_FormClosed(object sender, FormClosedEventArgs e)
{
mainSerialPort.DataReceived -= DataReceived_Read;
mainSerialPort.Close();
}
}
}
USB and serial ports are unmanaged ressources. You have to dispose it!. A simple "Close" on FormClosed will not do the same.
I think it has to do with some resources not properly freed up. Try calling Dispose method
mainSerialPort.Close();
mainSerialPort.Dispose();

Categories