// the loop routine runs over and over again forever:
void loop() {
int voltage = analogRead(A0);
pushNewData(voltage);
if(data[SIZE-1] != 0){
int average = (int)(calculateAVG(data));
int sd = (int)(calculateSD(data));
/*
Serial.print(voltage);
Serial.print(",");
Serial.print(average);
Serial.print(",");
Serial.print(average+2*sd);
Serial.print(",");
Serial.println(average-2.5*sd);
*/
if(voltage > average+2*sd || voltage < average+2.5*sd){
interval = 5;
}
else{
interval = 50;
}
//Serial.println(blinkElapsed);
unsigned long currentMillis = millis();
if(currentMillis - previous > interval) {
// save the last time you blinked the LED
previous = currentMillis;
// if the LED is off turn it on and vice-versa:
if (current_state == 1){
Serial.println("1");
led1_state = HIGH;
led2_state = LOW;
led3_state = LOW;
digitalWrite(led1, led1_state);
digitalWrite(led2, led2_state);
digitalWrite(led3, led3_state);
current_state = current_state + 1;
}
else if(current_state == 2){
Serial.println("2");
led1_state = LOW;
led2_state = HIGH;
led3_state = LOW;
digitalWrite(led1, led1_state);
digitalWrite(led2, led2_state);
digitalWrite(led3, led3_state);
current_state = current_state + 1;
}
else if(current_state ==3){
Serial.println("3");
led1_state = LOW;
led2_state = LOW;
led3_state = HIGH;
digitalWrite(led1, led1_state);
digitalWrite(led2, led2_state);
digitalWrite(led3, led3_state);
current_state = 1;
}
}
}
}
状态是前面的全局变量。我希望这些LED一个接一个地闪烁,间隔由声级决定。但它只是继续运行state1而永远不会进入state2。我不知道为什么。为什么它永远不会被添加1?
答案 0 :(得分:2)
我认为你的有限状态机“不是有限的”。状态3应该可以循环回到状态1,这是因为该过程有可能重复。现在回到1
的唯一方法是状态3
触发很多次,current_state
变量滚动到4..5..6..integer最大值。 0..1。
else if(current_state ==3){
Serial.println("3");
led1_state = LOW;
led2_state = LOW;
led3_state = HIGH;
digitalWrite(led1, led1_state);
digitalWrite(led2, led2_state);
digitalWrite(led3, led3_state);
current_state = 1;
}
如果这不能解决问题,那么让我们开始倒退。如果程序被第一个LED点亮,那么很可能是这个代码
else if(current_state == 2){
//...
current_state = current_state + 1;
}
从未执行过。因此,我们开始质疑我的状态机是否正在推进状态。要了解这是否正在发生,暂时让我们重用一个输出引脚,led3
作为一种“心跳“别针。因此,在代码更远的地方插入“flash LED3”剪辑,如下所示:
unsigned long currentMillis = millis();
// STOP FOR A SECOND TO TOGGLE THE STATE
if (led3_state == HIGH)
led3_state = LOW;
else
led3_state = HIGH;
// FLASH THE LED TO SEE IF WE'RE GETTTING HERE
digitalWrite(led3, led3_state);
// CONTINUE
if(currentMillis - previous > interval) {
你看,通过移动这个代码块,我们可以弄清楚我们要去的地方。现在,这个LED可能会非常快速地闪烁 - 足够快以显示持续亮起 - 但这是通过学习“是的,我的代码达到这一点”进行调试的基本方法。当你使用没有屏幕,没有键盘,没有打印机,没有这样的,没有示波器的“计算机”时,有时这就是你所能做的。
所以请这样做,并继续移动此代码块直到它退出工作。然后你会找到不起作用的声明,我们可以从那里开始。那声音怎么样?
答案 1 :(得分:2)
我重新格式化了你的代码。
现在有一些事情需要检查:
if(data[SIZE-1] != 0){
这会评估为true
吗? (这可能是因为您在该块中使用了一些调试打印)。
if(currentMillis - previous > interval) {
变量previous
是否正确初始化(在循环外)?例如:
unsigned long previous = millis();
current_state
的初始值是多少?例如,如果它为零,则不会执行3个块(并且您可能正在查看某个默认状态)。
您还可以将最后else if(current_state ==3){
更改为else{
以至少抓住这些问题 - 或者甚至更好,正如Patrick在评论中建议的那样,添加额外的else
分支来捕获可能无效的current_state
。
还要确保current_state
在任何其他功能中都不会改变。