Réseau LoRa Orange/Objenious/LiveObject/RN2483/envoyer et décoder les informations de capteurs

Bonjour, ceci est mon premier post sur ce forum, bien que j'ai beaucoup appris sans m'inscrire, après 3ans d'auto-formation je me lance dans un projet LoRa avec la carte RN2483 sur la plateforme LiveObject.

Il me semble avoir compris que c'est le type de carte et d'abonnement qui est plus tourné vers les sociétés plutôt que vers les particuliers, mais en insistant un peu et en inventant un projet grandiose, on peu quand même obtenir l'abonnement et la carte.
(Il suffit de leurs faire croire qu'on sera un client fidèle qui souhaite acheter des tonnes de capteurs connectés qu'ils vendent 3 fois plus chère que la normal).

Bref, je m'écarte du sujet, j'ai en ma possession cette carte RN2483 ainsi qu'un accès à LiveObject.
Documentation de la carte et libraire :
https://github.com/Orange-OpenSource/Orange-Eplorer-Kit-for-LoRa
(si ce lien ne marche pas, il suffit d'aller sur github et de taper explorer kit for LoRa mais normalement ca marche).

Mon projet :
Apprendre à envoyer les données de plusieurs capteurs, en un seul message, et de décoder ce message pour en faire des stats sur LiveObject.

Actuellement :
J'ai tester les différents exemples de codes, ils m'ont permis d'apprendre à envoyer :
chaîne hexadécimal style "uint8_t message = (0x3d, 0x65, 0xa5)"
Le problème de ce format est que je ne sais pas comment remplacer ces nombres par des noms de variables, exemple : "uint8_t message = (0x val_temperature_entier, 0x val_temperature_decimal, 0x val_humidite_entier, 0x val_humidite_decimal)"

Ca serai parfait pour moi, mais malheureusement je ne connais pas la syntaxe qui me permet de faire ça, je pense que c'est plus un problème de programmation global de ma part plutot que qlq chose relié à la librairie. en claire, mon but est de pouvoir integrer des Variables, alors que dans les exemples et tutoriels, à aucun moments ils n'indiquent comment le faire, ils ne parlent que d'envoyer soit des valeurs prédéfinis (style, ecrire Hello world en toute lettre, et envoyer le truc, ce qui ne sert vraiment à rien, vue qu'on veut faire de la com "objet à objet" et non pas "humain à objet à objet" donc j'ai vraiment besoin d'envoyer des variables et non pas des valeurs prédéfinis).

La deuxième chose que j'ai expérimenté est d'envoyer un buffer.

J'arrive à envoyer quelque chose du style :

bool SendLoRaMessage()
{ 
  uint8_t port = 5;
  uint8_t buf[] = { 't', 'e', 's', 't' };
  
  return OrangeForRN2483.sendMessage(buf, sizeof(buf), port); // send unconfirmed message
}

Ici on retrouve le port 5 de la carte RN2483, la taille du buffer, la commande sendMessage, tout marche bien, j'envoie "test" et sur LiveObject je reçoit "74657374" qui correspond à la valeur en hexadécimal. Donc, génial, mais en fait non, toujours pas, ici j'ai bien des charactères prédéfinit et non pas des Variables.

