使用暂停按钮ARDUINO创建灯光序列时出现问题



所以我试图创建一个程序,使用Arduino板运行各种光序列。我对C++不是很熟悉,所以我觉得语法知识的缺乏阻碍了我实现目标。

我的想法是根据红外遥控器上按下的按钮来播放各种灯光序列。一盏灯打开或关闭的时间量可能与另一盏灯的时间量相同,也可能不同。不幸的是,序列似乎不起作用,这表明问题可能与toggleLight函数有关。

我还希望有一个按钮,允许用户暂停序列(无论序列在哪里(。一旦再次按下按钮,序列就会继续。我读到一些关于使用C++的中断器和睡眠模式的内容,但我对此不熟悉,所以它没有包含在我的代码中。

我的其余目标已经包含在我的代码中。我创建了一个对象"light",因为我试图在不使用延迟函数的情况下创建序列,因为中断与延迟函数的配合不好(据我所知(。然后我就可以对特定的光对象调用函数toggleLight。然而,正如我之前所说,这些序列不起作用。

我更熟悉OOP语言,所以创建一个对象对Arduino来说可能不是最好的。如果有人对我如何实现目标有任何想法,我将不胜感激。

unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
//sets up the Infrared receiver for the remote controller
const int RECV_PIN = 1;
IRrecv irrecv(RECV_PIN);
decode_results results;
//Sets up the LED's pin number and light status
class light{
private:
int _pinNumber;
byte _Lstatus;
public:
//function that creates the objects with the parameters
light(int pinNum, byte Lstat){
_pinNumber = pinNum;
_Lstatus = Lstat;}
void toggleLight(long interval){
//ensures that the "interval" amount of time has passed between the last LED blink
if ((currentMillis - previousMillis) >= interval) {
// if the LED is off turn it on and vice-versa:
if (_Lstatus == LOW) {
_Lstatus = HIGH;
} else if (_Lstatus == HIGH) {
_Lstatus = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(_pinNumber, _Lstatus);
// save the last time you blinked the LED
previousMillis = currentMillis;
}
}
};
//creating four light objects with the pins and initial status of off.
light J1(13, LOW);
light J2(11, LOW);
light P1(12, LOW);
light P2(10, LOW);

void setup()
{
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
}
//Sequence 1 is a mock sequence. It will probably be longer and the intervals would not all be 1000
void seq1(){
currentMillis = millis();
J1.toggleLight(1000);
P1.toggleLight(1000);
J1.toggleLight(1000);
P1.toggleLight(1000);
J2.toggleLight(1000);
P2.toggleLight(1000);
}
void seq2(){
currentMillis = millis(); //I found that placing currentMillis = millis() here allows the lights to at least turn on
J1.toggleLight(2000);
J1.toggleLight(10);
P1.toggleLight(1000);
P1.toggleLight(0);
J2.toggleLight(1500);
J2.toggleLight(1);
P2.toggleLight(2000);
P2.toggleLight(1);
}
void loop()
{
/* So once i get the sequences working, my idea is to have different sequences play
depending on what button on the remote is pressed. However, first I want to get the sequences and
interrupter
For now I have just tried running sequence #2 but it does not work.. Neither does Sequence #1. */
seq2();

//I MADE THESE LINES OF CODE COMMENTS FOR NOW. UNTIL I GET THE REST OF THE PROGRAM WORKING
/*if (irrecv.decode(&results))
{
switch (results.value) {
case : 0xf00000 // When button #1 sequence one plays
seq1();
break;
case : 0xf00000 // when button #2 is pressed, sequence two plays
seq2();
break;
*/
}

我可以看到,您还没有了解Arduino内部的代码流。这里有一个快速教程,让你开始跑步。

基本上,您的代码不是按顺序处理的。因此,当处理器通过seq((并到达'J1.thoggleLight(2000(;'中的第一个if语句时并且发现条件不满足(即2000毫秒还没有过去(,它立即移动到seq((中的第二行。这个问题是,当它在第二行满足条件时,它将重置所有灯所依赖的"previousMillis"值。

因此,你应该把"previousMillis"作为一名成员移入课堂,为每盏灯奉献一个时钟。

class light{
private:
int _pinNumber;
byte _Lstatus;
unsigned long previousMillis = 0;

通过这种方式,每一盏灯都能够跟踪自己的时间,而不会与其他灯光发生冲突。这将导致你的灯以1/间隔的频率闪烁,我怀疑这是否是你想要的。(在seq((函数中,每个灯都被切换两次,它甚至不会这样做。试着去掉第二个电话,看看会发生什么(这就引出了第二个问题。

第二个问题是如何设置序列。由于你想让灯按顺序运行,你需要找到累积的时间,这会抵消使用类的机会,除非你愿意实现一种考虑每个实例的间隔和安排的调度机制。看起来有点不切实际。

我认为您应该放弃这个类,使用一个简单的函数来接受每个序列所需的八个值。然后可以使用if语句来操纵灯光的状态。

我希望这个答案有一定的道理。祝你好运

最新更新