Arduino Plug and Makeプロジェクト:メトロノーム


APDahlen Applications Engineer

Arduino Plug and Makeは、最新のArduino UNO R4 WiFiと、一連のModulinoボードを含み、製作者に優しいキットです。この記事では、Plug and Makeのコンポーネントの組み立て方と、音と光で音楽の拍子を示すメトロノームとして動作させるための、プログラミングの方法を説明します。また、UNO R4 WiFiのマトリックスディスプレイを使用して、1分間の拍数(BPM:Beats Per Minute)を表示することもできます。組み立てたプロジェクトの写真を、図1に示します。実際の動作は動画1で確認できます。1拍目を強調したメトロノームの音が聞こえます。また、1拍目は青、それ以外は赤に光る様子も確認できます。

コードはこちらからダウンロードしてください:Metronome.zip(3.0 KB)

図1: メトロノームプロジェクト用に組み立てられたArduino Plug and Make Kitのコンポーネントの写真。Modulinoモジュールはデイジーチェーン接続されたQwiicコネクタを使用して、電気的に接続されています。

動画1: 音楽の4拍子(4/4拍子)でメトロノームを動作させます。1拍目高い音で、青いLEDが点灯し、2拍目、3拍目、4拍目は低い音で、赤いLEDが点灯します。

プロジェクトで使用されているコンポーネント

このプロジェクトは、Arduino Plug and Make Kitに付属するコンポーネントで構築されています。追加されたのは、赤い半透明の、Hammondのエンクロージャ1591STRDのカバーだけです。この赤いカバーにより、UNO R4 WiFiのLEDディスプレイマトリックスが見やすくなり、撮影もしやすくなります。

Arduino 12 x 8 LEDマトリックスについてさらに詳しく知りたい方は、こちらの記事をご覧ください。Charlieplexing技術について説明しています。

Modulinoのチュートリアル

Modulinoボードの動作を説明した以下のDigiKeyチュートリアルにも、興味を持たれるかもしれません。

物理的な接続

Arduino Plug and Makeのハードウェアは、Qwiic接続により、組み立てを大幅に簡素化します。 図1は、コンポーネントを配置する1つの方法を示しています。それぞれのModulinoボードが個別にアドレス指定されているので、デイジーチェーンの配置や電気的接続の向きは重要ではありません。したがって、配線長が制限されるだけで、どの向きでも自由に選択できます。

ソフトウェアの説明

メトロノームにとって、予測可能なタイミングは最も重要です。光と音の双方を取り入れる場合、タイミングは特に難しくなります。プログラム開発者は、ブロッキングコードとノンブロッキングコードに特に注意しながら、個々のModulinoモジュールの動作を慎重に調整する必要があります。

ブロッキングコードとは何でしょうか?

一般的なブロッキングコードの例として、Arduinoのdelay( )関数があります。delay( )は、遅延時間が経過するまでloop( )コードの動作を停止させることを思い出してください。Delay( )が実行されている間は、マイクロコントローラはユーザー入力に応答できなくなり、事実上無効となります。

技術的なヒント: delay( )関数は、loop( )プログラムを停止します。割り込みサービスルーチン(ISR:Interrupt Service Routines)を使用することにより、バックグラウンドで発生するプロセスには影響しません。例えば、millis( )に関連するタイマメカニズムはバックグラウンドで継続して実行されます。これは望ましい動作です。なぜなら、メトロノームの主な機能は、バックグラウンドの割り込みサービスルーチン(ISR)として発生するこれらのタイミングメカニズムに完全に依存しているからです。

1分間の拍数(BPM)の監視

1分間の拍数(Beats Per Minute、BPM)の値は、Modulino Knob(ツマミ付きエンコーダ)モジュールで監視されます。このKnobモジュールは、ロータリエンコーダと、ポジションを監視しQwiicバス上で通信を行うマイクロコントローラで構成されています。このマイクロコントローラは、ユーザーが入力した「ロータリクリック」の回数(整数)を監視します。各クリックは、BPM値の1回の切り替えに相当します。この動作は、get( )メソッドを使用して実行されます。set( )メソッドは、BPM値の制限に使用されます。

BPMを監視する関数は以下に含まれています。この例では、set( )メソッドを使用して、BPM値を1から300BPMの範囲に制限しています。

int get_BPM( ){
  int BPM = encoder.get( );
  if (BPM < 1) {
    encoder.set(1);
    BPM = 1;                          // Don't divide by zero
  }
  if (BPM > MAX_BPM) {
    encoder.set(MAX_BPM);
    BPM = MAX_BPM;
  }
  return BPM;
}

