实现非阻塞定时操作 - 无延迟() - 为 Arduino
implementing non-blocking timed operations - without delay() - for Arduino
首先,Arduino 很新,我已经搜索了教程以努力完成这项工作,但似乎没有任何帮助。我想要做的是在按下按钮时让 LCD 背光激活 8 秒。
我第一次尝试编写代码时取得了小成功:
const int buttonPin = 13; // the number of the pushbutton pin
const int ledPin = 9; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void timeDelay(){
digitalWrite (ledPin, HIGH);
delay(8000);
digitalWrite (ledPin, LOW);
}
void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
timeDelay();
}
}
效果很好,我按下按钮,它会调用脚本,唯一的问题是它会暂停其他所有操作。看来我需要使用“millis”来实现一个解决方案,但我所看到的一切都适用于 BlinkWithoutDelay 草图,我似乎无法做到这一点。
任何建议或相关教程都会很棒。
编辑:
感谢 pirho 的解释。由于他们的指导,这是我能够工作的代码:
// constants won't change. Used here to set a pin number :
const int ledPin = 9;// the number of the LED pin
const int buttonPin = 13; // the number of the pushbutton pin
// Variables will change :
int ledState = LOW; // ledState used to set the LED
int buttonState = 0; // variable for reading the pushbutton status
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
unsigned long currentMillis = 0;
unsigned long ledTimer = 0;
// constants won't change :
const long interval = 8000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
// digitalWrite(ledPin, ledState);
pinMode(buttonPin, INPUT);
}
void loop() {
// here is where you'd put code that needs to be running all the time.
currentMillis = millis();
buttonState = digitalRead(buttonPin);
ledTimer = (currentMillis - previousMillis);
if (buttonState == HIGH) {
digitalWrite (ledPin, HIGH);
previousMillis = millis();
}
if (ledTimer >= interval) {
// save the last time you blinked the LED
digitalWrite (ledPin, LOW);
} else {
digitalWrite (ledPin, HIGH);
}
}
是的,您的 void timeDelay() {...}
中的 delay(8000);
阻止了循环。
要改变它解锁你必须在循环中,在每一轮:
- 如果 btn 按下存储 pressMillis,点亮 LED
- 比较 currentMillis-pressMillis > 8000,如果则关闭 LED
- 执行其他操作
希望这不是太抽象但不会为您编写代码 ;)
另请注意,可以根据 led 状态优化检查,但它可能不会带来任何性能变化,只是检查而不是 io 写入和额外代码。
更新:也可以使用一些多线程库,如 ProtoThreads。根据编程技能和 program/count 并行任务的复杂性,这也可能是不错的选择,但不一定。
在本网站搜索 arduino thread
首先,Arduino 很新,我已经搜索了教程以努力完成这项工作,但似乎没有任何帮助。我想要做的是在按下按钮时让 LCD 背光激活 8 秒。
我第一次尝试编写代码时取得了小成功:
const int buttonPin = 13; // the number of the pushbutton pin
const int ledPin = 9; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void timeDelay(){
digitalWrite (ledPin, HIGH);
delay(8000);
digitalWrite (ledPin, LOW);
}
void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
timeDelay();
}
}
效果很好,我按下按钮,它会调用脚本,唯一的问题是它会暂停其他所有操作。看来我需要使用“millis”来实现一个解决方案,但我所看到的一切都适用于 BlinkWithoutDelay 草图,我似乎无法做到这一点。
任何建议或相关教程都会很棒。
编辑:
感谢 pirho 的解释。由于他们的指导,这是我能够工作的代码:
// constants won't change. Used here to set a pin number :
const int ledPin = 9;// the number of the LED pin
const int buttonPin = 13; // the number of the pushbutton pin
// Variables will change :
int ledState = LOW; // ledState used to set the LED
int buttonState = 0; // variable for reading the pushbutton status
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
unsigned long currentMillis = 0;
unsigned long ledTimer = 0;
// constants won't change :
const long interval = 8000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
// digitalWrite(ledPin, ledState);
pinMode(buttonPin, INPUT);
}
void loop() {
// here is where you'd put code that needs to be running all the time.
currentMillis = millis();
buttonState = digitalRead(buttonPin);
ledTimer = (currentMillis - previousMillis);
if (buttonState == HIGH) {
digitalWrite (ledPin, HIGH);
previousMillis = millis();
}
if (ledTimer >= interval) {
// save the last time you blinked the LED
digitalWrite (ledPin, LOW);
} else {
digitalWrite (ledPin, HIGH);
}
}
是的,您的 void timeDelay() {...}
中的 delay(8000);
阻止了循环。
要改变它解锁你必须在循环中,在每一轮:
- 如果 btn 按下存储 pressMillis,点亮 LED
- 比较 currentMillis-pressMillis > 8000,如果则关闭 LED
- 执行其他操作
希望这不是太抽象但不会为您编写代码 ;)
另请注意,可以根据 led 状态优化检查,但它可能不会带来任何性能变化,只是检查而不是 io 写入和额外代码。
更新:也可以使用一些多线程库,如 ProtoThreads。根据编程技能和 program/count 并行任务的复杂性,这也可能是不错的选择,但不一定。
在本网站搜索 arduino thread