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

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

ただいまの
回答率

89.64%

ARDUINO UNO シリアル通信を使わずにキーボードの入力から音を出したい

受付中

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,163

The_ren

score 5

初めに

こんにちは!
授業でARDUINOを触っているものです。現在、成果物として、パソコンのキーボードを入力するとピアノのように音楽が引けちゃうプログラムを作成中です。シリアル通信で対応したキーを入力するとドレミが出力するシステムが出来上がっているのですが、連続で鳴らしたいときにどうすれば良いのか分からずに困っています。

プログラムコード

以下がプログラムコードになります。

// 12番ピンをスピーカーに接続する
const int pin = 12;
int melo =200;
// 10番,8番ピンをLEDに接続する
const int LED = 10;
const int LGD = 8;



// ここで初期化する
void setup()
{
  // スピーカーをつないだピンを出力に設定する
  pinMode(pin, OUTPUT);
  pinMode(LED, OUTPUT);
  // 9600bpsでシリアル通信を始めます
  Serial.begin(9600);
}

// ここからループに入る
void loop()
{
  // シリアル通信でパソコンから入力された文字を変数に保存する
  int sw = Serial.read();
  // もしaという文字が送られてきたら
  if (sw == 'a') {
    // ドを鳴らす
    tone(pin,262,melo);
    digitalWrite(LED,HIGH);
    delay(500);
    digitalWrite(LED,LOW);
  // もしsという文字が送られてきたら
  } else if (sw == 's') {
    // レを鳴らす
    tone(pin,294,melo);
    digitalWrite(LGD,HIGH);
    delay(500);
    digitalWrite(LGD,LOW);
  // dが送られたら
  } else if (sw == 'd') {
    //ミを鳴らす
    tone(pin,330,melo);
    digitalWrite(LED,HIGH);
    delay(500);
    digitalWrite(LED,LOW); 
  // もしfという文字が送られてきたら
  } else if (sw == 'f') {
    // ファを鳴らす
    tone(pin,349,melo);
    digitalWrite(LGD,HIGH);
    delay(500);
    digitalWrite(LGD,LOW);
  // gが送られたら
  } else if (sw == 'g') {
    //ソを鳴らす
    tone(pin,392,melo);
    digitalWrite(LED,HIGH);
    delay(500);
    digitalWrite(LED,LOW); 
  // もしhという文字が送られてきたら
  } else if (sw == 'h') {
    // ラを鳴らす
    tone(pin,440,melo);
    digitalWrite(LGD,HIGH);
    delay(500);
    digitalWrite(LGD,LOW);
  // jが送られたら
  } else if (sw == 'j') {
    //シを鳴らす
    tone(pin,494,melo);
    digitalWrite(LED,HIGH);
    delay(500);
    digitalWrite(LED,LOW); 
  }
}

このコードで実行したいこと

現在、シリアル通信を使っています。
パソコンのキーボードを入力し、対応したキーを押すとドレミファソラシドの内の一つを出力します。同時にキーを押すと同時に音だけでなくLEDが光るように設定されています。
しかし、シリアル通信だと、入力したキーを逐一送信してあげないと音が出力されません。そのため、ピアノのように連続した状態で鳴らすのが困難になっています。

最終的に達成したいこと

現在はシリアル通信でキーボードの入力を音と光で出力するように設計していますが、最終的にはシリアル通信を使わずにキーボード入力でそのままピアノのように音楽を演奏できるプログラムを設計したいです。課題の提出が1週間程度しかないので焦っています。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • y_waiwai

    2019/07/21 08:43

    > ピアノのように連続した状態で鳴らすのが困難になっています。
    現状ではどういう動作になってるんでしょうか

    キャンセル

  • The_ren

    2019/07/21 18:57

    現状は、一つの入力に対して対応したドレミ音が返ってくる程度です。
    シリアル通信のため、逐次エンターキーを押さないと出力が反映されません

    キャンセル

  • coco_bauer

    2019/07/24 09:58

    「最終的にはシリアル通信を使わずにキーボード入力でそのままピアノのように」というのを実現する際、PCとArduinoの間で信号をやり取りする方法は、どうするのですか?

    キャンセル

回答 2

+2

「シリアル通信」(UART)がコトの本質なのでしょうか? そこをちゃんと見極めないと、見当違いの苦労をして結局何も得られない、なんてことになりかねません。

楽器やシーケンサなどを繋ぐために使われているMIDIインターフェース。これも言ってしまえばシリアル通信。'Arduino MIDI'でググってみれば作例がいくつも見つかると思いますが、ArduinoのUARTを使っているものがほとんどでしょう。楽器で「連続で音が鳴らせない」では話になりませんから、MIDIではそれが出来るはず。つまり、UARTを使っていることは「連続」を検出できないことの本質ではない、ということが推察出来るでしょう。

じゃあなんで「連続」音が出ないのでしょう? 

そもそも「連続」って何? ということをちゃんと考えてみて下さい。音を出し始めて、任意の時間に止める。止めるためには何が必要か。キーを離した、という情報。

今のプログラムでは、キーが押されたら音を一定時間出しています。では、キーが離された情報は? 扱ってない、というよりそもそも送られて来ていないでしょう。送られてこないのは何故ですか? 経路がシリアル通信だからではなく、そもそもPCから送り出されていないから、では。

PC側をどうしているのか情報がありませんが、シリアルモニタとかあるいはターミナルプログラムを使っているのでしょう。そういったプログラムは、「キーが押された」ことさえ伝えられれば求められている機能を果たすので、そのように作られています。それを今回のような用途に流用したならば、機能が足りないのは当然です。目的が違うのですから。

さて、どうしましょう。とりあえず3つの選択肢があるかと思います。

  1. Arduino用の'USBホストシールド'を使って、USBキーボードを直結して「押した」「離した」情報を取得して音を出すプログラムを作る
  2. PC側でキーボードの「押した」「離した」情報を取得し、COMポート経由で送信する(PC側の)プログラムと、これを受けて音を出す/止める(Arduino側の)プログラムを作る
  3. 課題の範囲外と諦める(どこまでが範囲なのか私は知りませんが)

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/07/21 15:50

    1ですが、外部に別装置が必要なUSBキーボードよりArduino単体で読めるPS/2キーボードを使うのを私はお勧めしますね。
    何にせよ現状から1週間でできるかというとそれなりに厳しい気がしますが。

    キャンセル

  • 2019/07/21 16:12

    確かに選択肢としてはありですね。
    しかし、古い人(?)ならPS/2キーボードの一つや二つ押し入れに転がってるでしょうが、この質問を発するような人がPS/2キーボードとそのコネクタをひょいと入手できるのかとか、この件が片付いたあとそのキーボードどうするの? とか思わないでも。

    思いついたけど、課題の詳細によっては自分でキースイッチを6個並べてキーボード(鍵盤装置?)を作る、という手も許されるのかも。

    3はともかくとして、質問のプログラムを理解して作れているのなら、1でも2でも、あるいはPS/2キーボードでもスイッチを並べても、楽とはいいませんが一週間(ってのは今度の金曜のことか?)頑張れば出来ると思いますよ。
    追加ハードが要るものはモノの入手(とコスト)もちょっとネックになるかも知れません。

    キャンセル

0

どういうことをしたいのかイマイチ不明ですが、

おそらく、あなたの思うような動作にならない原因は、シリアル通信をしているからではありません。
他の方法にしたところで、同じ結果にしかなりませんよ。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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