You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么我的Arduino会无限向串口监视器重复发送相同消息?

问题原因
  • 核心原因1:Arduino的loop()是无限循环执行的,只要故障没有消除(val持续大于676),每次进入故障分支都会重新执行Serial.println("Fault")和Serial.write(3)逻辑,没有标记位阻止重复发送。
  • 核心原因2:你写的if (Serial.available() == 0){}完全不具备等待响应的作用,这段代码的逻辑只是“如果当前串口没有收到数据就什么都不做”,之后会直接结束本轮loop(),下一轮循环又会重新触发消息发送,自然会无限输出相同内容。
  • 额外小问题:你定义char statTX = "Good";是语法错误,char类型只能存储单个字符,存储字符串需要改成const char*类型,否则代码编译会有告警甚至运行异常。
修复方案

新增一个全局状态标记位,用来记录故障消息是否已经发送,避免重复触发发送逻辑;同时把串口等待响应的逻辑改成阻塞式等待,确保发送后不会直接进入下一轮循环。
修改后的完整代码如下:

int StatusPin = 13; //Assigns Pin 13 to be called "StatusPin"
int Relay = 12;     //Relay Signal Pin
int Feeder = 11;    //Feeder Control Switch Signal Pin
int readPin = A0;   //Assigns Pin A0 to be called "readPin"
int msg = 0;        //Used for case declaration
//Default = 0
//Yes = 1
//No = 2
//Are You OK? = 3
//Switching Possible? = 4
int Pcheck = 0;       //Used for Power Calculation
float val = 0;        //Creates an empty variable to store future readings
float volts = 0;      //Same as above
const char* statTX = "Good"; //Current Status for this module
// 新增状态标记:故障消息是否已经发送
bool faultMsgSent = false;

void setup() {
  statTX = "Good"; //Default Status for this module
  pinMode(StatusPin, OUTPUT);
  pinMode(Relay, OUTPUT);
  pinMode(Feeder, OUTPUT);
  Serial.begin(9600);
}
  
void loop() {
  val = analogRead(readPin); //Stores the input value from the A0 pin into a variable
  volts = (val/1024)*5;      //Converts ADC reading to volts
  digitalWrite(Feeder, LOW); //Feeder Switch is Default OPEN

  if (val <= 676){
    digitalWrite(StatusPin, HIGH); //Green light status turns on when greater than 3.3V
    digitalWrite(Relay, HIGH); //Breaker switch is closed
    // 故障消除,重置状态标记,下次故障可以重新触发发送
    faultMsgSent = false;
    statTX = "Good";
  }

 //Transmission Code for Fault Detection Side
  else{
    statTX = "Fault";
    digitalWrite(Relay, LOW);     //Breaker switch is opened
    digitalWrite(StatusPin, LOW); //Green light status turns off when greater than 3.3V
    
    // 只有没发过故障消息的时候才发送
    if(!faultMsgSent){
      Serial.println("Fault");      //Sent Fault Status Message
      Serial.write(3);              //Send "Are You Okay?" message
      faultMsgSent = true; //标记已经发过,避免重复发送
    }
    
    // 阻塞等待串口响应,直到收到数据再往下走
    while (Serial.available() == 0);
    msg = Serial.read();
    if (msg == 1) {
      statTX = "Isolated";           //Declares fault isolated
      Serial.println("Isolated");
      Serial.write(4);               //Send Message to Request Switch
      
      // 同样阻塞等待响应
      while (Serial.available() == 0);
      msg = Serial.read();
      if (msg == 1){
        Serial.write(20);       //Sends tentative current draw
        
        while (Serial.available() == 0);
        msg = Serial.read();
        if (msg == 1 && val < 676){
          statTX = "SystemRestored";
          Serial.println("SystemRestored");
          digitalWrite(StatusPin, HIGH); //Green light status turns on when greater than 3.3V
        }
        else {
          statTX = "Failure";
          Serial.println("Failure");
        }
      }
      else {
        statTX = "Failure";
        Serial.println("Failure");
      }
    }
  }
}
补充说明

如果你的场景需要在等待响应的同时还能持续监测电网电压变化,不要用阻塞式的while等待,可以改用状态机的逻辑拆分不同的交互阶段,每个loop只执行当前阶段的逻辑,不会卡住其他功能。

内容的提问来源于stack exchange,提问作者SgtTicklePants

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 03:27:05