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

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

ただいまの
回答率

90.35%

aruduinoのタクトスイッチのことを教えてください

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 901

OtoMura

score 17

タクトスイッチで音のモードを変えられるようにしたいのですがどうしてもわからなくて教えていただけないでしょうか。

3つのタクトスイッチをそれぞれ押すと”ド” ”レ” ”ミ”と鳴りもう一つのタクトスイッチを押すと3つの音が”ファ” ”ソ” ”ラ”と鳴るようにプログラムをしているのですが、切り替えに使うタクトスイッチの初めの切り替えはできたのですが、元に戻す時のプログラムがどうしてもわかりません。どんな仕組みにすればいいですか?
まだ始めたばかりでわからないことも多いのですが教えていただけないでしょうか。

 作ったプログラム

void setup() {
 pinMode(A2,INPUT_PULLUP);
 pinMode(A3,INPUT_PULLUP);
 pinMode(A4,INPUT_PULLUP);
 pinMode(A5,INPUT_PULLUP);
}
int a = 0;
int aqw[] = {262,294,330,349,392,440,494};
void loop() {
  if (digitalRead(A2)==LOW) tone(13,aqw [a],30);
  if (digitalRead(A3)==LOW) tone(13,aqw [a+1],30);
  if (digitalRead(A4)==LOW) tone(13,aqw [a+2],30);
  if (digitalRead(A5)==LOW) a=3;    //ここからが分かりません
  }

 試したこと

IFやWHILE、FORなどでやってみたりしたのですが、A=1にした時何を条件にして切り替えれば良いのか分かりません.

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • y_waiwai

    2018/03/26 23:09

    タクトスイッチは4つあるんでしょうか?

    キャンセル

  • OtoMura

    2018/03/26 23:11

    はい

    キャンセル

  • OtoMura

    2018/03/26 23:11

    4つ目で変換したいんです。

    キャンセル

回答 4

+2

全部タクトスイッチですか? 「切り替え」用のスイッチは最初はトグルスイッチとかシーソースイッチの方がわかりやすいようにも思いますけれど。

タクトスイッチで「切り替え」をおこなうには、手を離すと接点も離れちゃいますから、「押されている」ことを調べても駄目で「押された」ことを検出して、押された瞬間だけ切り替え動作を行うことになります。

さて、「押された」ってどういうこと? 直前までは押されていなくて、今は押されている、ということ。

