对于 aspberry pi 项目,我有连接到 GPIO 的按钮,我想根据按下按钮的时间采取不同的操作。以下 python 代码(摘录)按预期工作:
on_button2(channel):
t1 = time.time()
# Wait for button release
while GPIO.input(channel) == 0:
pass
duration = time.time() - t1
print "duration: %f" % (duration)
if duration > 0.75:
mpd_client.previous()
else:
mpd_client.next()
GPIO.add_event_detect(BUTTON2_PIN, GPIO.FALLING, callback=on_button2, bouncetime=700);
我想把它转换成C程序(别问为什么,我真的不喜欢python而且我对C更熟悉,所以我想用C来做)
尝试使用wiringPi将其转换为C,我想出了这个,但它没有按预期工作:
unsigned long btn2_t0;
static void on_button_2_pressed() {
unsigned long duration, t1;
int level;
level = digitalRead(BUTTON_2_PIN);
// Debounce button
t1 = millis();
if (t1 - btn2_t0 < 700) {
return;
}
btn2_t0 = t1;
// Wait for button being released
while (digitalRead(BUTTON_2_PIN) == LOW) {
delay(100);
}
duration = millis() - t1;
if (duration > 5000) {
printf("Self destruction sequence initiated!\n");
}
else if (duration > 700) {
player_previous();
}
else {
player_next();
}
}
int main() {
// Setup WiringPi Lib
wiringPiSetupGpio();
pinMode(BUTTON_2_PIN, INPUT);
// Register callbacks on button press
wiringPiISR(BUTTON_2_PIN, INT_EDGE_FALLING, on_button_2_pressed);
for (;;) {
delay(500);
}
return 0;
}
似乎应该等待按钮释放的循环没有被执行,或者 while 条件总是为真,因此,持续时间总是为零。
该digitalRead(BUTTON_2_PIN)
函数是否完全等同GPIO.input(channel)
于python代码中的函数?
如果有人能指出我如何检测按钮按下(软件去抖动)并测量 C 中按钮按下的持续时间的正确方向。
非常感谢。
编辑:工作解决方案
在玩了很多之后,在 Francesco Boi 的帮助下,我找到了一个可行的解决方案,虽然我真的不明白为什么与 python 代码相比,为什么使用 HIGH / LOW 的比较逻辑被交换(我认为按下按钮会导致引脚下降到低并释放它会将其提升到高......)
static void on_button_2_pressed() {
unsigned long duration;
static unsigned long button_pressed_timestamp;
int level = digitalRead(BUTTON_2_PIN);
if (level == HIGH) { // Why HIGH ?!?
button_pressed_timestamp = millis();
}
else {
duration = millis() - button_pressed_timestamp;
button_pressed_timestamp = millis();
if (duration < 100) {
// debounce...
return;
}
else if (duration < 700) {
syslog(LOG_NOTICE, ">> NEXT\n");
}
else if (duration < 3000) {
syslog(LOG_NOTICE, "<< PREV\n");
}
else {
syslog(LOG_NOTICE, "!! REBOOT\n");
}
}
}
int main() {
...
wiringPiISR(BUTTON_2_PIN, INT_EDGE_BOTH, on_button_2_pressed);
...
}