használatával az adatok oda-vissza küldéséhez a dolgok hálózaton keresztül bájtokat kell használnia. Ez az útmutató segít a különböző típusú adatok kódolásában a lehető legkisebb bájtban.
a LoRaWAN technológia példátlan tartománya, amelyre építünk, alacsony sávszélesség és korlátozott műsoridő (az elküldött csomagok száma) költségével jár. Szerencsére, nem kell egy képet, hogy az intelligens garázs bin, hogy ki kell üríteni. Még egy bit
1
is megteszi!,
mi az a bájt?
a byte egy 8 bites csoport. Egy kicsit a legalapvetőbb egység lehet 1 vagy 0. A bájt nem csupán 8 érték 0 és 1 között, hanem 256 (28) különböző kombináció (inkább permutáció), amely 00000000
via pl. 01010101
11111111
. Így egy bájt egy tizedes számot jelenthet 0(00) és 255 között.
Ne feledje, hogy a 3 decimális szám nem csak 3 értéket jelent 0 és 9 között, hanem 1000 (103) permutációt 0(00) és 999 között.,
Tudjon meg többet a dolgok működéséről: hogyan működnek a bitek és bájtok, valamint az Arduino Bit Math Tutorial, hogy többet tudjon meg róla.
mi a bájtok puffere?
Gondolj puffer, mint csak egy másik szót egy tömb, lista, bármi rezonál a programozási tapasztalat. Mint egy bájt egy 8 bites csoport, a puffer egy előre meghatározott bájtszám csoportja. Ha van egy 3 bájtos csoportunk, akkor ez 3 értéket jelenthet 0 és 255 között, de egy értéket is 0 és 16777216 között (2563).
lásd a mintát?, Pozíciónként (n) a pozíciók számának erejéig (r) a permutációk száma: nr. Tudjon meg többet MathIsFun.com.
mi a hex?
gyakran megjelenik egy bájtcsoport, amely a következőképpen jelenik meg:
FF F0 0F 11
nem volt bájt a 8 0
s és 1
s?, 🤔 Teljesen igazad van, de ahogy már láttuk 11111111
fordítja 255 a jó öreg decimális rendszer, azt is lefordítani, hogy FF a hexadecimális rendszer, ahol minden helyzetben van 16 (0-9 A-F) lehetséges értékeket. Ennek az az előnye, hogy rövidebb és explicit a maximális érték (257 nem opció).,
a fenti, decimális rendszerre lefordított és olvashatóság céljából kitöltött példa a következő lenne:
255 240 015 017
annak jelzésére, hogy a 11
hex-ben, nem pedig két bitben vagy a tizenegyes számban, akkor a 0x
formázó. Hogy elmondjam, azt jelenti, bináris használata B
.,h>Code
11
0x11
B11
An example for Arduino:
Yeah, I know… 0x
kind of blows the shorter-to-write advantage of hex., 🙃
hány bájtot tudok küldeni?
technikailag 51 bájtot küldhet. De minél több bájtot küldesz, annál több időt vesz igénybe a csomag, annál hamarabb eléri a maximális várakozási időt. Tehát ne kérdezd meg magadtól, hogy hány küldhet, hanem kérdezd meg, hogy kevesen tudják elvégezni a munkát.
hogyan lehet nagy számokat küldeni?
jobb kérdés az lenne, hogyan lehet 255-nél nagyobb tartományokat küldeni.
Index
Ha a támogatandó lehetséges értékek nem 0-kor kezdődnek, és ismeri a minimális értéket, kezdje az adott szám indexelésével.,
például képzeljük el, hogy 3400 és 3600 közötti értékeket várnánk.,
a készülék szeretnénk kódolni, mint:
int myVal = 3450;const int myBase = 3400;byte payload = { myVal - myBase };
a kérelem hasznos funkciók:
var myBase = 3400;decoded.myVal = bytes + myBase;
fordítva, az alkalmazás kódoló hasznos funkció mi lett volna:
var myVal = 3450;var myBase = 3400;var bytes = ;
a készülék dekódolni ezt:
int myBase = 3400;int myVal = payload + myBase;
Mint látható, amíg a legkisebb értéke ismert, valamint a tartomány az érték 256 vagy kevesebb, használhatjuk egyetlen byte anélkül, hogy egy verejtékcsepp., Ügyeljen arra, hogy ellenőrizze az érték nem nagyobb, mint 3655, hogy megakadályozzák a csúnya hibákat.😅
kerek
most mi van, ha a tartomány nagyobb, mint 256? A következő kérdés az lenne, ha tudnia kell a pontos értéket. Ha az érzékelőd 400-as és 2-es hibahatárral rendelkezik,akkor az érték kerekítésével nem veszítenél el semmit. Mind a 299, mind a 300 150-re fordulna, ami rendben van.
az eszközön ezt a következőképpen kódolnánk:
int myVal = 300;int errorMargin = 2byte payload = { round(myVal / errorMargin) };
és az alkalmazásban a hasznos terhelési funkciók:
var errorMargin = 2;decoded.myVal = bytes * errorMargin;
a másik irányba kapja az ötletet.,
Use words
a word is 2 byte (kivéve a Due, Zero és hasonló táblák, ahol ez 4 bájt), amely már kap egy hatalmas tartományban 65536 (2562). Az int adattípus egy szó, az Arduino pedig highByte()
és lowByte()
a bal és a jobb bájt egy szóból való kivonásához. Ez teszi igazán könnyű kódolni, dekódolni.
kódolás (Arduino):
int myVal = 20000;byte payload;payload = highByte(myVal);payload = lowByte(myVal);
dekódolás (hasznos funkciók):
decoded.myVal = (bytes << 8) + bytes;
a
<<
körülbelül?, Ez a bal eltolja a 8 Bit az első byte 8 pozíciók balra. Zavarodott? Gondolj bele, hogyan tudnánk kódolni a 11-es számot, mint két 1-es dekódolni eltolásával az első 1 egy pozícióba (így 10), mielőtt a másik. Többet fogunk beszélni a következő bitváltásról.
kódolás (hasznos funkciók):
var myVal = 20000;var bytes = ;bytes = (myVal & 0xFF00) >> 8;bytes = (myVal & 0x00FF);
soha nem látott
&
jóval korábban? Ez egy kicsit bölcs., Ilyen módon a kifejezés jobb oldala maszkként fog működni, hogy egy bájtot nullázzunk ki, így csak a másikkal dolgozhatunk.
dekódolás (Arduino):
int myVal = ((int)(payload) << 8) + payload;
Shift bit
Ha a várható értékek tartománya nagyobb, mint 65536, ugyanazt a trükköt használhatjuk. Az egyetlen különbség az, hogy manuálisan kell eltolnunk a biteket, amikor az Arduino-ra kódolunk, csakúgy, mint a hasznos teher funkcióban.
tegyük fel, hogy egy hosszú kódot kell kódolnunk, amely 4 bájtot használ a 4294967296 tartományig.,
kódolás (Arduino):
dekódolás (hasznos funkciók):
decoded.myVal = ((long)(bytes) << 24) + ((long)(bytes) << 16) + ((long)(bytes) << 8) + ((long)(bytes));
negatív számok küldése?
a -100 és 100 közötti különbség megállapításához aláírt adattípusra lesz szüksége. Ezek a legmagasabb (bal-legtöbb) bitet 1
értékre állítják, hogy ez egy negatív szám legyen. Ez azt jelenti, hogy például egy szóban a 16 bitből csak 15 áll rendelkezésre a tényleges számhoz, korlátozva a 65536-tól 32768-ig terjedő tartományt.,
Index, round and shift
az eddig használt adattípusok mind aláírásra kerültek, ami azt jelenti, hogy minden trükk ugyanúgy működik a negatív értékeknél. Csak vegye figyelembe a maximális értéket.
aláíratlan adattípusok
ha nem számít negatív számokra, és nagyobb tartományra van szüksége, akkor kifejezetten használja a unsigned int
vagy unsigned long
.
hogyan küldjünk tizedeseket?
eddig csak lekerekített számokkal foglalkoztunk. Mi van, ha nagyobb pontosságra van szüksége? A válasz nagyon hasonló ahhoz, ahogyan indexeltük vagy kerekítettük a nagy számokat., Egyszerűen Több, majd oszd meg az értéket, ahogy kódolni, dekódolni.
Kódolás (Arduino):
float myVal = 1.22;byte payload;payload = round(myVal * 100);
Dekódolni (hasznos funkciók):
decoded.myVal = bytes / 100;
Kódolás (hasznos funkciók):
bytes = Math.round(1.22 * 100);
Dekódolni (Arduino):
float myVal = payload / 100.00;
Hogyan kell küldeni több számok?
sok esetben több értéket szeretne küldeni egyetlen üzenetben. Kezdje azzal, hogy minden egyes számot kódol egy bájt pufferébe, majd egyesítse őket egyetlen pufferbe.,
kódolás (Arduino):
lehet, hogy vajon miért
memcpy()
elfogadjapayload + sizeOfPayloadA
mivel úgy tűnik 🍏 és 🍊. Gondolj rá, mint egy utasítást, hogy másolja apayload
puffer, de a pont áthelyezése után átmásolja, az eddig hozzáadott hasznos terhelések hosszával.,
Decode (payload functions)
decoded.myValA = bytes.slice(0, 2);decoded.myValB = bytes.slice(2, 5);// Decode both byte arrays as we did before
Encode (payload function)
// Encode both values as we did beforevar bytes = bytesA.concat(bytesB);
Decode (Arduino):
var payloadA;var payloadB;memcpy(payloadA,
hogyan küldjünk szöveget?
a rövid válasz: ne. a szöveg sok bájtot használ. A Unicode több mint 128000 karaktert határoz meg, így karakterenként 3 bájtot vesz igénybe! Ritkán van jó ok arra, hogy számok helyett szöveget használjunk, kivéve néhány felhasználói bemenet továbbítását., Legtöbbször csak az alfanumerikus karakterek elegendőek, ebben az esetben az ASCII karakterek használatával el lehet jutni, amelyek csak egy bájtot használnak karakterenként. Minden karakterláncot meg kell szüntetni egy NULL (0x00, ‘\0’) karakterrel, hogy jelezze, hogy a karakterlánc véget ért.
nem tőlem hallottad, de itt van, hogyan kódolnál egy karakterláncot:
, amellyel dekódolnád:
decoded.myVal = String.fromCharCode.apply(null, bytes);