BPMの表示

動画1で示されているように、Arduino UNO R4 WiFiのLEDマトリックスはBPMを表示するために使用されています。このコードはBPM値が変化したとき、具体的には、(BPM ! = last_BPM)の場合に実行されます。snprintf( )関数を使用して、BPM値を人間が読める文字列に変換し、LEDマトリックスに表示できるようにしている点に注目してください。

技術的なヒント: C言語の標準入出力ライブラリ(stdio.h)にあるsprintf( )とsnprintf( )関数は、同じような動作をします。ただし、sprintf( )は関連するバッファのサイズをチェックしないため、使用しないでください。この保護機能がないと、バッファが上書きされやすく、その結果、異常な動作が発生し、トラブルシューティングが非常に困難になります。

  if (BPM != last_BPM) {
    i = 0;                            // Always start a new sequence with beat 1
    delay(1000);                      // Allow the user time to set the new BPM (blocking metronome is off)
    BPM = get_BPM();                  // User should be done, get the new value
    last_BPM = BPM;
    matrix.beginDraw();               // Standard Arduino code to operate the UNO R4 WiFi’s LED matrix
    matrix.stroke(0xFFFFFFFF);
    matrix.textScrollSpeed(50);

    snprintf(buffer, sizeof(buffer), "   %d BPM   ", BPM);  // See tech tip
    matrix.textFont(Font_5x7);
    matrix.beginText(0, 1, 0xFFFFFF);
    matrix.println(buffer);
    matrix.endText(SCROLL_LEFT);
    matrix.endDraw();

    delay_val = 60000 / BPM;          // 60 second per minute and 1000 ms per second
  }

技術的なヒント: ArduinoのLEDマトリクスディスプレイAPIはブロックされています。そのため、メトロノームが動作しているときはBPM表示は利用できません。

どのように拍子が刻まれているのでしょうか

Arduinoのマイクロコントローラで拍子を刻む方法は数多くあり、ブロッキングコードのdelay( )やmillis( )の使用、上級ユーザー向けの専用ハードウェアタイマなどが含まれます。このプロジェクトでは、この記事で説明されているノンブロッキングタイマコードを使用することにします。このコードは、コンパクトなクラスベースのルーチンにmillis( )関数を組み込んだ妥協案です。参考記事には、従来のArduinoのノンブロッキング手法とコンパクトなクラスベースの実装を説明するチュートリアルが含まれています。

タイミングに関する記事を読めば、プログラマブルロジックコントローラ(PLC:Programmable Logic Controllers)に重点が置かれていることに気づくでしょう。実際、タイマコードはPLCのストラクチャードテキスト(ST:Structured Text)言語を使用してプログラムされたタイマモジュールであるかのように機能します。タイマクラスの使用例を以下に示します。この場合、TON_1は5秒ごとにパルスを1回生成します。TOF_1タイマは、このパルスを300ミリ秒延長します。その結果、5000ミリ秒ごとに300ミリ秒のパルスを生成する点滅変数が生成されます。

  // Produce a pulse that is one program scan long that occurs once every 5 seconds.
  // Use that pulse to blink an LED with a 300 ms on period.

  TON_1.update(!TON_1.Q, 5000);
  TOF_1.update(TON_1.Q, 300);
  int blink = TOF_1.Q;

技術的なヒント: このタイマコードは、PLCの実験として開発されました。PLCは、マシンやプロセスの実際の制御用に設計されていることを思い出してください。基本的には、PLCコードはノンブロッキングです。

このタイマコードはまた、AIを用いた実験の1つでした。ChatGPT 4.0にPLCのストラクチャードテキスト(ST)実装のような動作をするクラスベースのArduinoタイマモジュールの構築を依頼しました。数時間の改良を経て、コードはArduino環境でSTのような(ノンブロッキング)ステートメントを使用して期待通りに動作するようになりました。これは、ある環境(PLC ST)の技術を別の環境(Arduino C++)に適応させることでコーディングのスキルを向上させる良い例です。

音楽の拍子を刻む

ここで、拍が刻めるようになりました。このコードスニペットに示されているように、メトロノームは4/4拍子を刻むように固定されています。1拍目は、より高い880Hzの音と青色のLEDの点滅で強調されています(動画1を参照)。その他の拍はすべて、440Hzの音と赤色のLEDの点滅で示されています。

