This question already has answers here:
SerialPort not receiving any data
(3 answers)
Closed 7 years ago.
I am using a serial port application to send a command with Unicode control characters and am having no success. When I send the same command in hyperterminal or Putty the communication works so I am curious if these two programs write out an array of bytes or Unicode characters or even a string. If I mimic what they do, I might have success... Also I noticed that the serial port property I pulled out of the toolbox in Visual Studio was listed as using a different COM port that I write in my code, is this why I'm getting no response or does my code override that? When conducting loopback tests, I get the output of the correct command with the control characters as well so I cant figure out what I'm doing wrong. This is .NET 2.0 Framework FYI
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;
using System.Threading;
namespace SimpleSerial
{
public partial class Form1 : Form
{
string RxString;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
serialPort1.PortName = "COM3";
serialPort1.BaudRate = 9600;
serialPort1.Parity = Parity.None;
serialPort1.DataBits = 8;
serialPort1.StopBits = StopBits.One;
serialPort1.Handshake = Handshake.None;
serialPort1.ReadTimeout = 500;
serialPort1.WriteTimeout = 500;
serialPort1.Open();
if (serialPort1.IsOpen)
{
buttonStart.Enabled = false;
buttonStop.Enabled = true;
textBox1.ReadOnly = false;
}
}
const char STX = '\u0002';
const char ETX = '\u0003';
readonly string pull_shelf_104 = string.Format("{0}01P00104##{1}" , STX, ETX);
private byte[] WrapString(string pull_shelf_104)
{
return System.Text.Encoding.ASCII.GetBytes(pull_shelf_104);
}
private void linkLabel_HC1_100_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if (serialPort1.IsOpen)
{
byte[] data = WrapString(pull_shelf_104);
serialPort1.Write(data, 0, data.Length);
}
}
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();
}
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));
}
}
}
The comments above helped me solve the issue, thank you for your help! I needed to enable both RTS and DTS in my code, listing the COM ports was not the issue although I'm sure it is in some cases. Here's my code for anyone with similar issues.
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;
using System.Threading;
namespace SimpleSerial
{
public partial class Form1 : Form
{
string RxString;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
serialPort1.PortName = "COM3";
serialPort1.BaudRate = 9600;
serialPort1.Parity = Parity.None;
serialPort1.DataBits = 8;
serialPort1.StopBits = StopBits.One;
serialPort1.Handshake = Handshake.None;
serialPort1.RtsEnable = true;
serialPort1.DtrEnable = true;
serialPort1.ReadTimeout = 2000;
serialPort1.WriteTimeout = 2000;
serialPort1.Open();
if (serialPort1.IsOpen)
{
buttonStart.Enabled = false;
buttonStop.Enabled = true;
textBox1.ReadOnly = false;
}
}
const char STX = '\u0002';
const char ETX = '\u0003';
readonly string pull_shelf_104 = string.Format("{0}01P00204##{1}" , STX, ETX);
private byte[] WrapString(string pull_shelf_104)
{
return System.Text.Encoding.ASCII.GetBytes(pull_shelf_104);
}
private void linkLabel_HC1_100_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if (serialPort1.IsOpen)
{
byte[] data = WrapString(pull_shelf_104);
serialPort1.Write(data, 0, data.Length);
}
}
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();
}
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));
}
}
}
Related
I'm designing a GUI that receives voltage and current readings from a drone and displays it in text books.
I receive data in the form (H,0.00,0.00,)
I used the split function to read the values.
but when I start the program I get the error message
"system.indexOutOfRangeException:"index was outside the bound of the array"
I'm a beginner in C#. any suggestions on how to resolve the issue
...using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace G_Station
{
public partial class Form1 : Form
{
string ArduData = "";
string[] pot;
string current = "";
string voltage = "";
public Form1()
{
InitializeComponent();
}
private void ConnectBtn_Click(object sender, EventArgs e)
{
try
{
serialPort1.PortName = PortCmb.Text;
serialPort1.BaudRate = Convert.ToInt32(BaudCmb.Text);
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
serialPort1.Encoding = System.Text.Encoding.GetEncoding(28591);
serialPort1.DataBits = 8;
serialPort1.Open();
ConnectBtn.Enabled = false;
DisconnectBtn.Enabled = true;
timer1.Enabled = true;
}
catch (Exception errName)
{
MessageBox.Show(errName.ToString());
}
}
private void DisconnectBtn_Click(object sender, EventArgs e)
{
try
{
//serialPort1.PortName = PortCmb.Text;
//serialPort1.BaudRate = Convert.ToInt32(BaudCmb.Text);
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
serialPort1.Encoding = System.Text.Encoding.GetEncoding(28591);
serialPort1.DataBits = 8;
serialPort1.Close();
ConnectBtn.Enabled = true;
DisconnectBtn.Enabled = false;
timer1.Enabled = false;
}
catch (Exception errName)
{
MessageBox.Show(errName.ToString());
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
if (serialPort1.BytesToRead < 3 )
{
ArduData = "H,00.0,00.0,";
}
else
{
ArduData = serialPort1.ReadLine();
}
pot = ArduData.Split(',');
current = pot[2];
voltage = pot[1];
VoltLbl.Text = current;
CurrentLbl.Text = voltage;
}
private void VoltLbl_Click(object sender, EventArgs e)
{
}
private void CurrentLbl_Click(object sender, EventArgs e)
{
}
}
}...
Dear experts i am trying to access the serial port programmatically through C#.I have interface a gsm module serially for communication.problem i am facing is if data is small m getting it perfectly but when i am reading the all messages{AT+CMGL="ALL"} i am receiving only half data on contrary in third party application i am receiving the whole data.
so want to know where the problem is coming whether i have to inc the size of input buffer where the Readexisting() function storing data or have to increase the timeout?.Last i checked we can not vary the size of buffer. please help.
my code is as follows:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace SERIAL_PORT
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
getavailableports();
}
void getavailableports()
{
string[] ports = SerialPort.GetPortNames();
comboBox1.Items.AddRange(ports);
}
private void Button1_Click(object sender, EventArgs e)
{
try
{
if (comboBox1.Text == "" || comboBox2.Text == "")
{
MessageBox.Show("please select port");
}
else
{
serialPort1.PortName = comboBox1.Text;
serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
serialPort1.Open();
progressBar1.Value = 100;
// textBox2.Enabled = true;
button6.Enabled = true;
button7.Enabled = true;
textBox1.Enabled = true;
}
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("no");
}
}
private void button2_Click(object sender, EventArgs e)
{
serialPort1.Close();
progressBar1.Value = 0;
button6.Enabled = false;
button7.Enabled = false;
textBox1.Enabled = false;
//textBox2.Enabled = false;
}
private void button6_Click(object sender, EventArgs e)
{
serialPort1.WriteLine(textBox1.Text + "");
textBox1.Text = "";
}
private void button7_Click(object sender, EventArgs e)
{
richTextBox1.Text = serialPort1.ReadExisting();
}
}
}
I have an application in Visual studio, reading value from serial port and drawing it on a chart. Everything goes perfecly fine, but when I click a close button on the application (or serial port disconnect button), an error occurs:"IOException() was unhandled", and the program highlights the serial1.Readline() command. How can I handle the exception?
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;
using System.Windows.Forms.DataVisualization.Charting;
namespace usart3
{
public partial class OknoGlowne : Form
{
public OknoGlowne()
{
string[] mojePorty = SerialPort.GetPortNames();
InitializeComponent();
foreach (string port in mojePorty)
{
cmbPorty.Items.Add(port);
}
cmbBaud.Items.Add(2400);
cmbBaud.Items.Add(9600);
cmbBaud.Items.Add(19200);
btnRozlacz.Enabled = false;
}
private volatile string rxString;
//private byte[] rxByte;
private Object thisLock = new Object();
Boolean i = false;
private void btnPolacz_Click(object sender, EventArgs e)
{
i = true;
serialPort1.PortName = cmbPorty.Text;
serialPort1.BaudRate = Convert.ToInt32(cmbBaud.Text);
serialPort1.Parity = Parity.None;
serialPort1.StopBits = StopBits.One;
serialPort1.DataBits = 8;
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort1.Open();
btnPolacz.Enabled = false;
btnRozlacz.Enabled = true;
}
int rt = 0;
private void btnRozlacz_Click(object sender, EventArgs e)
{
serialPort1.Close();
btnPolacz.Enabled = true;
btnRozlacz.Enabled = false;
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
rt++;
rxString = serialPort1.ReadLine();
this.Invoke(new EventHandler(displayText));
}
private void displayText(object o, EventArgs e)
{
richTextBox1.AppendText(rxString);
this.chart1.Series["Temperatura"].Points.AddXY(rt, rxString);
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
Form2 nowy = new Form2();
nowy.Show();
}
private void textBox5_TextChanged(object sender, EventArgs e)
{
}
private void Start2_Click(object sender, EventArgs e)
{
Form2 nowy = new Form2();
nowy.Show();
}
private void button1_Click_1(object sender, EventArgs e)
{
Form2 nowy = new Form2();
nowy.Show();
}
}
}
I had similar issue.
The IOExcpection is kind of confusing because accordingly to the documentation ReadLine() is not supposed to throw this type of exception. The problem is that ReadLine is in a state of waiting for an EOL character when we close the port. Closing the port stops the thread holding ReadLine in an unsupported state.
For me the solution was to follow this port closure sequence:
Unsubscribe data_reciver method from the port.
Send a port.WriteLine("get serial number") command. The goal is to trig an EOL character in the input_buffer. This will release ReadLine.
Wait until EOL is recieved.
Close the port.
Surround your call with a try/catch block. In the catch you should code in way that you can handle the error by doing something else.
try {
rxString = serialPort1.ReadLine();
} catch (IOException e) {
// or do something else
}
EDIT:
try {
rt++;
rxString = serialPort1.ReadLine();
this.Invoke(new EventHandler(displayText));
} catch (IOException e) {
MessageBox.Show("Connection is lost");
}
I'm doing a project on serial port.. but after i changed my serial comm port into combo box selection, i cant seems to transmit anything data out. here's my codes:
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 XSP
{
public partial class Form1 : Form
{
string RxString;
byte[] buffer = Encoding.UTF8.GetBytes("RxString");
public Form1()
{
InitializeComponent();
this.Load += Form1_Load;
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
Console.ReadLine();
}
void Form1_Load(object sender, EventArgs e)
{
var serialPort1 = SerialPort.GetPortNames();
cbCommPorts.DataSource = serialPort1;
}
public static byte[] ConvertToBinary(string str)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
return encoding.GetBytes(str);
}
private void btnOpen_Click(object sender, EventArgs e)
{
if (cbCommPorts.SelectedIndex > -1)
{
MessageBox.Show(String.Format("You selected port '{0}'", cbCommPorts.SelectedItem));
Connect(cbCommPorts.SelectedItem.ToString());
}
else
{
MessageBox.Show("Please select a port first");
}
}
private void Connect(string portName)
{
var serialPort1 = new SerialPort(portName);
if (!serialPort1.IsOpen)
{
serialPort1.BaudRate = 115200;
serialPort1.Open();
btnTransmit.Enabled = true;
btn2.Enabled = true;
btn3.Enabled = true;
btnOpen.Enabled = false;
btnClose.Enabled = true;
}
}
private void btnTransmit_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
string value = "12345";
serialPort1.Write(value);
}
else serialPort1.Close();
}
private void txtReceive_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)
{
txtReceive.AppendText(RxString);
}
private void serialPort1_DataReceived
(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
RxString = serialPort1.ReadExisting();
this.Invoke(new EventHandler(DisplayText));
}
private void btnOpenFile_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = "c:\\";
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1.FilterIndex = 2;
openFileDialog1.RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
System.IO.StreamReader sr = new
System.IO.StreamReader(openFileDialog1.FileName);
MessageBox.Show(sr.ReadToEnd());
sr.Close();
}
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnClose_Click(object sender, EventArgs e)
{
serialPort1.Close();
btnOpen.Enabled = true;
btnClose.Enabled = false;
btnTransmit.Enabled = false;
btn2.Enabled = false;
btn3.Enabled = false;
}
}
}
Can someone help me to point out where my error lies in? Thanks
There are several options possible here, but we need more information to tackle this problem. To start off, make sure you are actually sending data. to do this try a breakpoint on the if statement above where you send the data. And step into the code using F10 and see whether you are actually sending any data.
If you are sending data, your code runs fine and check the receiver application. check baudrates etc...
I made a little application for my Arduino in C#. Everything works fine, but the problem is in my application. The user can chose his/hers COM port in a numericUpDown.
It works, but if the user chose the wrong port and tries to connect, it crashes, so I was thinking I need an IF statmant that gives a message. For example, the wrong port, etc., but I don't know how to make it. How can I do it?
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;
using System.IO.Ports;
namespace IO_Arduino_experiment_project
{
public partial class Form1 : Form
{
public static System.IO.Ports.SerialPort serialPort1;
private delegate void LineReceivedEvent(string line);
public Form1()
{
InitializeComponent();
button5.Enabled = false;
button2.Enabled = false;
button3.Enabled = false;
}
private void button1_Click(object sender, EventArgs e) // Connect Button
{
System.ComponentModel.IContainer components = new System.ComponentModel.Container();
serialPort1 = new System.IO.Ports.SerialPort(components); // Creating the new object.
serialPort1.PortName = "COM" + numericUpDown1.Value.ToString(); // Setting what port number.
serialPort1.BaudRate = 9600;
serialPort1.DtrEnable = true;
serialPort1.Open(); // Open the port for use.
button1.Text = "Connected.";
button1.Enabled = false;
numericUpDown1.Enabled = false;
button5.Enabled = true;
button2.Enabled = true;
button3.Enabled = true;
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (serialPort1.IsOpen) serialPort1.Close();
}
private void button2_Click(object sender, EventArgs e)
{
serialPort1.Write("1");
textBox1.Text = "LED is on!";
button2.Enabled = false;
button3.Enabled = true;
}
private void button3_Click(object sender, EventArgs e)
{
serialPort1.Write("0");
textBox1.Text = "LED is off!";
button2.Enabled = true;
button3.Enabled = false;
}
private void button4_Click(object sender, EventArgs e)
{
Close();
}
private void button5_Click(object sender, EventArgs e)
{
serialPort1.Close();
button1.Enabled = true;
numericUpDown1.Enabled = true;
}
}
}
You should really replace the numeric up/down with a ComboBox or some other list control/menu that populates when the form opens or when a refresh button is clicked (or by other automatic means such as a timer).
The ComboBox or List can be filled using the GetPortNames method:-
String[] pNames;
pNames = System.IO.Ports.SerialPort.GetPortNames();
If you want to do what you have described then you can lookup the port to see if it exists prior to attempted use using similar code:-
if (System.IO.Ports.SerialPort.GetPortNames().indexOf("COM" + thePortNum.ToString())>-1)
Note thatGetPortNames() returns a list like this:-
COM1
COM10
COM12