I have a .net app in Visual Studio that communicates with an Arduino Uno. The Uno is connected to a pressure sensor. I want to send a message from my .net app to the Arduino via serial, asking for pressure data. Then I want the Arduino to respond with the latest data point, and send it via serial back to my .net app which then plots it and stores the data.
I can send a stream of data continously from my Uno and the app registers the entire stream. But this creates significant lag. I have also tried to use a timer to send the message to my Uno, but this only works if I use a threadsleep of at least 2500ms, which is way too much for my purpose.
My problem is that I can not find a way to continuously send requests from the .net app. I can, for example, add a button that sends the command to the Arduino and I get the correct respons. But I want to do this at a high frequency in a continuous manner.
Here are the relevant parts of my code:
public void Read() //Reads sensor values from Uno
{
while (port.IsOpen)
{
try
{
if (port.BytesToRead > 0)
{
string message = port.ReadLine();
this.SetText(message);
}
}
catch (TimeoutException) { }
}
}
private void SetText(string text)
{
if (this.labelPressure.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] {text});
}
else
{
this.labelPressure.Text = text;
chart1.ChartAreas["ChartArea1"].AxisX.LabelStyle.Enabled = false;
chart1.Invoke((MethodInvoker)(() => chart1.Series["Pressure"].Points.AddXY(DateTime.Now.ToLongTimeString(), text)));
if (chart1.Series[0].Points.Count > 20)
{
chart1.Series[0].Points.RemoveAt(0);
chart1.ChartAreas[0].AxisX.Maximum = 0;
chart1.ChartAreas[0].AxisX.Maximum = 20;
chart1.ChartAreas[0].AxisY.Maximum = 10;
chart1.ChartAreas[0].AxisY.Minimum = -90;
chart1.ChartAreas[0].AxisY.Interval = 10;
}
}
}
This part of the code works for reading the entire data stream. The message I would like to send to the Uno is
string d2 = "M";
port.Write(d2);
But I have no idead how to continously and with high frequency send this message to my Uno and then recieve the answer. Does anyone have a solution?
The best algorithm would be that, you open the connection, send the measuring request and wait for the answer and start from the beginning.
There is a DataReceived
event, you can use that instead of continuously polling the data in a while loop.
using System;
using System.IO.Ports;
class PortDataReceived
{
public static void Main()
{
SerialPort mySerialPort = new SerialPort("COM1");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
mySerialPort.Write("M"); // initiate the query
Console.ReadKey();
mySerialPort.Close();
}
private static void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
var sp = (SerialPort)sender;
var indata = sp.ReadLine();
//process your message (here you refresh your controls in GUI app )
/* process data on the GUI thread
Application.Current.Dispatcher.Invoke(new Action(() => {
this.labelPressure.Text = indata;
}));
*/
Console.WriteLine(indata);
mySerialPort.Write("M"); // send message request again (it is a bit recursive solution, but maybe this is enough for your use case)
}
}
Try this first in a command line solution, and if you are satisfied with the data frequency, you implement it in your solution (Delete the Console.* lines, uncomment the commented code and everything should work).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.