【问题标题】:This code seems to get stuck on the first while loop此代码似乎卡在第一个 while 循环中
【发布时间】:2022-01-23 23:08:54
【问题描述】:

我有这个 arduino 代码似乎卡在第一个 while 循环上。它有什么问题? 它应该根据从1V到5V的电压水平分别打开绿色,黄色和红色LED。

0.01V - 2.9V 为绿灯
3.0V - 3.9V 为黄灯
4.0V - 5.0V 为红灯

int readPin = A1;
int readVal;
float Voltage;
int green = 8;
int yellow = 9;
int red = 10;
int delayT = 100;


 void setup() {
  // put your setup code here, to run once:
 pinMode(A1, INPUT);
 pinMode(green, OUTPUT);
 pinMode(yellow, OUTPUT);
 pinMode(red, OUTPUT);
 }

 void loop() {
  // put your main code here, to run repeatedly:
 readVal = analogRead(readPin);
 Voltage = (readVal/1023.) * 5.;
 

while (Voltage >= 0.01 && Voltage < 3.0){
 digitalWrite(green, HIGH);
 Voltage = (readVal/1023.) * 5.;
 }
 digitalWrite(green, LOW);

while (Voltage >= 3.0 && Voltage < 4.0){
 digitalWrite(yellow, HIGH);
 Voltage = (readVal/1023.) * 5;
 }
 digitalWrite(yellow, LOW);

while (Voltage >= 4.0 && Voltage <= 5.0){
 digitalWrite(red, HIGH);
 Voltage = (readVal/1023.) * 5;
 }
 digitalWrite(red, LOW);

delay(delayT);

 }

【问题讨论】:

  • 用你自己的话来说,Voltage = (readVal/1023.) * 5. 的结果为什么会超出范围?为什么它应该在 while 循环中更改
  • 应该不会,谢谢解答! :)

标签: arduino


【解决方案1】:

在您的 while 循环中,您不会更新 readVal 的值,因此它在 while 循环的每个循环中都保持不变。

考虑在 while 循环中添加 readVal = analogRead(readPin);

另外.. 你可能真的不需要 while 循环,只需执行 if 语句来触发每个条件:

void loop() {
 readVal = analogRead(readPin);
 Voltage = (readVal/1023.) * 5.;
 

if(Voltage >= 4.0 && Voltage <= 5.0){
 digitalWrite(red, HIGH);
 digitalWrite(green, LOW);
 digitalWrite(yellow, LOW);
 }
else if(Voltage >= 3.0 && Voltage < 4.0){
 digitalWrite(yellow, HIGH);
 digitalWrite(green, LOW);
 digitalWrite(read, LOW);
 }
else if (Voltage >= 0.01 && Voltage < 3.0){
 digitalWrite(green, HIGH);
 digitalWrite(red, LOW);
 digitalWrite(yellow, LOW);
 }



delay(delayT);

 }

甚至更好,这样您就不会那么频繁地编写 digitalWrite,添加一个简单的条件来检查您是否真的需要进行更改: (注意没有运行此代码,但应该可以工作..)

enum Colors {OFF, RED, YELLOW, GREEN};

int currentColor = Colors::OFF;  

void loop() {
 readVal = analogRead(readPin);
 Voltage = (readVal/1023.) * 5.;
 
 int expectedColor = Colors::OFF;

// go through our voltage logic to figure out the expected color
if(Voltage >= 4.0 && Voltage <= 5.0){
 expectedColor  = Colors::RED;
 }
else if(Voltage >= 3.0 && Voltage < 4.0){
 expectedColor  = Colors::YELLOW;
 }
else if (Voltage >= 0.01 && Voltage < 3.0){
 expectedColor  = Colors::GREEN;
 }

// we only want to call digitalWrite if the currentColor is not the
// color we expect, and we want to write the color we do expect
// (which is expectedColor.)

if (expectedColor != currentColor) {

 currentColor = expectedColor;

 digitalWrite(red, currentColor == Colors::RED ? HIGH : LOW);
 digitalWrite(green, currentColor == Colors::GREEN? HIGH : LOW);
 digitalWrite(yellow, currentColor == Colors::YELLOW ? HIGH : LOW);

}

delay(delayT);

 }

解释:

enum Colors {OFF, RED, YELLOW, GREEN};

我们可以使用枚举作为 LED 的一组可能状态 枚举有一个名称(例如颜色),默认情况下, 状态是整数类型,所以 OFF=0, RED=1, YELLOW=2, GREEN=3, 等等,如果你喜欢,你可以继续添加新的颜色。 您可以使用 Colors::RED 或 Colors::YELLOW 等访问枚举。

int currentColor = Colors::OFF;

我们从关闭状态开始。请注意,arduino 并不是真的 知道什么是 OFF,这是我们定义的不是 RED 的东西, 黄色或绿色。

int expectedColor = Colors::OFF;

初始化第二个变量来比较当前循环周期的 稍后使用 currentColor 的预期颜色

digitalWrite(red, currentColor == Colors::RED ? HIGH : LOW);

这里唯一棘手的部分是三元运算符 三元运算符是 if 语句的快捷方式 三元运算符是这样的: 健康)状况 ?真值:假值 对于红色,我们会问“是 currentColor == RED 吗?”如果是真的, 然后我们将其设置为高。如果为假,我们将其设置为假。 如果电压应该使 currentColor RED,那么对于 绿色运算符我们问的问题是“currentColor == GREEN?”, 答案是否定的,currentColor 是红色的,所以我们将绿色引脚写成 LOW

【讨论】:

  • 最后一个例子:nvm,在在线编译器上运行,运行良好!
  • 感谢您的回答!它解决了我的问题。至于最后一段代码,我还在努力理解是怎么回事。
  • 我明白了!非常聪明!
  • 很高兴你得到它。我添加了内联 cmets 以进一步阐明最后一个示例 :)
猜你喜欢
  • 2021-11-17
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
  • 2020-09-16
  • 1970-01-01
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
相关资源
最近更新 更多