//setupとかは変更なし
int prevA5=HIGH;//直前のA5の状態を記憶するための変数。最初は「押されていなかった」設定。
void loop(){
  if (digitalRead(A2)==LOW) tone(13,aqw [a],30);
  if (digitalRead(A3)==LOW) tone(13,aqw [a+1],30);
  if (digitalRead(A4)==LOW) tone(13,aqw [a+2],30);

  int curA5=digitalRead(A5);//プログラム中で何度もdigitalRead(A5)で状態を調べると、もしかしたら途中でスイッチの状態が変わってしまっていることもあるかも知れないので検査は一回だけにする
  if ( (prevA5==HIGH) && (curA5==LOW) ){ //直前は押されていませんでした、そして今は押されています...つまり、スイッチが今まさに押されました、ということを検出する
    if(a==0){//今までがa==0だったらaを3に、そうでなっかたらaを0に設定する
      a=3;
    }else{
      a=0;
    }
    delay(50); //簡易「チャタリング」避けで時間をおく
  }
  prevA5=curA5; //今の状態は、次の瞬間には「過去」になる
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/27 01:53

    スイッチは、プルアップしているのでOFF状態だとdigitalRead(A5)でHIGH, ON状態でLOWが返りますよね。
    prevA5はdigitalRead(A5)がLOWだったかHIGHだったかを記憶しているわけです。
    なので、スイッチがOFFである(prevA5なのでOFFであった、という方が正確か)、ということを調べています。

    キャンセル

  • 2018/03/27 02:13

    じゃぁ、こっちはとりあえず動いたみたいなんで寝ますね...(って、こんなチャットみたいに使う欄なのか、ここは?)

    キャンセル

  • 2018/03/27 08:26

    ありがとうございました。

    キャンセル

checkベストアンサー

+1

こんなかなー。

void setup()
{
 pinMode(A2,INPUT_PULLUP);
 pinMode(A3,INPUT_PULLUP);
 pinMode(A4,INPUT_PULLUP);
 pinMode(A5,INPUT_PULLUP);
}

int a = 0;
int aqw[] = {262,294,330,349,392,440,494};

void loop()
{
  if (digitalRead(A2)==LOW) tone(13,aqw [(a * 3) + 0],30);
  if (digitalRead(A3)==LOW) tone(13,aqw [(a * 3) + 1],30);
  if (digitalRead(A4)==LOW) tone(13,aqw [(a * 3) + 2],30);

  if (digitalRead(A5)==LOW)
  {
    a++;
    if(a > 1) { a = 0; }
  }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/27 12:49

    質問者も回答者も様々ですので、全員納得するのは難しいところもあると思います。
    このコードの場合、
    例えば、loopが10ms間隔で動作しており、ボタンを10ms以下だけ押して離した場合、A5 == LOW 部分は1回通り、a=1 で 以降、ファゾラで鳴り、11-20msで押して離した場合、A5 == LOW 部分は 2回通り、a=0 に戻って、以降、ドレミが鳴り、押した回数だけではなく、押した時間にも依存する。
    ような動作をすると思われます(机上での想像ですが)。
    段階を踏んで確認してもらうのは対面学習的に非常に良いと考えますが、
    この動作は動かなかった場合の確認、デバッグとして初心者には難しいように思えます。

    キャンセル

  • 2018/03/27 12:57

    で、わからなかったから「何故ですか?」と聞いて、それにこたえるわけですよ。

    フルコース料理、一度に全部出すシェフのとこで食べたいですか?

    キャンセル

  • 2018/03/27 13:20

    シェフや隣の客とも色々喋りながら食べられる、teratailは好きです。
    通りすがりの一見さんに長々お付き合いくださりありがとうございました。

    キャンセル

0

ああ、スイッチは4つあるのね。
4つ目のスイッチ押したときに、交互にaを1と0にして、 aの値で3つのスイッチの動作を切り替えればいい


訂正。
きちんと配列で音の高さ変えるようにしてるのね。
そしたら修正は最後の a の代入のところで、
aが0だったら aに3を入れ、
aが0以外だったら、aに0を入れるようにすればいい

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/27 01:54

    うごかしてみた?

    キャンセル

  • 2018/03/27 23:12

    はい。
    完璧です!

    キャンセル

  • 2018/03/27 23:13

    ありがとうございました。

    キャンセル

0

Arduinoはやったことありませんが、ブール型を利用すれば簡潔に記述できるのでは?
という内容で記述してみました。
Arduino 日本語リファレンス【ブール型】
Arduino 日本語リファレンス【true/false (論理レベルを定義する定数)】

あくまで、false=0 true=1 という値を取ればという前提ですが。

動くかどうかも、いや、コンパイルさえ通るかどうかも分かりませんけど。

void setup() {
 pinMode(A2,INPUT_PULLUP);
 pinMode(A3,INPUT_PULLUP);
 pinMode(A4,INPUT_PULLUP);
 pinMode(A5,INPUT_PULLUP);
}
boolean A5switch = false;
int aqw[] = {262,294,330,349,392,440,494};
void loop() {
  if (digitalRead(A2)==LOW) tone(13,aqw [(A5switch * 3) + 0],30);
  if (digitalRead(A3)==LOW) tone(13,aqw [(A5switch * 3) + 1],30);
  if (digitalRead(A4)==LOW) tone(13,aqw [(A5switch * 3) + 2],30);
  if (digitalRead(A5)==LOW) {
    delay(100);                   // バウンシング対策
    A5switch = !A5switch;         // ブール変数でオンオフ切替
  }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/27 11:24

    実用上はそれほど困りませんが、この場合も、delay(100)以上の時間A5を長押しした場合の問題が残ると思います。

    キャンセル

  • 2018/03/27 11:30 編集

    コメントありがとうございます。
    はい、その点については、考慮外です。(というか知識がありません)
    他の回答されている方(THOR_V6さんとか)のロジックが正しいなら、それと組み合わせて貰えば良いかと。
    フラグ反転とそれを利用した値の取得というのが主眼です。

    キャンセル

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

  • ただいまの回答率 90.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る