can anybody check below codes for C#. There is a issue at float sıcaklık = Convert.ToByte(seriPort.ReadExisting()); But I couldn't find out what is wrong? I guess SerialPort couldn't get the data.
public partial class Form1 : Form
{
SerialPort seriPort;
public Form1()
{
InitializeComponent();
seriPort = new SerialPort();
seriPort.BaudRate = 9600;
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
try
{
seriPort.PortName = textBox1.Text;
if (!seriPort.IsOpen)
MessageBox.Show("Bağlantı Kuruldu");
}
catch
{
MessageBox.Show("Bağlantı Kurulmadı!");
}
}
private void timer1_Tick(object sender, EventArgs e)
{
try
{
seriPort.Write("temperature");
float sıcaklık = Convert.ToByte(seriPort.ReadExisting());
textBox2.Text = sıcaklık.ToString();
comboBox1.Items.Add(textBox2.Text);
System.Threading.Thread.Sleep(100);
}
catch (Exception) {}
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Stop();
seriPort.Close();
}
}
First of all. After assigning the Name to the port you need to open it so that communication can take place:
seriPort.PortName = textBox1.Text;
// open the port
seriPort.Open();
Second thing is, that communication needs time to take place. Imagine you talk to someone. You ask him for the current temperature. Then you have to wait until your partner has spoken until the end. Only then you will have your desired information, which you can use.
Since you stick here to a synchronous approach you have to give the device as much time as it needs to answer. You could just wait:
seriPort.Write("temperature");
// wait for the response
System.Threading.Thread.Sleep(2000);
float sıcaklık = Convert.ToByte(seriPort.ReadExisting());
I would not really recommend this synchronous approach, but rather use the DataReceived. It will be fired when your device sends you data und you have received it.
SerialPort port = new SerialPort();
port.DataReceived += Port_DataReceived;
private static void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
float sıcaklık = Convert.ToByte(seriPort.ReadExisting());
// do what ever you want with this value
}
Hope that helps
Related
There's some outdated software that's used to control the scoreboard at my local athletics track and I've been tasked with creating a new advanced one. However, I cannot seem to get the scoreboard to do what I ask it to do.
I've installed the original software to the my laptop and it works fine, however, when I run my test software that sends data to the board through the serial port, it isn't doing what I want.
I have the "Scoreboard Data Protocol" supplied by the manufacturer and I've been following this. I will supply the code to my test program that I've been using to see if I can get it to work and I will also supply the Data Protocol.
In the text box, I type 010D0201SPAIN and 003C630 and send it to the board and this doesn't work.
public partial class Form1 : Form
{
private SerialPort m_port;
public Form1()
{
InitializeComponent();
m_list.Items.AddRange(SerialPort.GetPortNames()); // Adds ports to combobox
m_port = new SerialPort();
m_port.BaudRate = 9600;
m_port.DataBits = 8;
m_port.Parity = Parity.Even;
m_port.StopBits = StopBits.One;
//m_port.Handshake = Handshake.None;
m_port.Encoding = new ASCIIEncoding();
m_port.RtsEnable = true;
m_port.DtrEnable = true;
m_port.ReceivedBytesThreshold = 1;
m_port.DataReceived += DataReceivedEvent;
}
private void button1_Click(object sender, EventArgs e)
{
m_port.Close();
m_port.PortName = (string)m_list.SelectedItem;
try
{
m_port.Open();
m_sendbutton.Enabled = true;
button2.Enabled = true;
}catch(UnauthorizedAccessException ex)
{
MessageBox.Show(ex.Message);
}
}
private void m_sendbutton_Click(object sender, EventArgs e)
{
m_port.Write(m_textbox.Text);
}
private void DataReceivedEvent(object sender, SerialDataReceivedEventArgs args)
{
Invoke(new EventHandler(DoUpdate));
}
private void DoUpdate(object s, EventArgs e)
{
label1.Text += m_port.ReadLine();
}
private void button2_Click(object sender, EventArgs e)
{
byte[] r_bytes = Encoding.ASCII.GetBytes(m_textbox.Text);
m_port.Write(r_bytes, 0, r_bytes.Length);
}
}
}
Scoreboard Data Protocol
Code: https://hastebin.com/epirobuduv.cs
Here's how to add STX and ETX around your message, in a byte array.
private void button2_Click(object sender, EventArgs e)
{
var msg = Encoding.ASCII.GetBytes(m_textbox.Text).ToList();
msg.Insert(0, 0x02); // STX at the start
msg.Add(0x03); // ETX at the end
m_port.Write(msg.ToArray(), 0, msg.Count);
}
I am working on a small winform application that reads input from a barcode scanner on a virtual com port and writes the data back to a text box on my winform. I am new to C# so have been struggling through. My current code is below and adapted from here
namespace Barcode_Scanner
{
public partial class Form1 : Form
{
SerialPort sp;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
comboBox1.DataSource = ports;
Application.DoEvents();
}
private void btn_getComData_Click(object sender, EventArgs e)
{
try
{
if (!sp.IsOpen)
sp.Open();
sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
}
catch (Exception ex)
{
MessageBox.Show("There was a problem with the Serial Port: " + ex.Message, "Error!");
}
}
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
sp = (SerialPort)sender;
string data = sp.ReadExisting();
txt_comData.Text = data;
Application.DoEvents();
}
private void button1_Click(object sender, EventArgs e)
{
// Makes sure serial port is open before trying to write
string portname = comboBox1.SelectedItem.ToString();
sp = new SerialPort(portname, 9600, Parity.None, 8, StopBits.One);
sp.Handshake = Handshake.None;
sp.Open();
}
private void button2_Click(object sender, EventArgs e)
{
sp.Close();
}
}
}
The full string I am trying to scan is "3894038" but I am only able to get the textbox to display one character at a time in the text box. I suspect it has something to do with my .ReadExisting command, but I am a bit perplexed on how to proceed. Is there something wrong with my code?
Thanks for the help in advance.
Marshall
There are quite a few issues with your code. The issue you described is caused by the fact that you are assigning the value of ReadExisting to the textbox rather than appending it. I've fixed that and several other issues below.
Notes:
Use AppendText instead of assigning to add new data to the end of the text box's text
There is virtually never a good reason to call Application.DoEvents
You open the serial port in an inconsistent way in two different places
You already have sp in defined at the class level; there's no need to hide it with a cast of the event sender.
Fixed code:
namespace Barcode_Scanner
{
public partial class Form1 : Form
{
SerialPort sp;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
comboBox1.DataSource = ports;
}
private void btn_getComData_Click(object sender, EventArgs e)
{
try
{
if (!sp.IsOpen)
{
button1_Click(null, EventArgs.Empty);
}
}
catch (Exception ex)
{
MessageBox.Show("There was a problem with the Serial Port: " + ex.Message, "Error!");
}
}
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string data = sp.ReadExisting();
txt_comData.Appendtext(data);
}
private void button1_Click(object sender, EventArgs e)
{
// Makes sure serial port is open before trying to write
string portname = comboBox1.SelectedItem.ToString();
sp = new SerialPort(portname, 9600, Parity.None, 8, StopBits.One);
sp.Handshake = Handshake.None;
sp.Open();
sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
}
private void button2_Click(object sender, EventArgs e)
{
sp.Close();
}
}
}
I have a program that allows several Arduinos to communicate via Serial Port. For example if Arduino1 want to communicate with Arduino3 the user sends a string from Arduino1 and this string appears on Arduino3 and so on. This is working good with SerialMonitor.
The problem is when I try to do the same in my C# application (nothing appears). I tryed this:
//(...)
comPort1.Open();
//(...)
private void comPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string inData = comPort1.ReadLine();
msgBoxLog.AppendText(inData); // msgBoxLog = textBox with data received/sent
}
//(...)
private void sendButton_Click(object sender, EventArgs e)
{
string my_str = "my string";
msgBoxLog.AppendText(my_str + "\r\n");
comPort1.WriteLine(my_str + "\r\n");
}
Some notes:
RtsEnable and DtrEnable are both active
BaudRate (Arduino / C#) = 1200
Is baudrate value a problem? I must use this value but I'm not sure if it is accepted by C#. I also tryed something like this but with no success.
I have a vague memory about not being able to access UI controls through the dataReceived event. Try this.
private void comPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string inData = comPort1.ReadLine();
this.Invoke(new EventHandler(processData));
}
private void processData(object sender, EventArgs e)
{
msgBoxLog.AppendText(inData);
}
Do you have proper event handler enabled, like in this example?
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived.aspx
p.s. I'm using "dumb" delay in my software, between write and read serial port, and it's worked fine. Like this:
serialPort1.Write(Data, 0, Data.Length);
System.Threading.Thread.Sleep(500);
try
{
serialPort1.Read(Data2, 0, Data2.Length);
}
catch (TimeoutException)
{
errorProvider1.SetError(maskedTextBox1, "timeout");
}
catch (ArgumentNullException)
{
errorProvider1.SetError(maskedTextBox1, "no answer");
}
I have to create an aplication which reads the registers from a PLC every 200ms. To do that I am using something like:
SerialPort port = new SerialPort();
private void Form1_Load(object sender, EventArgs e)
{
port.ReceivedBytesThreshold = 21;
timer1.Interval = 200;
timer1.Start();
}
private void ProcessTimer_Tick(object sender, EventArgs e)
{
if (dataReceived)
{
dataReceived = false;
port.Read(buffer_rx, 0, 21);
TranslateValues();
}
if (port.IsOpen && connectected)
{
// sends command for a new reading
port.Write(buffer_tx, 0, length);
}
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Invoke(new EventHandler(DoUpdate));
}
void DoUpdate(object sender, EventArgs e)
{
dataReceived = true;
}
The problem is that my application freezes from time to time. When I debug this, the debugger points me to port.Read(), but doesn't throw any exceptions.
I have tried using a try-catch block but nothing was caught, and also made time1.Interval = 2000, but it didn't work either.
My question is, why is my application freezing at port.Read(), but not catching any exceptions? How can I fix this?
I am working on code that connects to a serial port of a stepper motor. I send a command to the stepper motor via textBox2 and am attempting to read in the return data from the command to textBox3. I am able to make a connection, send the command, and receive the data. But after my GUI populates textBox3 with the returned serial data it freezes.
I believe that the code is getting stuck in the try loop but I don't know how to break out of it. Here is my code:
private void button3_Click(object sender, EventArgs e)
{
if (isConnectedMotor)
{
string command = textBox2.Text;
portMotor.Write(command + "\r\n");
portMotor.DiscardInBuffer();
while (true)
{
try
{
string return_data = portMotor.ReadLine();
textBox3.AppendText(return_data);
textBox3.AppendText(Environment.NewLine);
}
catch(TimeoutException)
{
break;
}
}
}
}
DataReceived Code:
private void connectToMotor()
{
isConnectedMotor = true;
string selectedPort = comboBox2.GetItemText(comboBox2.SelectedItem);
portMotor = new SerialPort(selectedPort, 9600, Parity.None, 8, StopBits.One);
portMotor.RtsEnable = true;
portMotor.DtrEnable = true;
portMotor.Open();
portMotor.DiscardInBuffer();
portMotor.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
button4.Text = "Disconnect";
enableControlsMotor();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
textBox3.AppendText(indata);
textBox3.AppendText(Environment.NewLine);
}
I am getting an error saying:
An object reference is required for the non-static field, method, or property 'Form1.textBox3'
Invoke code:
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
portMotor.DiscardInBuffer();
incoming_data = portMotor.ReadExisting();
this.Invoke(new EventHandler(displayText));
}
private void displayText(object o, EventArgs e)
{
textBox3.Text += incoming_data;
}
Instead of looping to read data, use a DataReceived event to get at the incoming bytes asynchronously.
See the documentation and example.
Also see this question for troubleshooting.
P.S. Here is a code sample to avoid locking up the UI.
private void ReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
var incoming_data = portMotor.ReadExisting();
// this is executing on a separate thread - so throw it on the UI thread
Invoke(new Action(() => {
textBox3.Text += incoming_data;
}));
}