Problème envoie/Réception/Décodage Arduino MKR 1300 et réseau TTN

Bonjour à tous,

Je viens de recevoir un arduino MKR 1300. J’ai essayé de connecter dessus un petit capteur d’humidité de sol en grove et j’envoie bien des données sur le réseau TTN (thethingsnetwork).

Je mets ma valeur, retourné par le port Analogique dans une variable uint16_t et j’envoie sur le réseau.

Je reçois bien 2 bits sur l’interface TTN mais je n’arrive pas à trouver la bonne fonction de décodage, pour récupérer ma valeur.

J’ai testé avec l’envoie de la valeur : 736
Je reçois coté TTN en hexa : E0 02

et j’ai essayé de décoder en mettant cette fonction :

function Decoder(bytes, port) {
var decoded = {};
var HumiSolValue1tmp = 0;
//HumiSolValue1tmp = ((bytes[0]<<8)>>>0) + bytes[1];
HumiSolValue1tmp = (bytes[0]<<1) + bytes[1];
decoded.moisture = HumiSolValue1tmp;
return decoded;
}

mais il me renvoie : 450

Je pense que ce n’est qu’un problème de décalage de bits ?

Merci par avance de votre aide

Voici mon code sur l’arduino :

#include <MKRWAN.h>

LoRaModem modem;

// Please enter your sensitive data in the arduino_secrets.h tab

String appEui = "xxxxxx";
String appKey = "xxxxxxx";

#define DEBUG         true             // Set DEBUG to false to disable serial prints
#define SLEEPTIME     15 * 60 * 1000   // Set the delay to 15 minutes (15 min x 60 seconds x 1000 milliseconds)

int HumiSolPin1 = A0;
int HumiSolValue1 = 0;
int HumiSolValue1_percentage = 0;

int HumiSolPin2 = A1;
int HumiSolValue2 = 0;
int HumiSolValue2_percentage = 0;

uint16_t msg;

void setup() {

// put your setup code here, to run once:

Serial.begin(115200);
while (!Serial);

// change this to your regional band (eg. US915, AS923, ...)

if (!modem.begin(EU868)) {
Serial.println("Failed to start module");
while (1) {}

};

Serial.print("Your module version is: ");
Serial.println(modem.version());
Serial.print("Your device EUI is: ");
Serial.println(modem.deviceEUI());
int connected = modem.joinOTAA(appEui, appKey);

if (!connected) {

Serial.println("Something went wrong; are you indoors? Move near a window and retry");

while (1) {}

}

// Set poll interval to 60 secs.

modem.minPollInterval(60);

// NOTE: independently of this setting the modem will
// not send more than one message every 2 minutes,
// this is enforced by firmware and can not be changed.

}

void loop() {

if(DEBUG) {
  Serial.println("Get Humidite sol ...");}
  for (int i = 0; i <= 100; i++) 
    { 
      HumiSolValue1 = HumiSolValue1 + analogRead(HumiSolPin1); 
      delay(1); 
    } 

    HumiSolValue1 = HumiSolValue1/100;
    //HumiSolValue1 = 255;
    //HumiSolValue1_percentage = ( 100 - ( (HumiSolValue1/1023.00) * 100 ) );
    HumiSolValue1_percentage = ( (HumiSolValue1/1023.00) * 100 );

  for (int i = 0; i <= 100; i++) 
    { 
      HumiSolValue2 = HumiSolValue2 + analogRead(HumiSolPin2); 
      delay(1); 
    }
    
    HumiSolValue2 = HumiSolValue2/100;
    HumiSolValue2_percentage = ( (HumiSolValue2/1023.00) * 100 );


  // Mise en forme du message
 // stringSeparator = " ";
  msg= HumiSolValue1;

  // Envoi du message vers le port série
/*  Serial.println();
  Serial.print("Envoi: " + msg + " - ");
  // Conversion hexadecimale
  for (unsigned int i = 0; i < msg.length(); i++) {
    Serial.print(msg[i] >> 4, HEX);
    Serial.print(msg[i] & 0xF, HEX);
    Serial.print(" ");
  }
  Serial.println();*/

          if(DEBUG) {
                Serial.print("Humidite Sol 1 = " );
                Serial.println(HumiSolValue1_percentage);
                Serial.println(HumiSolValue1);
                Serial.print("Humidite Sol 2 = " );
                Serial.println(HumiSolValue2_percentage);
                Serial.println();
        }

  delay(1000);
  
  modem.beginPacket();
  modem.write(msg);
  int err = modem.endPacket(false);
  if (err > 0) {
  Serial.println("Data Sent");
  } else {
  Serial.println("Error");
  }
  
  delay(SLEEPTIME);
}

