- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
对于 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/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!