質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

3回答

5536閲覧

Arduino 最大で2つのボタンの同時押し、押されたボタンの組み合わせの判定と結果の入力

j8loop

総合スコア0

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2021/11/28 09:32

編集2021/11/28 10:55

Arduino Microで2つのボタンの同時押し、場合分けについて教えてください。
将来的には6つのボタンまで増やすつもりなのですが、そもそも2つができてない状態です。

やりたいこと:

Button 1, 2が押される → 全て離した瞬間、Cを入力
Button1が押される → 離した瞬間、Aを入力
Button2が押される → 離した瞬間、何も入力しない

使用ライブラリ:

ezButton

試したコード:

c

1/#include <ezButton.h> 2 3ezButton button1(2); 4ezButton button2(3); 5 6void setup() { 7 // put your setup code here, to run once: 8 button1.setDebounceTime(50); 9 button2.setDebounceTime(50); 10 11 Serial.begin(9600); 12 13} 14 15void loop() { 16 // put your main code here, to run repeatedly: 17 button1.loop(); 18 button2.loop(); 19 20 int btn1State = button1.getState(); 21 int btn2State = button2.getState(); 22 23 if((button1.isPressed()) && (button2.isPressed())){ 24 Serial.println("C"); 25 } else if (button1.isPressed()){ 26 Serial.println("A"); 27 } else if (button2.isPressed()){ 28 Serial.println(""); 29 } 30 31} 32

補足情報:

自分が書いたものは、ボタンが押した瞬間の検出であって、押下されたボタンの組み合わせを検出するものではないことには気づけているのですが、Arduinoがわかってくれる書き方や、使用すべき構文の当てがついていません。

日本語、英語でGoogleやフォーラムを検索したのですが、分からなくて、困っています。
どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2021/11/28 10:42

このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
j8loop

2021/11/28 10:55

ご指摘ありがとうございます。更新をいたしました。
guest

回答3

0

Arduino Leonardo で試してみました
二つのスイッチの同時押し時間差は、0.5秒まで許容しています

#include <MsTimer2.h> #define SW_MAX 6 #define SW_TIME 500 // 500ms const unsigned char SW_PIN[] = { 4,5,6,7,8,9 }; // sw port volatile unsigned char sw_flag[ SW_MAX ]; volatile unsigned char sw_code = 0; void prn_bin( unsigned char dat ){ char i; for ( i=7 ; i>=0 ; i-- ){ Serial.write( 0x30 + bitRead( dat , i ) ); } // for } void sw_scan(void){ static unsigned char sw_mode = 0; static unsigned long swa_time ; static unsigned char swa , swb , swc ; unsigned char i; if ( sw_code != 0 ){ return; } for ( i=0 ; i<SW_MAX ; i++ ){ sw_flag[i] = ( ( sw_flag[i] << 1 ) | digitalRead( SW_PIN[i] ) ) & 0x03 ; if ( sw_flag[i] == 0b10 ){ // sw_on switch( sw_mode ){ case 0: swa = i ; swa_time = millis() ; sw_mode = 1 ; break ; // swa_on_time case 1: if ( ( millis() - swa_time ) < SW_TIME ){ swb = i ; sw_mode = 2 ; } break; } // switch } // if if ( sw_flag[i] == 0b01 ){ // sw_off switch( sw_mode ){ case 1: if ( i == swa ){ bitSet( sw_code , swa ); sw_mode = 0; } // sw_single break ; case 2: if ( i == swa ){ swc = swb ; sw_mode = 3; } // sw_double if ( i == swb ){ swc = swa ; sw_mode = 3; } break; case 3: if ( i == swc ){ bitSet( sw_code , swa ) ; bitSet( sw_code , swb ); sw_mode = 0; } break; } // switch } // if } // for } void setup() { unsigned char i; for ( i=0 ; i<SW_MAX ; i++ ){ pinMode( SW_PIN[i] , INPUT_PULLUP ); sw_flag[i] = 0xFF; } Serial.begin(9600); while( !Serial ); Serial.println("Arduino Leonardo !!"); MsTimer2::set( 10 , sw_scan ); MsTimer2::start(); } void loop() { if ( sw_code != 0 ){ Serial.print("sw_code = "); prn_bin( sw_code ); if ( sw_code == 0b00000011 ){ Serial.print(" C"); } if ( sw_code == 0b00000001 ){ Serial.print(" A"); } Serial.println(); sw_code = 0; } // if }

実行結果↓

Arduino Leonardo !!

sw_code = 00000001 A
sw_code = 00000010
sw_code = 00000100
sw_code = 00001000
sw_code = 00010000
sw_code = 00100000
sw_code = 00000011 C
sw_code = 00000110
sw_code = 00001100
sw_code = 00011000
sw_code = 00110000
sw_code = 00000101
sw_code = 00001010
sw_code = 00010100
sw_code = 00101000

投稿2021/12/04 06:39

編集2021/12/05 04:10
koujikuu

総合スコア401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

検索するんじゃなくて、自分で考えるんです。

当然ながら、人が手で複数のスイッチを押すのに「全く同時に押される」「全く同時に離される」なんてことはなかなかないので、それなりの時間差は考慮されなければいけません。この時間差をどこまで許すか、なんてのも作りやすさに大きく関わってきますけれど。

で。いろいろ解釈が難しいのですけれど、「同時押し」って本当に「同時」押しを知りたいのでしょうか?
どうせ6つ押しができなきゃいけないなら最初からそれを前提に考えますけれど(2つは単純化しすぎだと思う)、
例えばこんな場合は3つ同時押しの判別になるのですか? それとも、2つ同時押しが2回の判断なんですか?
同時押し?

いずれにしろ、そのライブラリはisReleased()という機能もあるようですから、それぞれのボタンが押された時、離された時に他のボタンの状態を調べて適切な判断をするというようにしないとどうにもならないんじゃないかと。

上図を3つ同時とみなすなら、loop()内はこんな処理になるでしょうか。
・スイッチが押されたことを検出したら
・・検出中フラグを立てる
・・スイッチが押されたことを記録
・全部のスイッチが離されていたら
・・検出中フラグが立っていたら
・・・検出フラグクリア
・・・押された記録のあるスイッチを調べて同時押し確定
・・・全てのボタンの押された記録をクリア

2つ同時x2とみなすならこう、かな
・スイッチが押されたことを検出したら
・・検出中フラグを立てる
・・スイッチが押されたことを記録
・スイッチが離されたことを検出したら
・・検出中フラグが立っていたら
・・・検出フラグクリア
・・・押された記録のあるスイッチを調べて同時押し確定
・・このボタンの押された記録をクリア

投稿2021/11/28 13:38

thkana

総合スコア7639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

j8loop

2021/11/29 10:22

こんばんは。 早速に、大変詳しくご説明をいただいて、ありがとうございます。考え方が、大変参考になります。 いただいた情報をもとに、もう少しいろいろ試してみます。どうもありがとうございました。
guest

0

定期的にボタンの状態を読み込み、2つのボタンが押されているのを検出したあと、すべてのボタンが離されたのを検出した場合に、何かをする、と考えるとわかりやすいかと思います。

#んで、プロ(?)がこういう実装をする場合は、周期タイマ割り込みでこの処理を行ったりします

投稿2021/11/28 11:07

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

j8loop

2021/11/28 11:54

早速に手がかりをいただきありがとうございます。いただいたロジックでもう一度調べてコードを書いてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問