質問:
SoftwareSerialはMIDIには遅すぎますか?
Michel Keijzers
2017-05-20 06:06:16 UTC
view on stackexchange narkive permalink

MIDI用のSoftwareSerialライブラリを(47エフェクトで)使用しようとしましたが、定期的に破損した/予期しないメッセージが表示されるようです。

使用している回路は、に接続すると完全に機能します。 HardwareSerialソリューション(したがって、問題はソフトウェアにある必要があります)。

表示される内容:

  • ノートを押してリリースノートを押すと、LED13が正しくオン/オフになります。
  • デバッグにSerial.printを使用すると、正しいメッセージが表示されます。ただし、以下の例では、最小限の例を示すためにprintステートメントを削除しました。
  • SoftwareSerialを使用すると、すべてのノートでLED13が正しくオン/オフになります。ただし、多くのメッセージを送信すると(たとえば、短時間で多くのメッセージを送信するアフタータッチ/ピッチベンドなど)、「ランダム」値の注オン/オフコマンドが送信されることに気付きました。

一部の情報筋によると、SoftwareSerialはMIDIで機能するはずですが、これまでのところ完璧にはほど遠いです。間違いはありますか?

(ところで、MIDIのボーレートは31.250 bpsです。ピッチバンドを使用すると、これまでのところMIDI仕様の範囲内で、毎秒数百バイトが送信されます)。

使用するスケッチは次のとおりです。

  #include <MIDI.h> // Midiライブラリを追加します#include<SoftwareSerial.h>SoftwareSerial swSerial(2、11); // RX、TXMIDI_CREATE_INSTANCE(SoftwareSerial、swSerial、midiSw1); #define LED 13 // ArduinoボードのLEDはピン13にありますvoidsetup(){pinMode(LED、OUTPUT); // Arduinoボードのピン13を出力midiSw1.begin(MIDI_CHANNEL_OMNI);に設定します。 midiSw1.setHandleNoteOn(MyHandleNoteOn); midiSw1.setHandleNoteOff(MyHandleNoteOff);} void loop(){midiSw1.read();} void MyHandleNoteOn(バイトチャネル、バイトピッチ、バイト速度){digitalWrite(LED、HIGH); // LEDをオンにします} void MyHandleNoteOff(バイトチャネル、バイトピッチ、バイト速度){digitalWrite(LED、LOW); // LEDをオフにします}  
私はまったく同じ問題を経験しました。私の経験では、SoftwareSerialは、すばやく連続するMIDIメッセージを処理するのに十分な速度ではありません。 MIDIにハードウェアシリアルを使用し、デバッグにSoftwareSerial +別のArduinoを使用すると、最良の結果が得られることがわかりました。これは最良の設定でしたが、それでも完璧ではありませんでした。ハードウェアシリアルでさえ、時々メッセージを落としたり壊したりしました。
`digitalWrite`は遅すぎるかもしれません。 `PORTB | = 0x20;`および `PORTB&= 〜0x20;`に置き換えてみてください。しかし、すべてのMIDI処理コードを高速化するためにできることは何もありません。
@Mazaryk ...私はすでに4つのハードウェアシリアルを持つMegaを使用していますが、これまでのところ、MIDI用に3つ、デバッグ用に1つを使用しています(今のところ、後で4番目のMIDIにすることができます)。そして、4番目がMIDIに使用される場合、おそらくデバッグとして別のArduinoを使用します。私は多くのテストを行いましたが、これまでのところ、メッセージがドロップ/破損することはありませんでした...そしてCLは、現在使用している6N138の代わりにさらに優れたH11L1オプトカプラーを使用することを提案しました。
@CL:ありがとう...スピードアップするためのすべてが良いかもしれません...しかし、ハードウェアシリアルソリューションはdigitalWriteでうまく機能し、ソフトウェアシリアルはうまく機能しなかったので、そのような「トリック」を使用する必要がある場合はまだ予測できないと思います。 ..後で、ソフトウェアソリューションが(再び)機能しなくなる可能性のある追加の処理も実行したいと思います。
1 回答:
Majenko
2017-05-20 16:53:46 UTC
view on stackexchange narkive permalink

SoftwareSerialの問題は、パケットを受信して​​いる間、ArduinoがRXバッファーからのバイトの読み取りを含む他のことを実行できないことです。そのため、送信が速すぎるとオーバーフローしやすくなります。 HardwareSerialを使用すると、データの受信中にバッファから読み取ることができるため、オーバーフローの問題は少なくなります。

パケットのSTARTビットを受信するとすぐに、ISRに入り、各パケットを読み取ります。タイトループ内の残りの9ビットのデータ(ストップビットを含む)。そのISRは、パケット全体が受信されてRXバッファに格納されるまで終了しません。別のバイトがすぐに送信された場合、ISRが終了してから再度トリガーされるまでの時間はほとんどありません。 RXバッファーからデータを読み取るMIDI解析ルーチンを含む残りのコードは、CPUサイクルが不足し、正しく実行できなくなります。送信するバイト数が多すぎると、制限されたRXバッファ(64バイト)がいっぱいになってオーバーフローし、データが失われます。

