i am sending Sensor information with a NUCLEOF411RE to my PC. I receive this data on the COM98 with a BaudRate of 115200. Now i want to program a Windows Application that will split my string and put it on my textboxes. until now i display the data with a Button_click event. It puts values on the Textboxes that actually are the real values. But if i move my Sensor and klick the button again there should be a lot more different values, but there are the same values on the textboxes. In addition i want to refresh the textboxes automatically and not with a button click.
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 BNO080
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
getAvailablePorts();
}
public string comport;
SerialPort serial = new SerialPort();
void getAvailablePorts()
{
String[] ports = SerialPort.GetPortNames();
comboBox1.Items.AddRange(ports);
comport = comboBox1.Text;
}
private void button1_Click(object sender, EventArgs e)
{
try
{
if(comboBox1.Text=="" || textBox6.Text=="")
{
MessageBox.Show("Please Select Port Settings");
}
else
{
serial.PortName = comboBox1.Text;
serial.BaudRate = Convert.ToInt32(textBox6.Text);
serial.Parity = Parity.None;
serial.StopBits = StopBits.One;
serial.DataBits = 8;
serial.Handshake = Handshake.None;
serial.Open();
MessageBox.Show("connected!");
}
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Unauthorised Access");
}
}
private void button2_Click(object sender, EventArgs e)
{
textBox1.Clear();
textBox2.Clear();
textBox3.Clear();
textBox4.Clear();
textBox5.Clear();
MessageBox.Show("connection closed!");
serial.Close();
}
private void button3_Click(object sender, EventArgs e)
{
try
{
textBox5.Text = serial.ReadLine();
/*String[] Stringsizes = A.Split(new char[] {' '});
textBox1.Text = Stringsizes[0];
textBox2.Text = Stringsizes[1];
textBox3.Text = Stringsizes[2];
textBox4.Text = Stringsizes[3];*/
// textBox5.Text = A;
//Array.Clear(Stringsizes, 0, 3);
}
catch (Exception) { }
}
}
}
can someone help me?
Can you give more information why you use the Button_Click Event to read the text? Maybe it is a possible way for you to subscribe for the DataReceived-Event of the COM-port?
It would look something like this:
serial.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
string receivedString = serial.ReadExisting();
//Do something here...
}
I'd do a couple things. First subscribe to the DataReceived event on the serial port. This event handler will get called when there is data available on the serial port. Then in the event handler you can read from the serial port and add it to your textbox. You can't add it directly (see the AppendText function) because the event handler is called with a different thread, only the UI thread can update UI components (or you'll get a cross-thread exception).
...
public Form1()
{
InitializeComponent();
getAvailablePorts();
// Subscribe to the DataReceived event. Our function Serial_DataReceived
// will be called whenever there's data available on the serial port.
serial.DataReceived += Serial_DataReceived;
}
// Appends the given text to the given textbox in a way that is cross-thread
// safe. This can be called by any thread, not just the UI thread.
private void AppendText(TextBox textBox, string text)
{
// If Invoke is required, i.e. we're not running on the UI thread, then
// we need to invoke it so that this function gets run again but on the UI
// thread.
if (textBox.InvokeRequired)
{
textBox.BeginInvoke(new Action(() => AppendText(textBox, text)));
}
// We're on the UI thread, we can append the new text.
else
{
textBox.Text += text;
}
}
// Gets called whenever we receive data on the serial port.
private void Serial_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
string serialData = serial.ReadExisting();
AppendText(textBox5, serialData);
}
Because i want to add an rotating 3D cube i decided to switch to WPF. I heard it is much easier to implement a 3D graphic there. So i copied my code to the new WPF project. But now i got already problems to visualize my values on the Textboxes. It doesnt work. It looks like the Evenhandler did not fire an event while receiving Data from the com port.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;
using System.Drawing;
namespace cube
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
getAvailablePorts();
serial.DataReceived += Serial_DataReceived;
}
public bool button3clicked = false;
public bool button4clicked = false;
public bool button5clicked = false;
SerialPort serial = new SerialPort();
void getAvailablePorts()
{
List<string> Itemlist = new List<string>();
String[] ports = SerialPort.GetPortNames();
Itemlist.AddRange(ports);
comboBox1.ItemsSource = Itemlist;
}
private void button1_Click_1(object sender, EventArgs e)
{
try
{
if (comboBox1.Text == "" || textBox6.Text == "")
{
MessageBox.Show("Please Select Port Settings");
}
else
{
serial.PortName = comboBox1.Text;
serial.BaudRate = Convert.ToInt32(textBox6.Text);
serial.Parity = Parity.None;
serial.StopBits = StopBits.One;
serial.DataBits = 8;
serial.Handshake = Handshake.None;
serial.Open();
MessageBox.Show("connected!");
}
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Unauthorised Access");
}
}
private void button2_Click_1(object sender, EventArgs e)
{
textBox1.Clear();
textBox2.Clear();
textBox3.Clear();
textBox4.Clear();
textBox5.Clear();
MessageBox.Show("connection closed!");
serial.Close();
textBox1.Text = "test";
}
private void AppendText(string[] text)
{
try
{
textBox1.Text = text[0];
textBox2.Text = text[1];
textBox3.Text = text[2];
textBox4.Text = text[3];
}
catch (Exception) { }
}
private void Safe_Position1(TextBox tBr1, TextBox tBi1, TextBox tBj1, TextBox tBk1, string[] text)
{
if (button3clicked == true)
{
tBr1.Text = text[0];
tBi1.Text = text[1];
tBj1.Text = text[2];
tBk1.Text = text[3];
button3clicked = false;
}
}
private void Safe_Position2(TextBox tBr2, TextBox tBi2, TextBox tBj2, TextBox tBk2, string[] text)
{
if (button4clicked == true)
{
tBr2.Text = text[0];
tBi2.Text = text[1];
tBj2.Text = text[2];
tBk2.Text = text[3];
button4clicked = false;
}
}
private void Safe_Position3(TextBox tBr3, TextBox tBi3, TextBox tBj3, TextBox tBk3, string[] text)
{
if (button5clicked == true)
{
tBr3.Text = text[0];
tBi3.Text = text[1];
tBj3.Text = text[2];
tBk3.Text = text[3];
button5clicked = false;
}
}
private void Serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string serialData = serial.ReadLine();
String[] text = serialData.Split(new char[] { ' ' });
AppendText(text);
Safe_Position1(textBox5, textBox7, textBox8, textBox9, text);
Safe_Position2(textBox10, textBox11, textBox12, textBox13, text);
Safe_Position3(textBox14, textBox15, textBox16, textBox17, text);
}
private void button3_Click(object sender, EventArgs e)
{
button3clicked = true;
}
private void button4_Click(object sender, EventArgs e)
{
button4clicked = true;
}
private void button5_Click(object sender, EventArgs e)
{
button5clicked = true;
}
}
}
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();
}
}
}
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.Net;
using System.IO;
using HtmlAgilityPack;
using mshtml;
using System.Text.RegularExpressions;
namespace Extract_Images
{
public partial class Form1 : Form
{
private string[] linkstoextract;
private int numberoflinks;
private int currentLinkNumber = 0;
private string mainlink;
private WebClient client;
private WebBrowser webBrowser1;
private string htmlCode;
private bool pagesorimages = false;
public Form1()
{
InitializeComponent();
webBrowser1 = new WebBrowser();
webBrowser1.ScriptErrorsSuppressed = true;
webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
label1.Text = "Number of links: ";
mainlink = "http://www.test.com/";
numberoflinks = 13;
backgroundWorker1.RunWorkerAsync();
}
private void ProcessNextLink()
{
if (currentLinkNumber < numberoflinks)
{
currentLinkNumber++;
string linktonav = mainlink + "index"+currentLinkNumber.ToString() + ".html";
pagesorimages = false;
backgroundWorker1.ReportProgress(0,currentLinkNumber);
webBrowser1.Navigate(linktonav);
}
}
int count = 0;
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
mshtml.HTMLDocument objHtmlDoc = (mshtml.HTMLDocument)webBrowser1.Document.DomDocument;
string pageSource = objHtmlDoc.documentElement.innerHTML;
List<string> links = new List<string>();
string[] hrefs = this.webBrowser1.Document.Links.Cast<HtmlElement>()
.Select(a => a.GetAttribute("href")).Where(h => h.Contains(".jpg")).ToArray();
foreach(string a in hrefs)
{
using (WebClient client = new WebClient())
{
client.DownloadFile(a, #"C:\Images\file" + count + ".jpg");
}
count ++;
pagesorimages = true;
backgroundWorker1.ReportProgress(0, count);
}
//ProcessNextLink();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ProcessNextLink();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (pagesorimages == false)
{
label1.Text = e.UserState.ToString();
}
if (pagesorimages == true)
{
label2.Text = e.UserState.ToString();
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
}
}
The exception is on the second ReportProgress:
backgroundWorker1.ReportProgress(0, count);
This operation has already had OperationCompleted called on it and further calls are illegal
What i want to do is to report first the current page number in this case it's 1 to label1.
And then to report the number of downloaded images in this page to label2.
Then to move to the next page with the method ProcessNextLink(); and again report the page number it should be 2 and then to report the number of images downloaded in page 2.
But i'm getting this exception already on the first page.
It was working fine without the backgroundworker in the event webBrowser1_DocumentCompleted i called ProcessNextLink(); in the bottom and it was working fine. But with the backgroundworker it's not working.
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...