コードリストには、ブロッキングルーチンとノンブロッキングルーチンの両方が混在しています。buzzer.tone(880, 50)のようなステートメントは、880Hzの音を50ミリ秒間鳴らすので、ブザーはノンブロッキングです。LEDの点灯には、より複雑なブロッキングメカニズムが必要です。LEDの点灯に使用されるshow( )と、LEDの消灯に使用される2番目のshow( )メソッドの間に、一定の時間が経過しなければならないことに注目してください。LEDは非常に明るいので、5ミリ秒の期間で十分です。

if (TON_1.Q) {                // This is a pulse (high for one loop( ) cycle) coincident with the BPM.
    if (i >= 4) {             // TODO: Allow user to adjust the musical meter.
      i = 0;
    }

    if (i == 0) {
      buzzer.tone(880, 50);	  // hard code musical note A3
      flash_LED(BLUE, 50, 5);

    } else {
      buzzer.tone(440, 50);   // hard code musical note A4
      flash_LED(RED, 50, 5);
    }
    i++;
  }

今後の改善点

このプロジェクトは、Arduino Plug and Makeの使用方法を簡単に紹介するものです。このデバイスには、まだ改善の余地が十分にあります。ご参考までに、いくつかのアイデアを以下に紹介します。

  • 拍子を変えるには、Modulino Buttons(ボタン付き)モジュールを使用します。現在、拍子は4/4拍子に固定されています。ユーザーが選択できる拍子として、2/2拍子、3/4拍子、4/4拍子、さらに5/4拍子も用意しておくと便利です。そうすれば、「ミッションインポッシブル」のメインテーマをロック調にアレンジすることができます。

  • 一定のチューニング音を鳴らすボタンを設置します。

  • ユーザーインターフェースの応答性を改善します。例えば、粗調整と微調整を実装し、ユーザーが希望するBPMをすばやく設定できるようにします。

  • フットペダルを追加し、スライド(ダイナミックにテンポを調整)させることで、ソロ演奏者に自然なフレージングを持たせます。

  • デバイスの正確なBPMを測定し、その後、校正します。

  • 意欲的な実験者は、DDS(Direct Digital Synthesis)などの高度なコンポーネントや技術を使用したブレッドボードへ移行し、これにより、音量を変えることができる正弦波のチューニング音(複数音)を生成することができます。任意波形発生器を追加して、ロボットのようなビービーという音から、木琴やカウベルのようなビート音に変えることもできます。もっとカウベル音がほしいですね!

  • 12 x 8ディスプレイをノンブロッキングに変更します。これにより、ディスプレイはBPMを常に表示し続けることができます。

おわりに

Arduino Plug and Make Kitは、学生がさまざまなセンサやアクチュエータを試すのに便利なプラットフォームを提供します。ブレッドボード不要の設計により、学生はソフトウェアに専念することができます。

この記事で紹介したメトロノームは、非常に簡単に再現できます。同時に、改善の余地もたくさんあります。最初の課題は、Modulino Buttonsモジュールを駆使して、4/4拍子から、2/4拍子、ワルツ(3/4拍子)、5/4拍子、さらにはピンクフロイドの「Money」のようなジャズ風の7/4拍子に変更できるようにすることです。

オープンソースコミュニティの精神に則り、ご自身のメトロノームをコピー、改善、そして配布をお願いします。ご意見やご質問は、以下のスペースにご記入ください。

ご健闘をお祈りします。

APDahlen

関連する情報

関連する有益な情報については、以下のリンクをご覧ください。

著者について

Aaron Dahlen氏、LCDR USCG(退役)は、DigiKeyでアプリケーションエンジニアを務めています。彼は、技術者およびエンジニアとしての27年間の軍役を通じて構築されたユニークなエレクトロニクスおよびオートメーションのベースを持っており、これは12年間(一部、軍での経験を織り交ぜて)教鞭をとったことによってさらに強化されました。ミネソタ州立大学Mankato校でMSEEの学位を取得したDahlen氏は、ABET認定EEプログラムで教鞭をとり、EETプログラムのプログラムコーディネーターを務め、軍の電子技術者にコンポーネントレベルの修理を教えてきました。彼はミネソタ州北部の自宅に戻り、このような記事のリサーチやエレクトロニクスとオートメーションに関する啓蒙記事の執筆を楽しんでいます。

注目すべき経験

Dahlen氏は、DigiKey TechForumに積極的に貢献しています。この記事を書いている時点で、彼は180以上のユニークな記事を作成し、さらにTechForumへ580にものぼる投稿を提供しています。Dahlen氏は、マイクロコントローラ、VerilogによるFPGAプログラミング、膨大な産業用制御に関する研究など、さまざまなトピックに関する見識を共有しています。




オリジナル・ソース(English)