I'm trying to make GUI for my arduino analogread. The GUI display graph and text line of the value that arduino read. I'm using zedgraph for graphing.
I need to write "on" in the serial monitor window of arduino to start the readings. it runs well. But when I try to control via GUI I made with C# Visual
Studio, the reading won't start. it says "Access to the port 'COM3' is denied".
Here's my arduino code:
void loop() {
while (Serial.available() > 0)
{
input += (char) Serial.read(); // Read in one char at a time
delay(5);
} if (input == "on")
{
myservo.write(0);
---analog reading and Serial.println arduino---
} if (input == "off")
{
myservo.write(115);
}
}
And this is my visual studio code:
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 ZedGraph;
using System.IO.Ports;
using System.Globalization;
namespace concentrationMeasurement
{
public partial class Form1 : Form
{
private SerialPort myport;
private DateTime datetime;
private string in_data;
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
myport = new SerialPort();
myport.BaudRate = 115200;
myport.PortName = port_name.Text;
myport.Parity = Parity.None;
myport.DataBits = 8;
myport.StopBits = StopBits.One;
myport.DataReceived += myport_DataReceived;
try
{
myport.Open();
myport.WriteLine("on");
data_tb.Text = "";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message,"Error");
}
}
private void myport_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
in_data = myport.ReadLine();
this.Invoke(new EventHandler(displaydata_event));
}
private void displaydata_event(object sender, EventArgs e)
{
datetime = DateTime.Now;
string time = datetime.Hour + ":" + datetime.Minute + ":" + datetime.Second;
data_tb.AppendText(time + "\t\t" + in_data + "\n");
}
private void btnStop_Click(object sender, EventArgs e)
{
try
{
myport.Close();
}
catch (Exception ex2)
{
MessageBox.Show(ex2.Message, "Error");
}
}
private void save_btn_Click(object sender, EventArgs e)
{
try{
string pathfile = #"C:\Users\ajis.aprl\Documents\TA bgt\data_GUI\";
string filename = "concentration.txt";
System.IO.File.WriteAllText(pathfile + filename, data_tb.Text);
MessageBox.Show("Data has been saved to "+pathfile,"Save File");
}
catch (Exception ex3){
MessageBox.Show(ex3.Message, "Error");
}
}
private void Form1_Load(object sender, EventArgs e)
{
plotGraph();
SetSize();
}
private void plotGraph()
{
GraphPane myPane = zedGraphControl1.GraphPane;
myPane.Title.Text = "Concentration Growth";
myPane.XAxis.Title.Text = "time";
myPane.YAxis.Title.Text = "concentration";
}
}
}
So I got 2 problem here:
As I said, I can't run my analog reading via GUI, it says "Access to the port 'COM3' is denied".
in myPane.Title.Text, myPane.XAxis.Title.Tex, and myPane.YAxis.Title.Text, there's error in "Text" it says:
"Error 3 'string' does not contain a definition for 'Text' and no extension method 'Text' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)"
I googled everywhere but I can't find the answer. Please if anyone know what I'm missing. Can you tell me what's wrong with my code/logic? Thank you.
Related
I am testing a real-time port view for serial port.
The Form1 and debug state with always false is shown below.
When Form1 is created, the COM port list is stored in recordedPorts and timer1_Tick event is generated every 100ms, the current COM port list is read and stored in presentPorts and compared with recordedPorts. If you look at the debug state picture, you can see that the result value string[] each of GetPortNames() method is the same.
I want to display COM ports in comboBox1 in real time.
However, it could not be displayed in the comboBox1.
There was a problem in string operation, so timer1_Tick event could not be operated normally.
The first question is to know why string real-time comparison is always false,
and the second is whether there is any other way to display the serial port in real time.
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 TestSerial
{
public partial class Form1 : Form
{
string[] recordedPorts, presentPorts;
string str;
public Form1()
{
InitializeComponent();
recordedPorts = SerialPort.GetPortNames();
foreach (string PortName in recordedPorts)
{
comboBox1.Items.Add(PortName);
}
}
private void button2_Click(object sender, EventArgs e)
{
if(serialPort1.IsOpen == true)
{
serialPort1.Close();
textBox1.Text += "disconnected." + Environment.NewLine;
}
else
{
textBox1.Text += "already disconnected." + Environment.NewLine;
}
}
private void button1_Click(object sender, EventArgs e)
{
if(serialPort1.IsOpen == false)
{
serialPort1.PortName = comboBox1.SelectedItem.ToString();
serialPort1.BaudRate = 9600;
serialPort1.DataBits = 8;
serialPort1.StopBits = StopBits.One;
serialPort1.Parity = Parity.None;
//serialPort1.Open();
try
{
serialPort1.Open(); //serial port open!!!
}
catch (InvalidOperationException ex)
{
MessageBox.Show(ex.Message);
return;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
textBox1.Text += "connected." + Environment.NewLine;
serialPort1.WriteLine("abcd\r\n");
}
else
{
textBox1.Text += "already connected." + Environment.NewLine;
}
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
str = serialPort1.ReadExisting();
if(str.Length > 8)
{
textBox1.SelectedText += str + Environment.NewLine;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
presentPorts = SerialPort.GetPortNames();
if (presentPorts.Count() == 0)
{
//if(comboBox1.Items.Count != 0) comboBox1.Items.Clear();
recordedPorts = presentPorts;
return;
}
if (recordedPorts != presentPorts)
{
comboBox1.DataSource = presentPorts;
recordedPorts = presentPorts;
}
}
}
}
The debug state that is always false is as follows.
Thanks to Klaus Gütter.
I resolved this question by comparing the content of the arrays instead of the array references.
Change it to the code below and it works normally.
if (!recordedPorts.SequenceEqual(presentPorts))
//if (recordedPorts != presentPorts)
{
comboBox_port.DataSource = presentPorts;
recordedPorts = presentPorts;
}
I am doing a project in which i have to send the variable data from my console application project to windows form application( i have to write that data into textbox). I am trying to pass a variable val to my form and below code is what i tried to do but passed value(num variable in windows form) is zero instead of 1 (serial.Val in console application which is passed as argument and then i am calling the form).
Can anyone please help me with that ?
This is my windows forms code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WindowsFormsApplication2;
namespace WindowsFormsApplication2
{
public partial class Serial_comm_1 : Form
{
//private static int temp;
private DateTime Datetime;
string indata;
static SerialPort COMport;
// private static int num;
public Serial_comm_1(int num)
{
InitializeComponent();
string Port_Name = "COM3"; // Store the selected COM port name to "Port_Name" varaiable
int Baud_Rate = 9600; // Convert the string "9600" to int32 9600
COMport = new SerialPort(Port_Name, Baud_Rate);
COMport.Parity = Parity.None;
COMport.StopBits = StopBits.One;
COMport.DataBits = 8;
COMport.Handshake = Handshake.None;
COMport.RtsEnable = true;
COMport.DtrEnable = true;
TextBox_Transmit_Data.Text = num.ToString();
//try to open the port
#region
try
{
COMport.Open();
textBox_System_Log.Text = "";
}
catch (UnauthorizedAccessException SerialException) //exception that is thrown when the operating system denies access
{
MessageBox.Show(SerialException.ToString());
textBox_System_Log.Text = Port_Name + Environment.NewLine + Baud_Rate;
textBox_System_Log.Text = textBox_System_Log.Text + Environment.NewLine + SerialException.ToString();
COMport.Close();
}
catch (System.IO.IOException SerialException) // An attempt to set the state of the underlying port failed
{
MessageBox.Show(SerialException.ToString());
textBox_System_Log.Text = Port_Name + Environment.NewLine + Baud_Rate;
textBox_System_Log.Text = textBox_System_Log.Text + Environment.NewLine + SerialException.ToString();
COMport.Close();
}
catch (InvalidOperationException SerialException) // The specified port on the current instance of the SerialPort is already open
{
MessageBox.Show(SerialException.ToString());
textBox_System_Log.Text = Port_Name + Environment.NewLine + Baud_Rate;
textBox_System_Log.Text = textBox_System_Log.Text + Environment.NewLine + SerialException.ToString();
COMport.Close();
}
catch //Any other ERROR
{
MessageBox.Show("ERROR in Opening Serial PORT -- UnKnown ERROR");
COMport.Close();
}
#endregion
}
private void Button_Transmit_Data_Click(object sender, EventArgs e)
{
//Local Variables
string Port_Name = "COM3"; // Store the selected COM port name to "Port_Name" variable
int Baud_Rate = 9600; // Convert the string "9600" to int32 9600
string Data = TextBox_Transmit_Data.Text; //Store the string in Textbox to variable "Data"
COMport.ReadTimeout = 3500; //Setting ReadTimeout =3500 ms or 3.5 seconds
Console.WriteLine(COMport.IsOpen);
COMport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
//Program1 prog = new Program1();
//If we are able to open the port
if (COMport.IsOpen == true)
{
COMport.WriteLine(Data); // Send Data
textBox_System_Log.Text = Port_Name + Environment.NewLine + Baud_Rate;
textBox_System_Log.Text = textBox_System_Log.Text + Environment.NewLine + Data + " Written to Port" + Environment.NewLine;
}
else
{
TextBox_Received_Data.Enabled = true; // Enable the Receive Groupbox
MessageBox.Show("Unable to Write to COM port ");
COMport.Close();
}
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
indata = sp.ReadLine();
this.Invoke(new EventHandler(display_data_event));
}
private void display_data_event(object sender, EventArgs e)
{
Datetime = DateTime.Now;
String time = Datetime.Hour + ":" + Datetime.Minute + ":" + Datetime.Second;
textBox_System_Log.AppendText(time + "\t\t\t" + indata + Environment.NewLine);
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void textBox_Received_Data_TextChanged(object sender, EventArgs e)
{
}
private void TextBox_Transmit_Data_TextChanged(object sender, EventArgs e)
{
}
}
}
This is my trail of console application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WindowsFormsApplication2;
using System.Windows.Forms;
namespace ConsoleApplication1
{
class Program1
{
private int val;
public int Val
{
get { return val; }
set { val = value; }
}
static void Main(string[] args)
{
Program1 serial = new Program1();
serial.Val = 1;
System.Windows.Forms.Application.Run(new Serial_comm_1(serial.Val));
//Serial_comm_1 serial_form1 = new Serial_comm_1(serial.Val);
}
}
}
From your app you want to start the other app:
// Create a new Process
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = new System.Diagnostics.ProcessStartInfo();
process.StartInfo.FileName = #"C:\Projects\Temp912\bin\Debug\Temp912.exe";
process.StartInfo.Arguments = "Test Argument";
process.StartInfo.UseShellExecute = false;
process.Start();
Now from your Windows Form App, modify the Main method:
using System;
using System.Windows.Forms;
namespace Temp912
{
static class Program
{
[STAThread]
static void Main(string[] args)
{
string arg1 = "";
if ((args != null) && (args.Length > 0))
{
arg1 = args[0];
MessageBox.Show("Arg1: " + arg1, "Arg App Started With Parameter");
}
else
{
MessageBox.Show("Arg1: N/A", "Arg App Started Without Parameter");
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
If you need to pass the parameter value(s) to your Main Form, expose a property or properties on your form, and set the value(s) before you launch the form.
Edit Per Question:
Form Code
public string MyProperty { get; set; } // change the data type to int or whatever
Than in Program.cs, instead of:
Application.Run(new Form1());
Do this:
// create an instance of your form
Form1 form1 = new Form1();
// set the property or properties
form1.MyProperty = arg1;
Then call:
// this is should work, I didn't test this like the other code
Application.Run(form1);
I need some help with Background worker. I am trying to read data from a serial port (works fine with a button) the problem is that I need to continuously read from the serial port, until someone presses a button (Close button) on the form to stop reading. I tried doing this by adding a loop, but it just ran infinitely and froze up the form. I have the following code, whenever I press the button to read, a file is created, but when I press the close port button,it says
The I/O operation has been aborted because of either a thread exit or
an application request
Any ideas on how to fix this?
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.IO;
namespace SerialCommunication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
GetAvaliablePortNames();
}
bool indicator;
StreamWriter sw = new StreamWriter(#"C:\Users\slahiri\Desktop\Data\jumbo.txt");
void GetAvaliablePortNames()
{
string[] Ports = SerialPort.GetPortNames();
cmbPort.Items.AddRange(Ports);
}
private void btnOpen_Click(object sender, EventArgs e)
{
try
{
if (cmbPort.Text == "" || cmbBaud.Text == "")
{
MessageBox.Show("Please select the Port and Baud Rates");
}
else
{
serialPort1.PortName = cmbPort.Text;
serialPort1.BaudRate = Convert.ToInt32(cmbBaud.Text);
serialPort1.Open();
progressBar1.Value = 100;
groupBox2.Enabled = true;
btnRead.Enabled = true;
btnOpen.Enabled = false;
btnClose.Enabled = true;
}
}
catch (UnauthorizedAccessException)
{
txtRead.Text = "Unauthorized Acess";
}
}
private void btnClose_Click(object sender, EventArgs e)
{
serialPort1.Close();
progressBar1.Value = 0;
btnClose.Enabled = false;
btnRead.Enabled = false;
btnOpen.Enabled = true;
indicator = true;
}
private void btnRead_Click(object sender, EventArgs e)
{
if (btnRead.Text == "Read")
{
btnRead.Text = "Stop and Close Port";
progressBar1.Maximum = 1000;
progressBar1.Value = 0;
backgroundWorker1.RunWorkerAsync(progressBar1.Maximum);
indicator = false;
}
else
{
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.CancelAsync();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
int max = (int)e.Argument;
int n = 0;
indicator = false;
do
{
//write to serial writer
sw.WriteLine(serialPort1.ReadLine());
if (backgroundWorker1.CancellationPending)
{
sw.Flush();
sw.Close();
e.Cancel = true;
break;
}
// backgroundWorker1.ReportProgress(n++);
}
while (indicator ==false);
}
catch (TimeoutException)
{
//Close Serial Writer & Messagebox
//txtRead.Text = "Time Out!";
MessageBox.Show("TimeOut Exception");
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
btnRead.Text = "Read";
//close serial writer
}
}
}
Since you have a do-while construct you evaluate the condition at the END!
So when you hit the Close button and close the SerialPort the backgroundworker is still active and running in the background trying to read from the SerialPort. It enters the do compartment and tries to read from a closed port, which is like running agains a closed door :) this leads to the exception.
You could solve it by
1) putting the while-evaluation on top and get rid of the do statement (making it a simple while-loop). This way the serialPort.ReadLine will not be executed anymore, because you set indicator = true; when hitting the close button.
May be in this case you should put the setting of indicator as the first line before closing the port:
private void btnClose_Click(object sender, EventArgs e)
{
try
{
indicator = true;
serialPort1.Close();
Or
2) put an extra if clause that makes sure to read only if the port is open!
if (serialPort1.IsOpen)
{
sw.WriteLine(serialPort1.ReadLine());
}
I am trying to write a program that communicates with a controller. The controller is supposed to send a "welcome" message when a connection is successfully established and, in fact, it does when I connect using a communications software. However, using the .NET code below, I never see the welcome message. Beyond that, it works. How can I capture this message. It seems to be sent the moment the connection is established.
Again, I am able to communicate fine with the controller after connection but I simply cannot seem to get the welcome message that is sent a the moment the connection is opened.
using System;
using System.IO.Ports;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public delegate void AddDataDelegate(String myString);
public AddDataDelegate myDelegate;
SerialPort sp;
public Form1()
{
InitializeComponent();
}
public void AddDataMethod(String myString)
{
richTextBox1.AppendText(myString);
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.ScrollToCaret();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
sp = new SerialPort(comboBox1.SelectedItem.ToString(),Int32.Parse(comboBox2.SelectedItem.ToString()));
sp.DataReceived += SerialPort_OnDataReceived;
sp.Close();
sp.Open();
richTextBox1.AppendText("open\n");
button2.Enabled = true;
button3.Enabled = true;
}
catch (Exception ex)
{
richTextBox1.AppendText(ex.Message);
}
}
void SerialPort_OnDataReceived(object sender,SerialDataReceivedEventArgs args)
{
SerialPort sp = sender as SerialPort;
string s = sp.ReadExisting();
richTextBox1.Invoke(this.myDelegate, new Object[] { s });
}
private void button2_Click(object sender, EventArgs e)
{
sp.WriteLine(textBox1.Text);
textBox1.Text = "";
}
private void button3_Click(object sender, EventArgs e)
{
sp.DiscardOutBuffer();
sp.DiscardInBuffer();
sp.Close();
richTextBox1.AppendText("\nclosed\n");
}
private void Form1_Load_1(object sender, EventArgs e)
{
this.myDelegate = new AddDataDelegate(AddDataMethod);
string[] Ports = SerialPort.GetPortNames();
comboBox2.SelectedIndex = comboBox2.Items.Count - 1;
Array.Sort(Ports, (a, b) => string.Compare(a.Substring(3).PadLeft(3, '0'), b.Substring(3).PadLeft(3, '0')));
foreach (string port in Ports)
{
comboBox1.Items.Add(port);
}
comboBox1.SelectedIndex = 0;
}
}
}
I worked it out. Required a slight delay between connection and trying to pull data from the port.
i am working to make a c# program that can start streaming webcam, close and capture the still image when closing.
the programs work as excepted on my development machine but when i open it on other it dosent work and gives me unhandled exception: Afroge.Video.DirectShow error.
I have added references AFroge.Video.dll and AFroge.Video.DirectShow.dll
here is the exe file and code of my project.
sendspace .com/file/4okqsi
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;
//Create using directives for easier access of AForge library's methods
using AForge.Video;
using AForge.Video.DirectShow;
namespace aforgeWebcamTutorial
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//Create webcam object
VideoCaptureDevice videoSource;
private void Form1_Load(object sender, EventArgs e)
{
}
void videoSource_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
{
//Cast the frame as Bitmap object and don't forget to use ".Clone()" otherwise
//you'll probably get access violation exceptions
pictureBoxVideo.BackgroundImage = (Bitmap)eventArgs.Frame.Clone();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
//Stop and free the webcam object if application is closing
if (videoSource != null && videoSource.IsRunning)
{
videoSource.SignalToStop();
videoSource = null;
}
}
private void button1_Click(object sender, EventArgs e)
{
try {
if (videoSource.IsRunning)
{
videoSource.Stop();
pictureBoxVideo.BackgroundImage.Save("abc.png");
pictureBoxVideo.BackgroundImage = null;
}
}
catch (Exception er) { }
}
private void button2_Click(object sender, EventArgs e)
{
try {
//List all available video sources. (That can be webcams as well as tv cards, etc)
FilterInfoCollection videosources = new FilterInfoCollection(FilterCategory.VideoInputDevice);
//Check if atleast one video source is available
if (videosources != null)
{
//For example use first video device. You may check if this is your webcam.
videoSource = new VideoCaptureDevice(videosources[0].MonikerString);
try
{
//Check if the video device provides a list of supported resolutions
if (videoSource.VideoCapabilities.Length > 0)
{
string highestSolution = "0;0";
//Search for the highest resolution
for (int i = 0; i < videoSource.VideoCapabilities.Length; i++)
{
if (videoSource.VideoCapabilities[i].FrameSize.Width > Convert.ToInt32(highestSolution.Split(';')[0]))
highestSolution = videoSource.VideoCapabilities[i].FrameSize.Width.ToString() + ";" + i.ToString();
}
//Set the highest resolution as active
videoSource.VideoResolution = videoSource.VideoCapabilities[Convert.ToInt32(highestSolution.Split(';')[1])];
}
}
catch { }
//Create NewFrame event handler
//(This one triggers every time a new frame/image is captured
videoSource.NewFrame += new AForge.Video.NewFrameEventHandler(videoSource_NewFrame);
//Start recording
videoSource.Start();
}
}
catch (Exception er) { }
}
}
}
Try this link!
It worked for me!
If some parts cannot be installed. Delete all of the assemblies of AForge.Net and follow following tutorial.
https://premsivakumar.wordpress.com/2010/06/28/aforge-net-visual-studio-2010-setup-tutorial/