操作控制4个按钮电路

huangapple go评论57阅读模式
英文:

Operation control of 4 button circuits

问题

如果连接了4个按钮到Arduino,并使用下拉电阻连接它们。这时,我想要知道的代码是,如果按下超过2个按钮,则停止操作。以下是我创建的代码。在顶部,我写下了基本的引脚设置、设置和每个按钮的操作。

if ((button1State == HIGH && button2State == HIGH) || 
    (button1State == HIGH && button3State == HIGH) ||
    (button1State == HIGH && button4State == HIGH) ||
    (button2State == HIGH && button3State == HIGH) ||
    (button2State == HIGH && button4State == HIGH) ||
    (button3State == HIGH && button4State == HIGH))
{
  Serial.print("Two or more buttons were pressed");
}

这段代码的问题在于,当按下两个按钮时,首先按钮1起作用,然后按钮2起作用,然后才识别出按下了2个按钮,并输出文本。我想要做的是,当按下两个或更多按钮时,不应该执行任何操作,但我担心它们仍然起作用。

如果你知道在按下两个或更多按钮时停止操作的代码,请回复。

英文:

When connecting 4 buttons to Arduino, I connected them by pull-down. At this time, I would like to know the code that stops the operation if more than 2 buttons are pressed. Also, the code below is the code I made. At the top, I wrote down the basic pin settings, setup, and operation of each button.

 if ((button1State == HIGH && button2State == HIGH) || 
 (button1State == HIGH && button3State == HIGH) ||
 (button1State == HIGH && button4State == HIGH) ||
 (button2State == HIGH && button3State == HIGH) ||
 (button2State == HIGH && button4State == HIGH) ||
 (button3State == HIGH && button4State == HIGH))
 {
  Serial.print("Two or more buttons were pressed");
 }

The problem with this code is that when you press two buttons, button 1 works, then button 2 works, and then it recognizes that 2 buttons are pressed and the text is output. What I want to do is, when two or more buttons are pressed, I shouldn't do anything, but I'm worried because they keep working.

If you know the code that stops the operation when two or more buttons are pressed, please reply.

答案1

得分: 1

以下是翻译好的部分:

  • 对于灵活性,以下是您可以做的:

    • 像通常一样去抖动按钮。将去抖动的结果放入位字段变量中。
    • 创建一个函数指针跳转表。这可以通过为所有支持的按钮组合提供一个函数并忽略其余的组合(将它们设置为null)来实现。
    • 使用去抖动的位字段作为跳转表中的数组索引。
    • 如果找到的函数地址为NULL,可以选择进行一些错误处理,否则执行该函数。

例如,假设为了简单起见,所有按钮都连接到PORTA中的引脚0到3。然后,我们可以创建一个用于存储去抖动结果的变量 uint8_t debounced_PORTA,该变量可以存储所有按钮组合,相当于值从0到15。

然后,我们将定义一个函数模板:typedef void action_func (void);,然后使用这个模板声明一个跳转表,支持最多16个组合:

action_func* action[0x0F]

我们将初始化这个跳转表以指向各种函数:

action_func* action[0x0F] =
{
  [PTA0]        = do_something,
  [PTA1 | PTA2] = do_something_else
};

这里的 PTA0 等是您的寄存器映射提供的引脚名称(我不记得确切的名称) - 它们是整数常数。在上面的示例中,当按下PTA0并且仅按下PTA0时,将调用函数 void do_something (void)。而当按下PTA1并且PTA2,而没有按下其他按钮时,将调用函数 do_something_else。以此类推 - 这种设计易于维护且具有良好的扩展性。

上面的跳转表中未提及的索引将自动设置为null,因为这是C语言所要求的。

然后,我们可以使用带有去抖动的端口值作为索引的这个跳转表:

if (action[debounced_PORTA] == NULL)
{
  /* 可选的错误处理 */
}
else
{
  action[debounced_PORTA]();
}
英文:

For flexibility, here is what you can do:

  • De-bounce the buttons like usual. Place the de-bounced result in a bit-field variable.
  • Create a function pointer jump table. This can be done by providing a function to all supported combinations of buttons and ignoring the rest (setting them to null).
  • Use the de-bounced bit-field as array index in the jump table.
  • If the function address found is NULL, optionally do some error handling, otherwise execute the function.

For example lets assume for simplicity that all buttons are connected to pins 0 to 3 in PORTA. We could then create a variable for the de-bounced result uint8_t debounced_PORTA which can then hold all button combinations, equavilent to values 0 to 15.

We'd then define a function template: typedef void action_func (void); then declare a jump table by using this template, supporting up to 16 combinations:

action_func* action [0x0F]

We will initialize this one to point at various functions:

action_func* action [0x0F] =
{
  [PTA0]        = do_something,
  [PTA1 | PTA2] = do_something_else
};

Here PTA0 etc are the pin names provided by your register map (I don't remember exact names) - they are integer constants. In the above example the function void do_something (void) will get called when PTA0 and only PTA0 is pressed. Whereas the function do_something_else will get called when PTA1 and PTA2 and nothing else is pressed. And so on - this design is easy to maintain and scales well.

Indices not mentioned in the above jump table will get automatically set to null since that's required by C.

We can then use this jump table with the debounced port value as index:

if( action[debounced_PORTA] == NULL )
{
  /* optional error handling */
}
else
{
  action[debounced_PORTA]();
}

huangapple
  • 本文由 发表于 2023年6月18日 23:00:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76501158.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定