Pour envoyer des données sur ce Réseau, vous aurez besoin d’utiliser des octets. Ce guide vous aidera à encoder différents types de données dans le moins d’octets possible.
La gamme sans précédent de la technologie LoRaWAN sur laquelle nous nous appuyons se fait au prix d’une faible bande passante et d’un temps d’antenne limité (le nombre de fois la taille des paquets que vous envoyez). Heureusement, vous n’avez pas besoin d’une photo de cette poubelle de garage intelligente qui doit être vidée. Même un seul bit
1
ferait l’affaire!,
qu’est Ce qu’un octet?
Un octet est un groupe de 8 bits. Un bit est l’unité la plus basique et peut être 1 ou 0. Un octet n’est pas seulement 8 valeurs entre 0 et 1, mais 256 (28) combinaisons différentes (plutôt des permutations) allant de 00000000
via par exemple 01010101
à 11111111
. Ainsi, un octet peut représenter un nombre décimal compris entre 0(00) et 255.
Perplexe? Rappelez-vous que 3 Nombres Décimaux ne représentent pas seulement 3 valeurs entre 0 et 9, mais 1000 (103) permutations de 0(00) à 999.,
En savoir plus sur le fonctionnement des choses: comment fonctionnent les Bits et les octets et le tutoriel Arduino Bit Math pour en savoir plus à ce sujet.
qu’est Ce qu’un tampon d’octets?
pensez à buffer comme un autre mot pour un tableau, une liste, Tout ce qui résonne avec votre expérience de programmation. Comme un octet est un groupe de 8 bits, une mémoire tampon est un groupe d’une pré-définis nombre d’octets. Si nous avons un groupe de 3 octets, cela pourrait représenter 3 valeurs entre 0 et 255, mais également une seule valeur entre 0 et 16777216 (2563).
Voir le modèle?, Le nombre de choix par position (n) à la puissance du nombre de positions (r) est le nombre de permutations: nr. en savoir plus sur MathIsFun.com.
Qu’est-ce que l’hexadécimal?
Souvent, vous verrez un groupe d’octets affiche:
FF F0 0F 11
N’était pas un octet, un groupe de 8 0
s et 1
s?, You Vous avez tout à fait raison, mais comme nous l’avons déjà vu 11111111
se traduit par 255 dans le bon vieux système décimal, nous pouvons également le traduire en FF dans le système hexadécimal où chaque position a 16 (0-9 A-F) valeurs possibles. L’avantage est qu’il est plus court et explicite sur la valeur maximale (257 n’est pas une option).,
L’exemple ci-dessus traduit le système décimal et rembourré pour plus de lisibilité serait:
255 240 015 017
Pour indiquer que tu veux dire 11
hex et non pas deux bits ou le nombre onze, vous préfixe avec la balise 0x
formateur. Pour le dire, vous voulez dire binaire, utilisez B
.,h>Code
11
0x11
B11
An example for Arduino:
Yeah, I know… 0x
kind of blows the shorter-to-write advantage of hex., 🙃
Combien d’octets puis-je envoyer?
Techniquement, vous pouvez envoyer 51 octets. Mais, plus vous enverrez d’octets, plus le forfait vous coûtera de temps d’antenne et plus tôt vous atteindrez votre temps maximum alloué. Alors, ne vous demandez pas combien vous pouvez éventuellement en envoyer, mais demandez plutôt combien peu pourraient faire le travail.
comment envoyer de grands nombres?
Une meilleure question serait de savoir comment envoyer des plages supérieures à 255.
Index
Si les valeurs possibles que vous devez prendre en charge ne commencent pas à 0 et que vous connaissez la valeur minimale, commencez par indexer ce nombre.,
par exemple, imaginez que nous nous attendions à des valeurs comprises entre 3400 et 3600.,
Sur l’appareil que nous serions coder ceci:
int myVal = 3450;const int myBase = 3400;byte payload = { myVal - myBase };
Et dans l’application de la charge utile des fonctions de faire:
var myBase = 3400;decoded.myVal = bytes + myBase;
dans L’autre sens, dans l’application de l’encodeur de la charge utile de la fonction, nous aurions:
var myVal = 3450;var myBase = 3400;var bytes = ;
Et sur le dispositif de décodage de ces avec:
int myBase = 3400;int myVal = payload + myBase;
Comme vous pouvez le voir, tant que la valeur minimale est connu et la diversité de notre valeur est de 256 ou moins, on peut encore utiliser un seul octet sans casser une sueur., Assurez-vous de vérifier que votre valeur n’est pas supérieure à 3655 pour éviter les bugs désagréables.😅
Round
maintenant, que faire si la plage est supérieure à 256? La prochaine question serait si vous avez besoin de connaître la valeur exacte. Si votre capteur a une plage de 400 et une marge d’erreur de 2, vous ne perdrez aucune signification en arrondissant la valeur. 299 et 300 arrondiraient à 150, ce qui est bien.
Sur l’appareil que nous serions coder ceci:
int myVal = 300;int errorMargin = 2byte payload = { round(myVal / errorMargin) };
Et dans l’application de la charge utile des fonctions de faire:
var errorMargin = 2;decoded.myVal = bytes * errorMargin;
Vous aurez l’idée de l’autre manière autour.,
utilisez des mots
Un mot est de 2 octets (sauf sur les cartes Due, Zero et similaires où il est de 4 octets), ce qui vous donne déjà une énorme plage de 65536 (2562). Le type de données int est un mot et Arduino est livré avec highByte()
Et lowByte()
pour extraire l’octet gauche et droit d’un mot. Cela le rend vraiment facile à encoder et à décoder.
Encode (Arduino):
int myVal = 20000;byte payload;payload = highByte(myVal);payload = lowByte(myVal);
Décoder (charge utile de fonctions):
decoded.myVal = (bytes << 8) + bytes;
vous vous Demandez ce que le
<<
est d’environ?, Cette Gauche décale les 8 bits du premier octet 8 positions vers la gauche. Confus? Pensez à la façon dont nous pourrions encoder le nombre 11 comme deux 1 et décoder en déplaçant le premier 1 vers le haut d’une position (ce qui en fait 10) avant d’ajouter l’autre. Nous parlerons plus sur bit shifting ensuite.
Encode (charge utile de fonctions):
var myVal = 20000;var bytes = ;bytes = (myVal & 0xFF00) >> 8;bytes = (myVal & 0x00FF);
Jamais vu
&
utilisés de cette manière avant? C’est un bit à Bit ET., Utilisé de cette façon, le côté droit de l’expression agir comme un masque à zéro sur un octet, donc nous pouvons travailler avec l’autre.
Decode (Arduino):
int myVal = ((int)(payload) << 8) + payload;
Décalage de bits
Si la plage de valeurs est plus grand que 65536 nous pouvons utiliser la même astuce. La seule différence est que nous devons décaler manuellement les bits lorsque nous encodons sur Arduino, tout comme nous l’avons fait dans la fonction de charge utile.
disons que nous devons encoder un long qui utilise 4 octets pour une plage allant jusqu’à 4294967296.,
Encode (Arduino):
Décoder (charge utile de fonctions):
decoded.myVal = ((long)(bytes) << 24) + ((long)(bytes) << 16) + ((long)(bytes) << 8) + ((long)(bytes));
Comment envoyer des nombres négatifs?
Pour faire la différence entre -100 et 100, vous aurez besoin d’un type de données signées. Ceux-ci définissent le bit le plus élevé (le plus à gauche) sur 1
pour indiquer qu’il s’agit d’un nombre négatif. Cela signifie que par exemple dans un mot seulement 15 des 16 bits sont disponibles pour le nombre réel, limitant la plage de 65536 à 32768.,
Index, round et shift
les types de données que nous avons utilisés jusqu’à présent sont tous signés, ce qui signifie que toutes les astuces fonctionnent aussi bien pour les valeurs négatives. Soyez juste conscient de la valeur maximale.
types de données non signés
Si vous ne vous attendez pas à des nombres négatifs et avez besoin d’une plage plus grande, utilisez explicitementunsigned int
ouunsigned long
.
Comment envoyer des décimales?
Jusqu’à présent, nous n’avons traité que des nombres arrondis. Et si vous avez besoin de plus de précision? La réponse est très similaire à la façon dont nous avons indexé ou arrondi les grands nombres., Simplement plusieurs et de diviser la valeur de l’encodage et de décodage.
Encode (Arduino):
float myVal = 1.22;byte payload;payload = round(myVal * 100);
Décoder (charge utile de fonctions):
decoded.myVal = bytes / 100;
Encode (charge utile de fonctions):
bytes = Math.round(1.22 * 100);
Decode (Arduino):
float myVal = payload / 100.00;
Comment envoyer plusieurs numéros?
dans de nombreux cas, vous voudrez envoyer plusieurs valeurs dans un seul message. Commencez par ENCODER chaque numéro individuel dans un tampon d’octets, puis combinez-les en un seul tampon.,
Encode (Arduino):
vous pourriez Vous demander pourquoi
memcpy()
acceptepayload + sizeOfPayloadA
comme ils semblent l’ 🍏 et 🍊. Considérez-le comme une instruction à copier dans le tamponpayload
, mais après avoir déplacé le point où il sera copié, avec la longueur des charges utiles que nous avons ajoutées jusqu’à présent.,
Decode (charge utile fonctions)
decoded.myValA = bytes.slice(0, 2);decoded.myValB = bytes.slice(2, 5);// Decode both byte arrays as we did before
Encode (la charge utile de la fonction)
// Encode both values as we did beforevar bytes = bytesA.concat(bytesB);
Decode (Arduino):
var payloadA;var payloadB;memcpy(payloadA,
Comment envoyer des sms?
la réponse courte est: don’T. Text utilise beaucoup d’octets. Unicode définit plus de 128000 caractères, ce qui prendrait 3 octets par caractère! Il y a rarement de bonnes raisons d’utiliser du texte au lieu de chiffres, à part peut-être transmettre une entrée utilisateur., La plupart du temps, seuls les caractères alphanumériques suffisent, dans ce cas, vous pouvez vous en sortir en utilisant des caractères ASCII qui n’utilisent qu’un seul octet par caractère. Chaque chaîne doit être terminée par un caractère NULL (0x00, ‘\0’) pour indiquer que la chaîne est terminée.
Vous ne l’avez pas entendu de moi, Mais voici comment encoder une chaîne:
que vous décoderiez avec:
decoded.myVal = String.fromCharCode.apply(null, bytes);