En plus de ça je ne maîtrise toujours pas les décodeurs de la plateforme LiveObject, donc impossible pour moi de transformer ce 74657374 en "test". (Mais c'est un autre problème).

Je ne suis pas très bon en programmation (je suis autodidacte et je n'ai pas suivis de formation en programmation). Donc je ne connais pas encore très bien les buffers, je ne connais pas la syntaxe pour transformer " 't' 'e' 's' 't'" en " 'val_temperature' 'val_humidite' " ?

Mon idéale serai d'avoir un type char, dans lequel je stock directement les caractères des valeurs.
Pour ce qui se rapporche le plus de la réalité pour l'instant c'est la méthode hexadécimal avec :

bool SendLoRaMessage()
{
  const uint8_t size = 5;
  uint8_t port = 5;
  uint8_t data[size] = { 0x48, 0x5, 0x6C, 0x6C, 0x6F }; // Hello

  return OrangeForRN2483.sendMessage(data, size, port); // send unconfirmed message
} 

mais je ne comprend pas comment remplacer ces valeurs avec des Variables, j'ai toujours des messages d'erreurs car je ne connais pas les bonnes syntaxes.

Le gros du problème est qu'il faut envoyer des chaînes de 8 caractères (même si ma valeur est 30°C, ce qui donne en gros 1E en héxa, et donc pas besoin de 8 caractères, mais il faut quand même les mettre, enfin je suppose, je n'en suis pas certain, mais il me semble que le décodeur n'accepte que les chaînes de 8 caractères).

J'en profite pour switcher sur le second problème, je n'ai pas encore réussis à utiliser les décodeurs (mais je n'ai fais qu'une journée de recherche donc c'est bien normal).

En gros pour résumer le problème,
je cherche un moyen de stocker dans un buffer uint8_t, les valeurs de mes capteurs, (Variables donc, j'arrive actuellement à convertir mes données en héxadécimal, et à couper en deux parties réel/décimal, donc je peux faire des pairs de 2 par 2 (pour 0x12, 0x34, 0xetc) toujours par 2. Mais je n'arrive pas à faire entrer de variables dans les buffers).

Il me semble que ce genre de projet n'est pas beaucoup présent sur cette plateforme (surtout en utilisant LiveObject). Donc je m'engage à partager mon avancement, je ne m'attend pas à beaucoup de réponses non plus, mais voila, je pose ça ici, si quelqu'un m'aime, qu'il me suive, si vous avez des questions pour répondre à mes questions, je serai heureux de répondre aux questions qui répondront à mes questions.
Je peux partager les petits bouts de programmes, même si ces exemples sont disponibles sur le lien que j'ai mis en haut.

Merci pour votre temps et votre intérêt.
0VI.

ça se fait en créant une structure et vous balancez les octets de la structure en passant l'adresse de la structure et sa taille.

si vous regardez mon tuto decouverte-du-mkrfox

vous verrez que j'envoie une seule donnée mais encapsulée dans une structure
avec LORA c'est pareil, ça pourrait ressembler à cela:

// on définit le type t_loraMsg qui est un groupe de données
struct __attribute__ ((packed)) t_loraMsg {
  uint8_t stationID;
  uint8_t  humidite_Pourcent;
  int16_t  temperature_C;
  uint16_t pression_hPa;
};

bool SendLoRaMessage() {
  const uint8_t port = 5;
  t_loraMsg message;
  
  // on remplit le message
  message.stationID = 42;           // bien sûr on pourrait mettre des variables ou appel de fonctoin à la place des nombres
  message.humidite_Pourcent = 74;
  message.temperature_C = 23;
  message.pression_hPa = 1018;

  // on émet le message
  return OrangeForRN2483.sendMessage((uint8_t*) &message, sizeof message, port); // send unconfirmed message
}

En plus de ça je ne maîtrise toujours pas les décodeurs de la plateforme LiveObject, donc impossible pour moi de transformer ce 74657374 en "test". (Mais c'est un autre problème).

c'est sans doute (je n'ai pas regardé) un peu comme pour sigfox, il faut définir ce que contient votre message, à quoi chaque octet correspond et comment on les lit.

par exemple dans la table ASCII


le code 74 en hexadécimal correspond à la lettre 't'
le code 65 en hexadécimal correspond à la lettre 'e'
le code 73 en hexadécimal correspond à la lettre 's'
➜ c'est donc bien le mot "test" qui est dans le message. Il faut juste spécifier que ces 4 octets sont à prendre sous forme de chaîne de caractères ASCII.

1 Like

Merci beaucoup ! je vais jeter un coup d'oeil à votre tutoriel, même si j'avoue avoir déjà trouvé les réponses de mon propre problème entre hier soir et ce matin.
Je met ici mon code à titre informatif :
J'arrive à envoyer les valeurs de plusieurs capteurs, j'attaque maintenant la géolocalisation (non pas par triangulation car trop imprécise, mais par carte GPS/GSM).

Je tiendrai actif ce post pour faire part de l'avancement, et surtout parce que je pense que ce ne sera pas ma seul question pour ce projet. (et si ça peu aider qlq plus tard, c'est que du benef).

Pour l'instant je n'arrive pas à récuperer les informations GPS, mais je viens tout juste de m'y mettre alors c'est bien normal. J'ai cette puce : " Module A6 GPRS, SMS, carte de développement, GSM, transmission de données sans fil via SIM900A" bleu avec une antenne en angle droit.

Le code que j'ai pour l'instant et qui fonctionne :

#include <OrangeForRN2483.h>
#include <DHT.h>
#include <stdio.h>

#define debugSerial SerialUSB

#define DHTPIN 9
#define photo_rez_pin A0
#define potar_pin A1

#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

// The following keys are for structure purpose only. You must define YOUR OWN. 
const uint8_t appEUI[8] = { ***adresse perso secrète*** };
const uint8_t appKey[16] = { ***adresse perso secrète***};

int compteur_laser = 0;
long compteur_tours = 0;

bool first = true;
  
bool joinNetwork()
{             
  OrangeForRN2483.setDataRate(DATA_RATE_1); // Set DataRate to SF11/125Khz
  return OrangeForRN2483.joinNetwork(appEUI, appKey);
}

void setup() {
  debugSerial.begin(57600); 
  dht.begin();
  
  while ((!debugSerial) && (millis() < 10000)) ;

  OrangeForRN2483.init();
}

void loop() {

  pinMode(photo_rez_pin, INPUT);

  int photorez = analogRead(photo_rez_pin);
  
  double temperature = dht.readTemperature();
  double humidite = dht.readHumidity();

  double potar = analogRead(potar_pin);

  uint8_t port = 5;
  
  
  
  //debugSerial.println(buf2[0]);
  
  if(photorez < 700){
  compteur_laser++;
  debugSerial.println("portail coupé");
  delay(100);
}
  
compteur_tours++; 

  if(compteur_tours == 20000)
  {  
    debugSerial.println("Demande d'envoie de message activé (toute les ?? secondes)");
    bool res = joinNetwork();
    
    if(res)
    {
      uint8_t buf2[4] = { potar, temperature, humidite, compteur_laser };

      
      debugSerial.println("Accès à la communication réussie");
      OrangeForRN2483.enableAdr();

      debugSerial.println("Les valeurs suivantes : ");
      
      for(int i = 0; i < 4; i++){
        debugSerial.println(buf2[i]); 
      }

      debugSerial.println("sont en train d'être envoyées...");
      
      OrangeForRN2483.sendMessage(buf2, sizeof(buf2), port);
      
      delay(20000);
      debugSerial.println("Transmission terminée");  

      compteur_laser = 0;
      compteur_tours = 0;
          
    }
    else debugSerial.println("Join Failed");
      compteur_laser = 0;
      compteur_tours = 0;  
      delay(20000);   
  }

C'est un mode d'envoie où la carte attend pendant un certain temps, pendant ce temps, elle compte le fois où la photorésistance est coupé (détecteur de passage), et une fois tout les xtemps, j'envoie, et le nombre de passage, la température humidité, la valeur d'un potentiomètre (malheresement stockable que sur 1 octet maxi, donc je ne sais pas encore comment envoyer une valeur au dessus de 255... mais ça va venir !).
je suis entrain d'ajouter la géoloc, après ça, je vais ajuster un timer pour envoyer toutes les 5-6 minutes, 1 message, avec les valeurs moyennes/max/min, de chaque type de capteur.

Dans cet exemple, j'envois un message toute les qlq secondes, je recois le message suivant "
15:04:21.270 -> mac join otaa
15:04:21.270 -> Rn2483 Buffer: ok
15:04:21.315 -> Rn2483 Buffer: no_free_ch
15:04:21.315 -> Response : no_free_ch received during execution !

qui veut sans doute dire que j'occupe trop l'espace de la bande passante ?? je ne sais pas vraiment, mais je remarque simplement que une fois toute les 5-6 minutes, le message réussit à partir :

14:58:54.445 -> Sending message...
14:58:54.445 -> mac tx uncnf
14:58:54.491 -> Rn2483 Buffer: ok
14:59:21.525 -> Transmission terminée

donc voila, des fois ça envois, des fois non, le premier/deuxième messages s'envoient quasiment tt le temps, c'est quand je laisse la carte tourner en arrière plan que je reçois beaucoup de refus, et qu'une fois toute les 6 minutes, le message passe.

Pour ce qui est du côté du décodeur sur LiveObject j'ai mis les paramètres suivants :
Nom "Décodeur complet"
Model " "
Type "Paramétré Binaire"

Description du contenu binaire :

bit:8 tension;
byte temperature;
byte humidite;
bit:8 portail;

Template :

"payload" : "{{tension}}"
"payload" : "{{temperature}}"
"payload" : "{{humidite}}"
"payload" : {{portail}}

Tester le décodeur, valeur à décoder en héxa :
D41E1D14

résultat :

{
  "parsingOk": true,
  "decodingResult": {
    "tension": 212,
    "temperature": 30,
    "humidite": 29,
    "portail": 20
  },
  "descriptionValid": true,
  "templatingOK": false
}

voilà après il suffit de mettre dans le tableau de bord une nouvelle dashboard, avec nouveau widget, au moment de choisir "Données à afficher" il faut aller choisir dans "@lora_v0{1}" si comme moi vous n'avez rien paramétré de particulier pour ça (c'est là où se rangent les données par défauts).

Voila voila, je reviens sur ce post au moment où j'aurai une question sur l'utilisation du GPS/GPRS A6, ou au moment où j'aurai finis.

Après cette étape j'aurai aussi des questions pour récupérer les données de LiveObject et les transférer sur ma propre appli, mais je n'y suis pas encore, il me reste le GPS, les stats, le bluetooth, et les SMS. =)

A+

OK - Merci de lire et appliquer "Les bonnes pratiques du Forum Francophone” pour votre post et le modifier pour rajouter les balises de code SVP

merci

1 Like

Ah, très bien merci pour l'info, c'est noté !

merci !