Thingsネットワークを介してデータを前後に送信するには、bytesを使用する必要があります。 このガ
私たちが構築するLoRaWAN技術の前例のない範囲は、低帯域幅と限られた放送時間(送信するパッケージの回数サイズ)を犠牲にしています。 幸いにも、空にする必要があるそのスマートなガレージの大箱の映像を必要としない。 単一のビットでさえ
1
するでしょう!,
バイトとは何ですか?
バイトは8ビットのグループです。 ビットは最も基本的な単位であり、1または0のいずれかになります。 バイトは8 0と1の間の値だけでなく、256(28)異なる組み合わせ(むしろ順列)からの範囲です。00000000
例えば01010101
から11111111
。 したがって、一つのバイトは0(00)から255までの小数を表すことができます。
困惑? 3つの小数点以下の数字は、3つの0から9の間の値を表すだけでなく、1000(103)の0(00)から999までの順列を表すことに注意してください。,
ものの仕組みの詳細:ビットとバイトの仕組みとArduinoのビット数学チュートリアルの詳細については、こちらをご覧ください。
バイトのバッファとは何ですか?
bufferは、あなたのプログラミング経験に共鳴するものは何でも、配列、リストの単なる別の単語として考えてください。 バイトが8ビットのグループであるように、バッファは事前に定義されたバイト数のグループです。 3バイトのグループがある場合、これは3つの0と255の間の値を表すことができますが、0と16777216(2563)の間の単一の値も表すことができます。
パターンを参照してください?, 位置あたりの選択肢の数(n)位置の数のべき乗(r)は順列の数です:nr.詳細については、こちらをご覧くださいMathIsFun.com.
どのような六角?
多くの場合、バイトのグループが次のように表示されます。
FF F0 0F 11
バイトは8のグループではありませんでした0
sと1
s?, √あなたは完全に正しいですが、すでに見たように11111111
古き良き十進数システムで255に変換され、各位置が16(0-9A-F)可能な値を持つ十進数システムでFFに変換することもできます。 利点は、最大値について短く明示的であることです(257はオプションではありません)。,
255 240 015 017
11
hexではなく、二つのビットまたはナンバーイレブンではなく、0x
フォーマッタであることを示すために、0x
フォーマッタをプレフィックスに付けます。 それを伝えるために、バイナリ使用を意味しますB
。,h>Code
11
0x11
B11
An example for Arduino:
Yeah, I know… 0x
kind of blows the shorter-to-write advantage of hex., √
どのように多くのバイトを送信することができますか?
技術的には、51バイトを送信できます。 しかし、あなたが送るより多くのバイトは、より多くの放送時間パッケージはあなたの費用がかかりますし、早くあなたの最大割り当てられた時間 なんで自分自身に尋ねくることができるお送りくお願いが少なくない。
大きな数字を送信するには?
より良い質問は、255より大きい範囲を送信する方法です。
Index
サポートする必要がある可能な値が0で始まらず、最小値がわかっている場合は、その番号にインデックスを付けることから始めます。,
たとえば、3400と3600の間の値が期待されるとします。,
デバイス上では、これを次のようにエンコードします。
int myVal = 3450;const int myBase = 3400;byte payload = { myVal - myBase };
アプリケーションペイロード関数では、
var myBase = 3400;decoded.myVal = bytes + myBase;
逆に、アプリケーションエンコーダペイロード関数では、
var myVal = 3450;var myBase = 3400;var bytes = ;
そして、デバイス上でこれを次のようにデコードします。
int myBase = 3400;int myVal = payload + myBase;
最小値がわかっていて、値の範囲が256以下である限り、わかるように、汗をかくことなくシングルバイトを使用することができます。, 厄介なバグを防ぐために、値が3655より大きくないことを確認してください。√
Round
範囲が256より大きい場合はどうなりますか? 次の質問は、正確な値を知る必要があるかどうかです。 センサーの範囲が400で誤差マージンが2の場合、値を丸めても意味を失うことはありません。 299と300の両方が150に丸められますが、これは問題ありません。
デバイス上では、これを次のようにエンコードします。
int myVal = 300;int errorMargin = 2byte payload = { round(myVal / errorMargin) };
アプリケーションのペイロード関数では、
var errorMargin = 2;decoded.myVal = bytes * errorMargin;
逆のアイデアを得ることができます。,
Use words
ワードは2バイト(Due、Zero、およびそれが4バイトである類似のボードを除く)であり、これはすでに65536(2562)の巨大な範囲を取得しています。 Intデータ型はワードであり、ArduinoにはhighByte()
とlowByte()
が付属しており、ワードから左右のバイトを抽出します。 これは本当に簡単にエンコードとデコード.
エンコード(Arduino):
int myVal = 20000;byte payload;payload = highByte(myVal);payload = lowByte(myVal);
デコード(ペイロード関数):
decoded.myVal = (bytes << 8) + bytes;
<<
が何であるか疑問に思っていますか?, これは、最初のバイトの8ビット8位置を左にシフトします。 混乱? 数字11を1つの位置にエンコードし、最初の1つを一方の位置にシフト(10にする)してから他方を追加する方法について考えてみましょう。 次にビットシフトについて詳しく説明します。
エンコード(ペイロード関数):
var myVal = 20000;var bytes = ;bytes = (myVal & 0xFF00) >> 8;bytes = (myVal & 0x00FF);
見たことがない
&
前にこのように使用されましたか? これはビット単位のANDです。, このようにして使用すると、式の右側は一方のバイトをゼロにするマスクとして機能するので、もう一方のバイトだけで作業できます。
Decode(Arduino):
int myVal = ((int)(payload) << 8) + payload;
シフトビット
期待値の範囲が65536より大きい場合、同じトリックを使用できます。 唯一の違いは、ペイロード関数で行ったように、Arduinoでエンコードするときに手動でビットをシフトする必要があることです。
4バイトを使用するlongを4294967296までの範囲でエンコードする必要があるとしましょう。,
エンコード(Arduino):
デコード(ペイロード関数):
decoded.myVal = ((long)(bytes) << 24) + ((long)(bytes) << 16) + ((long)(bytes) << 8) + ((long)(bytes));
負の数を送信するにはどうすればよいですか?
-100と100の違いを知るには、符号付きデータ型が必要です。 これらは、最大(左端)ビットを1
に設定して、負の数であることを示します。 これは、たとえば、ワードでは15ビットのうち16ビットのみが実際の数に利用可能であり、65536から32768までの範囲を制限することを意味します。,
Index、round、およびshift
これまでに使用したデータ型はすべて符号付きであるため、すべてのトリックが負の値に対しても同様に機能します。 最大値に注意してください。
符号なしデータ型
負の数を期待せず、より大きな範囲が必要な場合は、unsigned int
またはunsigned long
を明示的に使用します。
小数点以下を送信するには?
これまでのところ、丸められた数字のみを扱ってきました。 より多くの精密を必要とすれば何か。 その答えに近い物価連動や丸みの大きます。, エンコードしてデコードするときに値を単に倍数にして分割します。
エンコード(Arduino):
float myVal = 1.22;byte payload;payload = round(myVal * 100);
デコード(ペイロード関数):
decoded.myVal = bytes / 100;
エンコード(ペイロード関数):
bytes = Math.round(1.22 * 100);
デコード(Arduino):
float myVal = payload / 100.00;
複数の番号を送信するにはどうすればよいですか?
多くの場合、単一のメッセージで複数の値を送信したいと思うでしょう。 まず、個々の数値をバイトのバッファにエンコードし、それらを単一のバッファに結合します。,
エンコード(Arduino):
なぜ
memcpy()
受け入れるのか疑問に思うかもしれませんpayload + sizeOfPayloadA
それらは①と②に見えます。 これをpayload
バッファにコピーする命令と考えてくださいが、ポイントを移動した後、これまでに追加したペイロードの長さでコピーします。,
デコード(ペイロード関数)
decoded.myValA = bytes.slice(0, 2);decoded.myValB = bytes.slice(2, 5);// Decode both byte arrays as we did before
エンコード(ペイロード関数)
// Encode both values as we did beforevar bytes = bytesA.concat(bytesB);
デコード(Arduino):
var payloadA;var payloadB;memcpy(payloadA,
どのようにテキストを送信するのですか?
短い答えは:しないでください。Textは多くのバイトを使用します。 Unicodeは128000文字を超える文字を定義しているので、文字ごとに3バイトかかります! ユーザー入力を送信すること以外に、数字の代わりにテキストを使用する正当な理由はめったにありません。, ほとんどの場合、英数字のみで十分ですが、その場合は、文字ごとに単一バイトのみを使用するASCII文字を使用することで逃げることができます。 文字列が終了したことを示すには、すべての文字列をNULL(0x00,’\0′)文字で終了する必要があります。
あなたは私からそれを聞いていませんでしたが、文字列をエンコードする方法は次のとおりです。
あなたがデコードする方法は次のとおりです。
decoded.myVal = String.fromCharCode.apply(null, bytes);