Bonjour

j’écris comme ça mon décodeur (dans la console TTN) pour réarranger les deux octets reçus :

function Decoder(bytes, port) {
  var tension = (bytes[0] << 8) | bytes[1];
  
  return {
    field1: tension / 1000
  }
}

je n’ai pas testé cette écriture qui convient aussi probablement
(bytes[0]*256+bytes[1])

al1fch:
var tension = (bytes[0] << 8 ) | bytes[1];
je n’ai pas testé cette écriture qui convient aussi probablement

(bytes[0]*256+bytes[1])

vous n’êtes pas garanti que ça va finir dans 2 octets mais oui ça fera l’adaptation little endian <-> big endian

al1fch:
Bonjour

j’écris comme ça mon décodeur (dans la console TTN) pour réarranger les deux octets reçus :

function Decoder(bytes, port) {

var tension = (bytes[0] << 8) | bytes[1];
 
  return {
    field1: tension / 1000
  }
}




je n'ai pas testé cette écriture qui convient aussi probablement
(bytes[0]*256+bytes[1])

Merci pour ton retour.

Comment fais tu, coté Arduino, pour compiler 2 Valeurs (uint8_t) dans une variable (uint16_t) et pouvoir l’envoyer ?

en gros je voudrais envoyer sous forme de bits, 2 valeurs des ports Analogiques codées sur 1024, positionnées dans des variables uint8_t.

Merci pour votre aide.

un uint16_t c’est deux octets
un uint8_t c’est un octet, donc 8 bits.

si vous voulez mettre un octet sur l’octet de poids faible il suffit d’écrire dans le uint16_t (avec un OU binaire si vous ne voulez pas toucher ce qu’il y a dans les poids forts).

si vous voulez mettre un octet dans l’octet de poids fort alors il faut le transformer en 2 octets, décaler de 8 bits pour que l’octet de poids faible passe côté poids fort.

bref ça donne cela:

void setup() {
  Serial.begin(115200);
  uint8_t poidsFaible = 0x0D;
  uint8_t poidsFort = 0xF0;
  uint16_t resultat = (poidsFort << 8) | poidsFaible; // | est le OU binaire
  Serial.println(resultat, HEX);
}

void loop() {}

J-M-L:
un uint16_t c’est deux octets
un uint8_t c’est un octet, donc 8 bits.

si vous voulez mettre un octet sur l’octet de poids faible il suffit d’écrire dans le uint16_t (avec un OU binaire si vous ne voulez pas toucher ce qu’il y a dans les poids forts).

si vous voulez mettre un octet dans l’octet de poids fort alors il faut le transformer en 2 octets, décaler de 8 bits pour que l’octet de poids faible passe côté poids fort.

bref ça donne cela:

void setup() {

Serial.begin(115200);
  uint8_t poidsFaible = 0x0D;
  uint8_t poidsFort = 0xF0;
  uint16_t resultat = (poidsFort << 8) | poidsFaible; // | est le OU binaire
  Serial.println(resultat, HEX);
}

void loop() {}

Merci :slight_smile: Je vais me tester ça