3

高周波でサンプリングしており、Arduino から UART 経由で 10 ビットの ADC 値を送信する必要があります。

デフォルトでは、1 文字あたり 1 バイトを使用します。したがって、analogRead を実行すると "612" の値が得られる場合、UART 経由で "6" を 1 バイトとして、"1" を 1 バイトとして、"2" を 1 バイトとして、行ターミネータを最後のバイトとして送信します。

この通信によってサンプリング レートが切り捨てられることを考えると、可能な限り効率的かつ均一であることが重要です。そのため、実際のデータが何であるかに関係なく、そのデータを送信するために 2 バイトを使用するように強制しようとしています (byデフォルトでは、"23" の送信に 3 バイト、"883" の送信に 4 バイト、"1001" の送信に 5 バイトが使用されます)。

現在、私はこのようなことをしています。これは私が見つけた最良の方法です:

int a = 600; //Just an example
char high = (char)highByte(a);
char low = (char)lowByte(a);
Serial.print(high);
Serial.println(low);

現在、これは値に関係なく 3 バイト (\n を含む) を使用します。さらに効率的な方法はありますか?

のようなもので印刷するだけです

Serial.print(foo, BIN);

まったく機能しません。実際には、foo のバイナリ表現の各ビットごとに 1 バイトを使用しますが、これは非常にばかげています。

4

2 に答える 2

11

私は何かが足りないかもしれませんが、なぜあなたは使わないのですSerial.write(byte)か?

次のようなメソッドを使用できます。

void writeIntAsBinary(int value){
    Serial.write(lowByte(value));
    Serial.write(highByte(value));
}

コンピューター上のデータをどうする予定ですか?

于 2013-10-10T11:56:21.580 に答える
8

バイナリ データをシリアル ラインで送信する場合、テキスト スタイルの改行区切り文字を使用してすべてを混乱させるべきではありません。

一方、何らかの同期の助けがなければ、どのバイトがどれであるかを知るのは(相手側にとって)ちょっと難しいです。

ただし、ペイロードは 10 ビットしかないのに 16 ビットのデータを送信するため、「UTF-8 を実行」し、空きビットを使用して「値の開始」を知らせることができます。これには、ペイロードに各 8 ビット バイトの 7 ビットのみを使用する必要がありますが、7 + 7 = 14 は 10 をはるかに超えるため、問題ありません。のバイト":

const int a = 600;
const unsigned char high = ((a >> 7) & 0x7f) | 0x80;
const unsigned char low  = (a & 0x7f);

Serial.print(high);
Serial.print(low);

上記では、送信される 2 バイトは次のようになります。

high == ((600 >> 7) & 0x7f) | 0x80 == 4 | 0x80 == 0x84
low  == (600 & 0x7f)               == 88       == 0x58

受信者は上記を逆に実行する必要があります。

const int value = ((high & 0x7f) << 7) | low;

これは機能し、最初に送信される上位バイトの最上位ビットを使用して、それが実際に上位バイトであることを示します。下位バイトに MSB が設定されることはありません。

于 2013-10-10T11:00:11.487 に答える