arduino - 通过按钮打开和关闭 Arduino
问题描述
我正在尝试通过按钮打开和关闭 Arduino。我使用教程https://www.instructables.com/id/A-Guide-to-Putting-Your-Arduino-to-Sleep/来了解如何操作。但不幸的是,这种情况并不适合 100%。我想要通过同一个开关(而不是计时器)打开和关闭。所以我已经按照下图的方式实现了,只是通过attachInterrupt()给事件重新分配了不同的函数。就像您一旦分配给事件就无法重新分配功能。是这样吗?有人有解决这个问题的方法吗?
在再次使用 attachInterrupt 之前,我已经添加了 detachInterrupt。此外,我已经在两者之间添加了延迟。尝试了中断事件 HIGH、LOW 和 CHANGE,总是相同的结果,进入睡眠状态但再也不会醒来。
#include <avr/sleep.h>
#define INTERRUPT_PWR_BUTTON_PIN 2 // pin for power button (Power button)
void setup() {
Serial.println("I'm up...");
attachInterrupt (digitalPinToInterrupt(INTERRUPT_PWR_BUTTON_PIN), goToSleep, HIGH); //attaching wakeup to interrup 0 on pin 2
delay(1000);
}
void loop() {
Serial.println("Ping");
delay(1000); // wait 1 sec
}
void goToSleep() {
Serial.println("Power Button pressed...");
Serial.flush();
sleep_enable(); // only enabling sleep mode, nothing more
detachInterrupt(digitalPinToInterrupt(INTERRUPT_PWR_BUTTON_PIN)); //remove interrupt 0 from pin 2
attachInterrupt (digitalPinToInterrupt(INTERRUPT_PWR_BUTTON_PIN), wakeUp, HIGH);
/* 2019-05-02 NN: Does not work, device will not wake up at all, unless pressing reset -> 2 buttons for now */
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // setting sleep mode to max pwr saving
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
sleep_cpu();
Serial.println("Just woke up!"); // gets executed after interrupt
digitalWrite(LED_BUILTIN, HIGH);
}
void wakeUp () {
Serial.println("Wakeup Interrupt Fired");
sleep_disable();
detachInterrupt(digitalPinToInterrupt(INTERRUPT_PWR_BUTTON_PIN)); //remove interrupt 0 from pin 2
attachInterrupt (digitalPinToInterrupt(INTERRUPT_PWR_BUTTON_PIN), goToSleep, HIGH);
}
解决方案
由于您只想使用一个按钮,您可以通过中断触发切换功能,并通过该功能使 Arduino 睡眠或唤醒。您必须使用一个布尔标志来实现这一点。
...
// use flag to control state of sleep
bool isSleeping = false;
void setup() {
...
attachInterrupt (digitalPinToInterrupt(INTERRUPT_PWR_BUTTON_PIN), toggleSleepState, HIGH); //attaching wakeup to interrup 0 on pin 2
...
}
void loop() {
...
}
void toggleSleepState() {
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
// If interrupts come faster than 200ms, assume it's a bounce and ignore
if (interrupt_time - last_interrupt_time > 200)
{
// toggle state of sleep
isSleeping = !isSleeping;
if (isSleeping == true) {
goToSleep();
}
else {
wakeUp()
}
}
last_interrupt_time = interrupt_time;
}
void goToSleep() {
// sleep logic
}
void wakeUp () {
// wake up logic
}
推荐阅读
- ios - 将我的项目文件夹移动到另一个位置,现在 xcworkspace 无法与我的主项目一起打开
- c - 给定现有路径时,Fopen 函数返回 null
- postman - 从邮递员导出结果,以便可以使用邮递员以外的工具(例如浏览器、csv)查看它们
- angular - 是否可以自定义材料的日期选择器主体?
- javascript - Nodejs Asynchronous reusable function call
- web-scraping - 抓取电子商务网站并聚合相同的产品
- python - 使用列表理解的单行“for”循环
- node.js - 使用 ajax 在不刷新站点的情况下更改 mongoDB 中的某些项目
- javascript - Carbon Design Systems React UI Shell 组件不工作
- java - Hitting a nullPointerExecption in my android project