可以通过串行连接发送字符串以使用 C++ 和 arduino 打开开关吗?

Can a string be sent over serial connection to open a swtch using c++ and an arduino?

问题总结:

它有效,但在我的具体情况下,由于数据编码,我遇到了问题。数据通过 arduino 作为 "coin" 发送,但它在我的控制台应用程序中的打印输出是“2”。然后我有从我的控制台应用程序发送字符串“1234”的问题,并且无法在 arduino 中接收它。我认为数据被设置为不同的编码,因此语句不会寻找正确的信息。就是这么简单又那么复杂。 (哦计算器!)

串口已打开,波特率已设置

Arduino 代码片段:

Serial.println('coin');

if( Serial.readString() == "1234"); <<<--- 我怎样才能放宽 这个条件,就像我在下面的例子中所做的那样。 (它在串行监视器上工作但在软件上不工作,这是编码情况吗?)

VS 代码片段:

SerialPort sp = (SerialPort)sender;

string indata = sp.ReadExisting();

if (indata.Contains("coin"))   <<<---  it is a relaxed contains condition, **works** in my case, since I dont really know excaclty what it is receiving.

SerialPort.Write("1234");(我如何确保它接收到我发送的字符,无论是 ANSI 十六进制还是其他字符。

感谢您的帮助。

常规开始 post

下午好,

我有arduino代码:

int ledPin = 13;
const int coinInt = 0;
int incomingByte = 0;

#define RELAY_ON 1
#define RELAY_OFF 0
#define Relay_2  7

int waittime;
volatile int coinsValue = 00;
volatile int coinsChange = 0;       //A Coin has been inserted flag

void setup()   {
  digitalWrite(Relay_2, RELAY_ON);
  pinMode(Relay_2, OUTPUT);  
  delay(1000);

  Serial.begin(9600);                
  attachInterrupt(coinInt, coinInserted, RISING);   //If coinInt goes HIGH (a Pulse), call the coinInserted function
}

void coinInserted()  {
  coinsValue = coinsValue + 01; 
  coinsChange = 1;  //Flag
}

void loop() {
  if(coinsChange == 1)   
  {
    coinsChange = 0;   

   if(coinsValue >= 50)   {
      Serial.println('coininsertion');
      coinsValue = 0;
      digitalWrite(Relay_2, RELAY_OFF);
      digitalWrite(ledPin, HIGH);    
  }
         if (Serial.available() > 0) {
                incomingByte = Serial.read();
                delay(250);
                digitalWrite(ledPin, LOW);
                digitalWrite(Relay_2, RELAY_ON);

   }                
  }
}

和 c# 控制台应用程序代码:

using System;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;


class PortDataReceived
{
    public static void Main()
    {
        SerialPort mySerialPort = new SerialPort("COM3");

        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();


      Console.WriteLine("Press a key to continue...");
      Console.WriteLine();
      Console.ReadKey();
      mySerialPort.Close();
    }

    private static void DataReceivedHandler(
                        object sender,
                        SerialDataReceivedEventArgs e)
    {

        SerialPort sp = (SerialPort)sender;
        string indata = sp.ReadExisting();
   //     Thread.Sleep(100);
       // Console.Write(indata);
        Thread.Sleep(100);
        if (indata.Contains("coininsertion"))
        {
            Thread.Sleep(100);
            //Process.Start(@"C:\Users\laptop\Documents\rb_software\print.ahk");
           Process process = new Process();
            // Configure the process using the StartInfo properties.
           process.StartInfo.FileName = @"C:\Users\laptop\Documents\rb_software\print.ahk";
            //process.StartInfo.Arguments = "-n";
            //process.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
           process.Start();
           Thread.Sleep(100);
           process.WaitForExit();
           Thread.Sleep(1000);// Waits here for the process to exit.
           sp.Write("a");

        }

      Console.Write(indata);

    }
}

最后在arduino代码中关闭继电器:

void loop() {
  if(coinsChange == 1)   
  {
    coinsChange = 0;   

   if(coinsValue >= 50)   {
      Serial.println('coininsertion');
      coinsValue = 0;
      digitalWrite(Relay_2, RELAY_OFF);
      digitalWrite(ledPin, HIGH);    
  }
         if (Serial.available() > 0) {
                incomingByte = Serial.read();
                delay(250);
                digitalWrite(ledPin, LOW);
                digitalWrite(Relay_2, RELAY_ON);

   }                
  }
}

或者至少应该关闭。因为我在接近尾声的 C++ 代码中通过串行连接发送了一个字符:

  process.WaitForExit();
               Thread.Sleep(1000);// Waits here for the process to exit.
               sp.Write("a");

无论如何,如果有人能告诉我为什么它没有关闭开关,我将不胜感激。即转Relay_2"ON".

就是这样。再次感谢。

主要问题:如果您使用串行监视器发送该控制字符,它是否有效?

Arduino 代码注释(有时 "WTFs"):

  • ledPin, LOW;setup() 中也没有 pinMode 这个 pin
  • coinsChange 也必须是可变的,因为它由 ISR 处理程序设置并在循环中检查
  • 忘记:0001,这些值被认为是八进制的。对于这些值,这不是问题,但是如果您使用 0012 之类的东西,它将是十进制的 10!
  • 我从来没有在他们所属的命令下看到评论。您可以将它们放在前一行,放在同一行(后),但是将它们放在下一行会非常混乱。他们中的很多人都在评论显而易见的事情——比如:Serial.begin(9600); //Start Serial Communication
  • 错误的缩进使这段代码难以阅读。而且只有几行。
  • waittime只设置了一次,不再使用。
  • 你确定投币信号去抖了吗?如果没有,它会为一枚硬币插入计算很多脉冲。
  • 为什么你的密码和其他常量如此不一致?一次是int,一次是const int,一次是#define...
  • if (incomingByte == '97') 选择一个:== 97== 'a' 但永远不要 '97' 因为这对字符来说是无稽之谈。

顺便说一句:C++ 代码实际上是 C#

编辑:您只修复了几件事。但最重要的是没有。例如缩进。 ' 也适用于 ONE 个字符。如果你想要字符串,你必须使用 "some string"。而且您绝对不想在块 if(coinsChange == 1) 之外进行串行处理。 som整理后:

const int  ledPin = 1;
const int Relay_2 = 7;
const int coinInt = 0; // coin external interrupt no

int  incomingByte = 0;

#define RELAY_ON 1
#define RELAY_OFF 0

int waittime = 1000;

// Volatile as this variable changes any time the Interrupt is triggered
volatile int  coinsValue = 0;  // Set the coinsValue to a Volatile float
volatile int coinsChange = 0;  // A Coin has been inserted flag

void setup()
{
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // -------( Initialize Pins so relays are inactive at reset)----
  digitalWrite(Relay_2, RELAY_ON);
  pinMode(Relay_2, OUTPUT);

  delay(1000);

  Serial.begin(9600);

  // Attach coinInt to Interrupt Pin 0 (Digital Pin 2). Pin 3 = Interrpt Pin 1.
  // If coinInt goes HIGH (a Pulse), call the coinInserted function
  // An attachInterrupt will always trigger, even if your using delays
  attachInterrupt(coinInt, coinInserted, RISING);
}

void coinInserted()  // The function that is called every time it recieves a pulse
{
  ++coinsValue;     // As we set the Pulse to represent 5p or 5c we add this to the coinsValue
  coinsChange = 1;  // Flag that there has been a coin inserted
}

void loop()
{
  if(coinsChange == 1) // check if a coin has been Inserted
  {
    coinsChange = 0;   // unflag that a coin has been inserted
    if(coinsValue >= 50)
    {
      Serial.println("coininsertion");
      coinsValue = 0;
      digitalWrite(Relay_2, RELAY_OFF);
      digitalWrite(ledPin, HIGH);
    }
  }

  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    delay(250);

    if (incomingByte == 'a') {
      digitalWrite(ledPin, LOW);
      digitalWrite(Relay_2, RELAY_ON);
    }                
  }
}

我认为对于发送和接收字符串,最好在arduino中使用字符串class。试试 Serial.readString()

https://www.arduino.cc/en/Serial/ReadString

这是我从 RX 引脚检查密码的示例代码

void loop() {
  if (Serial.available() > 0) {  // if the data came

data=Serial.readString();


if( data == "1234") {
  data="";
   digitalWrite(LED, HIGH); // if 0, switch LED on
   Serial.println("LED ON. Press 0 to LED OFF!");
}
 if(data=="0000"){
 data="";
   digitalWrite(LED, LOW);  // if 1, switch LED Off
   Serial.println("LED OFF. Press 1 to LED ON!");  // print message
}
}

希望对你有所帮助