如何通过串行通信从 Arduino 按钮获取标志?
How to get a flag from an Arduino button through serial communication?
我的objective是获取Arduino通过按钮发送的flag。该标志将通过串行通信发送到 C# windows 表单程序,我将能够在其中获取该标志。
Arduino发送到串口的数据为"ON"和"OFF",点击按钮时为"ON",未点击按钮时为"OFF" .此标志将用于打开和关闭将以 windows 形式显示的红色图表。
我的问题是如何从串行通信中获取 "ON" 和 "OFF",同时要记住来自传感器的数据也被发送到 windows 表单应用程序。
//C# Code
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 rtChart;
namespace Distance_Sensor_using_Flight_of_time
{
public partial class Form1 : Form
{
string recvData = "temporary";
bool breakloop = false;
kayChart chartData;
bool buttonPress = false;
string bufferString = "";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//chart1.Series.Add("Series1");
//Connection COM & Baud Rate
string[] ports = SerialPort.GetPortNames();
string[] rates = new string[10] { "300", "600", "1200", "2400", "9600", "14400", "19200", "38400", "57600", "115200" };
cboBaudRate.SelectedText = "9600";
cboCOM.Items.AddRange(ports);
cboBaudRate.Items.AddRange(rates);
if (ports.Length >= 1)
cboCOM.SelectedIndex = 0;
//kayChart real time
chartData = new kayChart(chart1, 60);
btnStart.Enabled = false;
btnSave.Enabled = false;
chart1.Series["Series1"].Enabled = false;
}
private void BtnConnect_Click(object sender, EventArgs e)
{
try
{
if (btnConnect.Text == "Disconnect")
{
if (btnStart.Text == "Stop")
MessageBox.Show("Please click \"Stop\" button first!");
else
{
serialPort1.Close();
btnStart.Enabled = false;
btnConnect.Text = "Connect";
}
}
else
{
serialPort1.PortName = cboCOM.Text;
serialPort1.BaudRate = Convert.ToInt32(cboBaudRate.Text);
serialPort1.Parity = Parity.None;
serialPort1.StopBits = StopBits.One;
serialPort1.DataBits = 8;
serialPort1.Open();
btnStart.Enabled = true;
btnConnect.Text = "Disconnect";
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void serialDataReceive(object sender, SerialDataReceivedEventArgs e)
{
if (!breakloop)
{
SerialPort sData = sender as SerialPort;
recvData = sData.ReadLine();
bufferString = recvData;
//rtbData.Invoke((MethodInvoker)delegate {rtbData.AppendText(recvData); });
//update chart
if (recvData == "ON\r" || recvData == "OFF\r")
{
if (recvData == "ON")
buttonPress = true;
else
buttonPress = false;
}
else
{
double data;
bool result = Double.TryParse(recvData, out data);
if (result)
{
chartData.TriggeredUpdate(data);
if (buttonPress == false)
{
chart1.Invoke((MethodInvoker)delegate { chart1.Series["Series1"].Enabled = false; });
chartData.serieName = "Length";
}
else
{
chart1.Invoke((MethodInvoker)delegate { chart1.Series["Series1"].Enabled = true; });
chartData.serieName = "Series1";
}
}
}
rtbData.Invoke((MethodInvoker)delegate { rtbData.AppendText(recvData); });
}
}
private void BtnStart_Click(object sender, EventArgs e)
{
try
{
if (btnStart.Text == "Start")
{
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialDataReceive);
btnStart.Text = "Stop";
breakloop = false;
}
else
{
btnStart.Text = "Start";
breakloop = true;
//serialPort1.DataReceived += null;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
btnStart.Text = "Start";
}
}
private void RtbData_TextChanged(object sender, EventArgs e)
{
rtbData.SelectionStart = rtbData.Text.Length;
rtbData.ScrollToCaret();
}
}
}
//Arduino Code
/* This example shows how to get single-shot range
measurements from the VL53L0X. The sensor can optionally be
configured with different ranging profiles, as described in
the VL53L0X API user manual, to get better performance for
a certain application. This code is based on the four
"SingleRanging" examples in the VL53L0X API.
The range readings are in units of mm. */
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
// Uncomment this line to use long range mode. This
// increases the sensitivity of the sensor and extends its
// potential range, but increases the likelihood of getting
// an inaccurate reading because of reflections from objects
// other than the intended target. It works best in dark
// conditions.
//#define LONG_RANGE
// Uncomment ONE of these two lines to get
// - higher speed at the cost of lower accuracy OR
// - higher accuracy at the cost of lower speed
//#define HIGH_SPEED
#define HIGH_ACCURACY
const int buttonPin = 2;
const int ledPin = 8;
int buttonState = 0;
bool inLoop = false;
void setup()
{
Serial.begin(9600);
Wire.begin();
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
sensor.init();
sensor.setTimeout(500);
#if defined LONG_RANGE
// lower the return signal rate limit (default is 0.25 MCPS)
sensor.setSignalRateLimit(0.1);
// increase laser pulse periods (defaults are 14 and 10 PCLKs)
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
#endif
#if defined HIGH_SPEED
// reduce timing budget to 20 ms (default is about 33 ms)
sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
// increase timing budget to 200 ms
sensor.setMeasurementTimingBudget(200000);
//sensor.setMeasurementTimingBudget(900000);
#endif
}
void loop()
{
buttonState = digitalRead(buttonPin);
Serial.print(sensor.readRangeSingleMillimeters());
if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
Serial.println();
if (buttonState == HIGH && inLoop == false)
{
Serial.write("ON");
Serial.println();
digitalWrite(ledPin, HIGH);
inLoop = true;
}
else if (buttonState == LOW && inLoop == true)
{
Serial.write("OFF");
Serial.println();
digitalWrite(ledPin, LOW);
inLoop = false;
}
}
我希望图表在单击按钮后变为红色,而在未单击按钮时变为蓝色。提前谢谢你。
虽然您正在做的事情可能有效(即只是试图弄清楚接收方的消息是什么),但如果您使用某种形式的消息头和分隔符,它的可扩展性要大得多。所以您的消息将如下所示:
"btnState,true"
"btnState,false"
"data,124"
在接收方,您需要执行 recvData.Split(',') 然后检查数组的第一个成员以找出它们的消息类型,然后相应地解析第二部分.
此外,具体与您的代码有关,我不确定您为什么选择为您 "ON" 和 "OFF" 使用 Serial.write 而不是坚持使用 Serial.println。没有测试我不是肯定的,但很确定你正在尝试使用 println 作为消息定界符,我认为它可能将 write 和空 println 作为两个单独的消息发送(这可以解释为什么你的 on off equality 可能会失败).
我的objective是获取Arduino通过按钮发送的flag。该标志将通过串行通信发送到 C# windows 表单程序,我将能够在其中获取该标志。
Arduino发送到串口的数据为"ON"和"OFF",点击按钮时为"ON",未点击按钮时为"OFF" .此标志将用于打开和关闭将以 windows 形式显示的红色图表。
我的问题是如何从串行通信中获取 "ON" 和 "OFF",同时要记住来自传感器的数据也被发送到 windows 表单应用程序。
//C# Code
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 rtChart;
namespace Distance_Sensor_using_Flight_of_time
{
public partial class Form1 : Form
{
string recvData = "temporary";
bool breakloop = false;
kayChart chartData;
bool buttonPress = false;
string bufferString = "";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//chart1.Series.Add("Series1");
//Connection COM & Baud Rate
string[] ports = SerialPort.GetPortNames();
string[] rates = new string[10] { "300", "600", "1200", "2400", "9600", "14400", "19200", "38400", "57600", "115200" };
cboBaudRate.SelectedText = "9600";
cboCOM.Items.AddRange(ports);
cboBaudRate.Items.AddRange(rates);
if (ports.Length >= 1)
cboCOM.SelectedIndex = 0;
//kayChart real time
chartData = new kayChart(chart1, 60);
btnStart.Enabled = false;
btnSave.Enabled = false;
chart1.Series["Series1"].Enabled = false;
}
private void BtnConnect_Click(object sender, EventArgs e)
{
try
{
if (btnConnect.Text == "Disconnect")
{
if (btnStart.Text == "Stop")
MessageBox.Show("Please click \"Stop\" button first!");
else
{
serialPort1.Close();
btnStart.Enabled = false;
btnConnect.Text = "Connect";
}
}
else
{
serialPort1.PortName = cboCOM.Text;
serialPort1.BaudRate = Convert.ToInt32(cboBaudRate.Text);
serialPort1.Parity = Parity.None;
serialPort1.StopBits = StopBits.One;
serialPort1.DataBits = 8;
serialPort1.Open();
btnStart.Enabled = true;
btnConnect.Text = "Disconnect";
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void serialDataReceive(object sender, SerialDataReceivedEventArgs e)
{
if (!breakloop)
{
SerialPort sData = sender as SerialPort;
recvData = sData.ReadLine();
bufferString = recvData;
//rtbData.Invoke((MethodInvoker)delegate {rtbData.AppendText(recvData); });
//update chart
if (recvData == "ON\r" || recvData == "OFF\r")
{
if (recvData == "ON")
buttonPress = true;
else
buttonPress = false;
}
else
{
double data;
bool result = Double.TryParse(recvData, out data);
if (result)
{
chartData.TriggeredUpdate(data);
if (buttonPress == false)
{
chart1.Invoke((MethodInvoker)delegate { chart1.Series["Series1"].Enabled = false; });
chartData.serieName = "Length";
}
else
{
chart1.Invoke((MethodInvoker)delegate { chart1.Series["Series1"].Enabled = true; });
chartData.serieName = "Series1";
}
}
}
rtbData.Invoke((MethodInvoker)delegate { rtbData.AppendText(recvData); });
}
}
private void BtnStart_Click(object sender, EventArgs e)
{
try
{
if (btnStart.Text == "Start")
{
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialDataReceive);
btnStart.Text = "Stop";
breakloop = false;
}
else
{
btnStart.Text = "Start";
breakloop = true;
//serialPort1.DataReceived += null;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
btnStart.Text = "Start";
}
}
private void RtbData_TextChanged(object sender, EventArgs e)
{
rtbData.SelectionStart = rtbData.Text.Length;
rtbData.ScrollToCaret();
}
}
}
//Arduino Code
/* This example shows how to get single-shot range
measurements from the VL53L0X. The sensor can optionally be
configured with different ranging profiles, as described in
the VL53L0X API user manual, to get better performance for
a certain application. This code is based on the four
"SingleRanging" examples in the VL53L0X API.
The range readings are in units of mm. */
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
// Uncomment this line to use long range mode. This
// increases the sensitivity of the sensor and extends its
// potential range, but increases the likelihood of getting
// an inaccurate reading because of reflections from objects
// other than the intended target. It works best in dark
// conditions.
//#define LONG_RANGE
// Uncomment ONE of these two lines to get
// - higher speed at the cost of lower accuracy OR
// - higher accuracy at the cost of lower speed
//#define HIGH_SPEED
#define HIGH_ACCURACY
const int buttonPin = 2;
const int ledPin = 8;
int buttonState = 0;
bool inLoop = false;
void setup()
{
Serial.begin(9600);
Wire.begin();
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
sensor.init();
sensor.setTimeout(500);
#if defined LONG_RANGE
// lower the return signal rate limit (default is 0.25 MCPS)
sensor.setSignalRateLimit(0.1);
// increase laser pulse periods (defaults are 14 and 10 PCLKs)
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
#endif
#if defined HIGH_SPEED
// reduce timing budget to 20 ms (default is about 33 ms)
sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
// increase timing budget to 200 ms
sensor.setMeasurementTimingBudget(200000);
//sensor.setMeasurementTimingBudget(900000);
#endif
}
void loop()
{
buttonState = digitalRead(buttonPin);
Serial.print(sensor.readRangeSingleMillimeters());
if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
Serial.println();
if (buttonState == HIGH && inLoop == false)
{
Serial.write("ON");
Serial.println();
digitalWrite(ledPin, HIGH);
inLoop = true;
}
else if (buttonState == LOW && inLoop == true)
{
Serial.write("OFF");
Serial.println();
digitalWrite(ledPin, LOW);
inLoop = false;
}
}
我希望图表在单击按钮后变为红色,而在未单击按钮时变为蓝色。提前谢谢你。
虽然您正在做的事情可能有效(即只是试图弄清楚接收方的消息是什么),但如果您使用某种形式的消息头和分隔符,它的可扩展性要大得多。所以您的消息将如下所示:
"btnState,true"
"btnState,false"
"data,124"
在接收方,您需要执行 recvData.Split(',') 然后检查数组的第一个成员以找出它们的消息类型,然后相应地解析第二部分.
此外,具体与您的代码有关,我不确定您为什么选择为您 "ON" 和 "OFF" 使用 Serial.write 而不是坚持使用 Serial.println。没有测试我不是肯定的,但很确定你正在尝试使用 println 作为消息定界符,我认为它可能将 write 和空 println 作为两个单独的消息发送(这可以解释为什么你的 on off equality 可能会失败).