简体   繁体   English

为什么 Serial.read() 没有在 Arduino 中循环

[英]Why is Serial.read() not looped in Arduino

I've been trying to connect Gui(graphic user interface) to my Arduino to control my motor.我一直在尝试将 Gui(图形用户界面)连接到我的 Arduino 来控制我的电机。 There are 4 buttons: L(Low),M(Medium),H(High),S(Stop).When I click there, one of 4 characters will be sent to my Arduino. Combining with the signal from my Infrared Obstacle Avoidance(Output pin is connected to pin 2 on Arduino),my motor will run for a period of time accordingly: L(3s), M(5s), H(10s), S(not running).有 4 个按钮:L(低)、M(中)、H(高)、S(停止)。当我点击那里时,4 个字符之一将发送到我的 Arduino。结合我的红外避障信号(输出引脚连接到Arduino上的引脚2),我的电机将相应地运行一段时间:L(3s),M(5s),H(10s),S(不运行)。 But when I click on any of these 3 buttons (L,M,H) with my hand covering the sensor, my motor will continue to run even after I release my hand.但是,当我用手覆盖传感器点击这 3 个按钮(L、M、H)中的任何一个时,即使我松开手,我的电机仍会继续运行。 The motor only stop running when I releases my hand and click any of these 3 buttons or S button.只有当我松开手并单击这 3 个按钮或 S 按钮中的任何一个时,电机才会停止运行。 Here is my Arduino code:这是我的 Arduino 代码:

#include<AFMotor.h>
AF_DCMotor motor(4);
int sensor=2;
char sig;
int t;
void setup() {
  Serial.begin(9600);
  pinMode(sensor,INPUT);
}

void loop() {
      t = digitalRead(sensor);
      delay(100);
      sig = Serial.read();
        if(sig=='L')
         {  
              if(t==LOW)
                {
                 runMotor(3000);
                }
               else if(t==HIGH)
                {
                  stopMotor();
                }
         }

         else if(sig=='M')
         {
              if(t==LOW)
                {
                  runMotor(5000);
                }
               else if(t==HIGH)
                {
                  stopMotor();
                }
         } 

         else if(sig=='H')
         {
              if(t==LOW)
                {
                  runMotor(10000);
                }
               else if(t==HIGH)
                {
                 stopMotor();
                }
         } 

         else if(sig == 'S')
          {
                  stopMotor();
          }
}

void runMotor(int n)
{
   motor.setSpeed(200);
   motor.run(FORWARD);
   delay(n);
}

void stopMotor()
{
   motor.setSpeed(200);
   motor.run(RELEASE);
   delay(200);
}

And here is my Winform Code这是我的 Winform 代码

private: System::Void run_Click(System::Object^ sender, System::EventArgs^ e) {
    
        serialPort1->Close();
        serialPort1->Open();
        if (listBox1->Text == "Low")
        {
            serialPort1->Write("L");
        }
        else if (listBox1->Text == "Medium")
        {
            serialPort1->Write("M");
        }
        else if (listBox1->Text == "High")
        {
            serialPort1->Write("H");
        }
        
    
}
private: System::Void stop_Click(System::Object^ sender, System::EventArgs^ e) {
    
    serialPort1->Close();
    serialPort1->Open();
    serialPort1->Write("S");
    
    
}

My design:我的设计:

enter image description here在此处输入图像描述

I've been trying to figure out what's the problem with my code and haven't been able to find it.我一直试图弄清楚我的代码有什么问题,但一直没能找到。

I cannot be certain of the problem without looking at Winforms code but I believe the problem might be related to having the code to stop the motor inside if statements that read serial input thus for it to work winforms app should be writing the value of the current button all the time in order be able to reach stopMotor function.如果不查看 Winforms 代码,我无法确定问题所在,但我相信问题可能与让代码在内部停止电机有关,如果读取串行输入的语句使其工作,winforms 应用程序应该写入当前的值一直按下按钮,以便能够到达 stopMotor function。

Keep in mind that Serial.read() as per documentation will return -1 if there is no input to be read, so unless your winforms app sends the value of the button constantly, you won't be reaching the stop method (because of the if statements).请记住,如果没有要读取的输入, Serial.read()根据文档将返回 -1,因此除非您的 winforms 应用程序不断发送按钮的值,否则您将不会到达停止方法(因为if 语句)。 Please see the following simplified sample.请参阅以下简化示例。

char sig;
int t;
void setup() {
  Serial.begin(9600);
}
void loop() {
    delay(1000);
    sig = Serial.read();
    Serial.println(sig);
    if(sig=='L')
    {  
        Serial.println("Case L");
    }
    else if(sig=='M')
    {
        Serial.println("Case M");
    } else
    {
      Serial.println("Read nothing");
    }
}

从串行监视器输出代码

As you can see here we only get inside if statements when input is received.正如您在这里看到的,我们仅在收到输入时才进入 if 语句。

One solution will be to only update sig variable when the value read is one of your settings, this way sig won't get overriden by empty serial reads and you won't need any extra code in UI.一种解决方案是仅在读取的值是您的设置之一时更新 sig 变量,这样 sig 就不会被空串行读取覆盖,并且您不需要在 UI 中添加任何额外代码。

char readValue = Serial.read();
if (readValue== 'L' || readValue == 'M' || readValue == 'H'){
   sig = readValue;
}

So basically after sending a signal, the computer will send nothing to Arduino,therefor Serial.read() will wait till the next signal is sent.所以基本上在发送信号后,计算机不会向 Arduino 发送任何内容,因此 Serial.read() 将等待下一个信号发送。 In that time, Arduino will do nothing and remain the previous stage of the motor在那个时候,Arduino什么都不做,仍然是电机的前一级

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM