如何通过串行通信从 Arduino 按钮获取标志?

How to get a flag from an Arduino button through serial communication?

我的objective是获取Arduino通过按钮发送的flag。该标志将通过串行通信发送到 C# windows 表单程序,我将能够在其中获取该标志。

A​​rduino发送到串口的数据为"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 可能会失败).