gpt4 book ai didi

c - 如何使用C中的wiringpi确定按钮按下持续时间

转载 作者:太空宇宙 更新时间:2023-11-04 03:13:15 25 4
gpt4 key购买 nike

对于 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) 函数是否等同于 python 代码中的 GPIO.input(channel)

如果有人能指出正确的方向,告诉我如何检测按钮按下(软件去抖动)并测量 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);
...
}

最佳答案

首先,您将 pin 的值读取到 level 中,然后在 while 循环中重新读取它:这是为什么呢?你不能做这样的事情吗:

// Wait for button being released
while (level == LOW) {
delay(100);
}

?

即使时间小于 700 毫秒,您也不想重新分配 btn2_t0 = t1; 吗?喜欢:

t1 = millis();
if (t1 - btn2_t0 < 700) {
btn2_t0 = t1;
return;
}

行为取决于您构建电子电路的方式:按下按钮应该使引脚变高还是变低?通过连接 LED 和电阻器或使用电压表,确保行为符合您的预期。

但是,由于您的 Python 代码有效,我假设电子是正确的,您的算法也是正确的。

当然要确保您按下按钮的时间足够长。在您的代码中添加一些打印以了解它正在执行哪些分支,因为当涉及电子时,仅通过代码很难理解。

在等待您的消息时,我认为最好执行以下操作:将回调定义为:INT_EDGE_BOTH 以便在按下底部和释放按钮时调用它。您可以使用静态变量保持耗时。

void yourCallback()
{
unsigned long ela, t;
int level = digitalRead(BUTTON_2_PIN);
static unsigned long button_pressed_timestamp;
//if button pressed:
if(level==LOW)
{
//start counting
button_pressed_timestamp = millis();
}
else //button released
{
duration = millis()-button_pressed_timestamp;
button_pressed_timestamp = millis(); //just to be sure....
if (duration > 5000) {
printf("Self destruction sequence initiated!\n");
}
else if (duration > 700) {
player_previous();
}
else {
player_next();
}
}


}

关于c - 如何使用C中的wiringpi确定按钮按下持续时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54280752/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com