SoftwareSerialのもう1つの問題は、到着時にSTARTビットをキャプチャする必要があることです。そのエッジのキャプチャに遅延があると、ビットサンプリングタイミングがドリフトします。同時に割り込みを使用しているもの( millis()タイマーなど)がある場合、STARTビット検出に使用されるPCINT割り込みのトリガーが遅延します。 SoftwareSerial割り込み自体でさえ、パケットの受信が終了してからRXバッファーに格納され、割り込みルーチンから戻るまでに一定の時間があります。次のパケットがISRがサービスを提供する準備ができる前に 到着した場合、遅延が発生します。遅延は悪いものです。

個人的には、SoftwareSerialは決してそうすべきではないと考えています。何にでも使われます。より多くのシリアルポートが必要な場合は、より強力なチップが必要であるか、複数のチップが必要であり、それらを別のより高速なハードウェアチャネル(たとえば、SPIまたはI2C)を介して通信させます。

SoftwareSerialは、データの短いバーストを送信する場合(送信中に完全にブロックされるため)、または送信頻度の低い非常に短いメッセージを受信する場合にのみ適しています。

非常に役立つ情報(いつ​​ものように)...バッファを128バイトにしようとしましたが、改善は見られませんでした。もちろん、512個のうち256個にすることもできますが、説明を読んだら、問題が発生するまでの時間を「遅らせる」だけかもしれません。
あなたがいつもたくさんを送っているなら、そうです、あなたがすることはあなたが問題を見る前に時間を遅らせることだけです。また、次のパケットの受信速度が速すぎると、ISRが十分な速度で応答できなくなり、次のパケットの開始が失われ、パケット内の次の立ち下がりエッジで途中でトリガーされる可能性が常にあります。
たぶん将来(私のプロジェクトが成長するなら)私は別のボードに行かなければならないかもしれません(私に8つのハードウェアシリアルを与えます)。現在、私はSDシールドを使用しており、WIFIシールドと場合によってはUSB(ホスト)シールドを使用する予定です。追加のコンポーネント(いくつかのオプトカプラーなど)用のプロトタイプボードも必要です。だから多分2メガがいいでしょう:-)
たぶん3つでも;)多すぎることは決してありません。プロジェクトをコンポーネントブロックに分割し、それらを個別に制御および管理することをお勧めします。たぶん、他のすべてに何をすべきかを指示するよりも、1つの中央マスターコントローラーを持っているでしょう。
はい、私には完全に明確に聞こえます:-) ... MIDIに精通しているかどうかはわかりませんが、オン/オフは問題になりませんが、CCメッセージ(ピッチベンディング/アフタータッチなどの結果、バイト数が多くなります。 31250 bpsのMIDIのボーレート内ですが、SoftwareSerialには遅すぎる可能性があります。
それも非常にクールなアイデアのように聞こえます...しかし、これは私が行う最初のArduinoプロジェクトです:-) ...一方、プロジェクトがゆっくりと成長する場合は、Arduino /マイクロコントローラーについて多くを学ぶことは非常に良いことですエレクトロニクス。
ええ、私はMIDIをよく知っています。上記のコメントで述べたように、問題になる可能性があるのは量だけではなく、連続するパケット間のギャップです。 2つのパケットが近すぎて送信されただけでも、問題が発生する可能性があります。
そして、「問題」は、CCメッセージを失ってもかまわないということですが、ノートオフメッセージが処理されないと、(シンセのサウンドを変更しない限り)永遠に聞こえるノートになります...これはライブミュージックの状況。
絶対に。緊急時にすべての音を停止する「キルスイッチ」をプログラムすると便利です。念のため。
キルスイッチも便利なものではありません(私の場合)...シンセサイザーからのミスに応答し、それらを処理してメッセージを送り返すために、MIDIボックス(私はそれを呼んでいます)を許可したいのですが...演奏中はボックスが見えないかもしれませんが、MIDIメッセージを作成してそのようなキル(ノート)機能を実現することはできます。
ええ、それは直接接続された物理的なボタンである必要はありません-それが私が引用符を使用した理由です;)「地獄を閉めなさい」と言うために送ることができるただのいくつかの信号。たぶん、演奏したことのない音(C8など)に反応するようになっているので、キーボードの前に常にあります。あなたもそれをあなたのパフォーマンスに取り入れることになるかもしれません;)
[チャットでこのディスカッションを続けてください](http://chat.stackexchange.com/rooms/59042/discussion-between-michel-keijzers-and-majenko)。


このQ&Aは英語から自動的に翻訳されました。オリジナルのコンテンツはstackexchangeで入手できます。これは、配布されているcc by-sa 3.0ライセンスに感謝します。
Loading...