为什么我的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
相关产品推荐
相关产品推荐

