Envoi d'une trame Json

Bonjour à tous, je viens vers vous car cela fait deux jours que je me casse la tête sur l'envoi d'une trame Json. :woozy_face:

Je suis sur un ESP32 qui reçoit des données en Lora. Jusqu'à là tout va bien je "print" bien toutes mes données sur le sérial.

Je voudrais exploiter ces données avec Node red. Pour cela il faut que je les traduisent en Json. Et la, catastrophe ! Je n'y arrive pas !

Pourriez-vous me donner un coup de pouce s'il vous plaît ?

Voici mon code:

#include <ArduinoJson.h>
#include <SPI.h>
#include <LoRa.h>
#include <Wire.h>  
#include "SSD1306.h" 
#include "images.h"

#define SCK     5    // GPIO5  -- SX1278's SCK
#define MISO    19   // GPIO19 -- SX1278's MISO
#define MOSI    27   // GPIO27 -- SX1278's MOSI
#define SS      18   // GPIO18 -- SX1278's CS
#define RST     14   // GPIO14 -- SX1278's RESET
#define DI0     26   // GPIO26 -- SX1278's IRQ(Interrupt Request)
#define BAND    8695E5

SSD1306 display(0x3c, 21, 22);
unsigned int compteur = 0;
String rssi = "RSSI --";
String packSize = "--";
String packet ;
String poids = "";
String tempINT = "";
String tempEXT = "";;
String humEXT = "";;
float data1R[7];
int NumRuche; // Donnée de discrimination pour reconnaître les différentes ruches
String Data1 = "";
String Volts = "";



void setup() {
  pinMode(16,OUTPUT);
  digitalWrite(16, LOW);    // set GPIO16 low to reset OLED
  delay(50); 
  digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high、
  compteur = 0 ;
  Serial.begin(9600);
  while (!Serial);
  Serial.println();
  Serial.println("LoRa Receiver Callback");
  LoRa.setSpreadingFactor(10);
  SPI.begin(SCK,MISO,MOSI,SS);
  LoRa.setPins(SS,RST,DI0);  
  if (!LoRa.begin(BAND)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  
  LoRa.setSpreadingFactor(10); // Facteur d'étalement 7 est la valeur par défaut. Permet de discriminer deux émissions
  LoRa.receive();
  Serial.println("init ok");
  display.init();
  display.flipScreenVertically();  
  display.setFont(ArialMT_Plain_10);
 
  delay(1500);
}

void loop() {
 
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    received a packet
    
    
     read packet
      while (LoRa.available()) {
      Serial.println("Paquets recus ");
      
      compteur++ ;
      Serial.println(compteur);
     
      LoRa.readBytes((uint8_t *)&data1R, packetSize);
      Data1 += data1R[0]; //Lit les données l'une après l'autre (+=)
      Data1 = Data1.toFloat();
      NumRuche = data1R[0];
      tempINT = data1R[1];
      tempEXT = data1R[2];
      humEXT = data1R[3];
      poids = data1R[5];
      Volts = data1R[6];
 /*     Serial.print("Tension :");
      Serial.println (Volts);
      Serial.print("Numero de ruche :");
      Serial.println (NumRuche);
      Serial.print("Température INT :");
      Serial.println (tempINT);
      Serial.print("Température EXT :");
      Serial.println (tempEXT);
      Serial.print("Humidite EXT :");
      Serial.println (humEXT);
      Serial.print("Poids :");
      Serial.println (poids);*/

      //json  

  

     //Gestion de l'écran
  display.clear();    
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_10);
  
  display.drawString(0, 0, "Numero de ruche :");
  display.drawString(90, 0, String(NumRuche));
  display.drawString(0, 15, "Temp INT: ");
  display.drawString(90, 15, String(tempINT));
  display.drawString(0, 30, "Temp EXT: ");
  display.drawString(90, 30, String(tempEXT));
  display.drawString(0, 45, "Humidite EXT: ");
  display.drawString(90, 45, String(humEXT));
  display.drawString(0, 60, "Poids: ");
  display.drawString(90, 60, String(poids));
  display.display();
    } 
  
  }
  
  
}

la bibliothèque ArduinoJson fait cela pour vous assez simplement

par exemple

#include <ArduinoJson.h>

String s1 = "Salut";
String s2 = "Bonjour";
int v = 123;
bool b = true;

DynamicJsonDocument doc(250); // sur le heap.

void setup() {
  Serial.begin(115200);

  // on construit le JSON
  doc["s1"] = s1;
  doc["s2"] = s2;
  doc["v"] = v;
  doc["b"] = b;

  // on l'imprime
  serializeJsonPretty(doc, Serial);
}

void loop() {}

va vous imprimer sur le port série

 {
  "s1": "Salut",
  "s2": "Bonjour",
  "v": 123,
  "b": true
}

si des données doivent être dans un tableau c'est pas très compliqué non plus

#include <ArduinoJson.h>

String s1 = "Salut";
String s2 = "Bonjour";
int v = 123;
bool b = true;

DynamicJsonDocument doc(500); // sur le heap.

void setup() {
  Serial.begin(115200);

  // on construit le JSON
  doc["s1"] = s1;
  doc["s2"] = s2;
  doc["v"] = v;
  doc["b"] = b;

  // on créee un tableau
  JsonArray liste = doc.createNestedArray("liste");
  for (int i=0; i<=100; i+=10) liste.add(i);

  // on l'imprime
  serializeJsonPretty(doc, Serial);
}

void loop() {}

va afficher

{
  "s1": "Salut",
  "s2": "Bonjour",
  "v": 123,
  "b": true,
  "liste": [
    0,
    10,
    20,
    30,
    40,
    50,
    60,
    70,
    80,
    90,
    100
  ]
}

il faut juste faire attention à ce que le doc soit assez grand pour stocker toutes vos données

Merci J-M-L pour tes exemples. Je viens d'essayer avec mes données pour ton 1er exemple mais je pense effectivement que Node Red attend un tableau puisqu'il parle d'objet (array).

Le hic est que je ne comprends pas trop le tableau que tu propose ou plutôt comment le remplir avec des données tels que des capteurs.

Pourrais tu me donner un exemple avec juste deux données stp ?

Merci !

Au lieu de la boucle qui ajoute dans le tableau un entier qui va de 10 en 10, faites liste.add(xxx); où xxx est ce que vous voulez mettre dans le tableau

Essayez par exemple

Bonjour et merci pour ton exemple. J'ai pu mettre tous mes capteurs et faire des essais. Cependant, je pense que la syntaxe ne convient pas à Node Red.

En effet, sur le debug, j'ai cette forme:

{
  "s1": "Salut",
  "s2": "Bonjour",
  "v": 123,
  "b": true
}

Et Node Red attend une trame sans retour à la ligne du style:

{ "s1": "Salut",  "s2": "Bonjour",  "v": 123,  "b": true}

Je pense que ça doit être ça car il n'arrive pas à dissocier le payload de la valeur.
Aurais-tu une astuce ?

C’est exactement ce qui est dans le JSON

L’affichage du json est fait avec serializeJsonPretty() - le pretty c’est pour dire qu’il fait une jolie mise en forme sur la sortie en faisant l’Indentation et les retours à la ligne

Nodered se fiche aussi de savoir s’il y a des espaces il est capable de parser le JSON quelle que soit sa forme

Pouvez vous partager la spec exacte de ce qu’attend votre serveur ?

Partagez aussi votre code. Comment envoyez vous le JSON ?

Oui biensûr, voici les specifications Node red : Working with messages : Node-RED

Voici mon code:

#include <ArduinoJson.h>
#include <SPI.h>
#include <LoRa.h>
#include <Wire.h>
#include "SSD1306.h"
#include "images.h"

#define SCK     5    // GPIO5  -- SX1278's SCK
#define MISO    19   // GPIO19 -- SX1278's MISO
#define MOSI    27   // GPIO27 -- SX1278's MOSI
#define SS      18   // GPIO18 -- SX1278's CS
#define RST     14   // GPIO14 -- SX1278's RESET
#define DI0     26   // GPIO26 -- SX1278's IRQ(Interrupt Request)
#define BAND    8695E5

SSD1306 display(0x3c, 21, 22);
unsigned int compteur = 0;
String rssi = "RSSI --";
String packSize = "--";
String packet ;
String poids = "Poids";
String tempINT = "Température INT";
String tempEXT = "Température EXT";
String humEXT = "Humidité EXT";
float data1R[7];
String NumRuche = "Numéro de ruche"; // Donnée de discrimination pour reconnaître les différentes ruches
String Data1 = "";
String Volts = "Tension";
int bouton = 0;
int etatbouton = 0;
long temps;
int memoirebouton;


DynamicJsonDocument doc(500); // sur le heap.



void setup() {
  pinMode(bouton, INPUT);
  pinMode(16, OUTPUT);
  digitalWrite(16, LOW);    // set GPIO16 low to reset OLED
  delay(50);
  digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high、
  compteur = 0 ;
  temps = millis();
  Serial.begin(9600);
  while (!Serial);
  Serial.println();
  Serial.println("LoRa Receiver Callback");
  LoRa.setSpreadingFactor(10);
  SPI.begin(SCK, MISO, MOSI, SS);
  LoRa.setPins(SS, RST, DI0);
  if (!LoRa.begin(BAND)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
    LoRa.setSpreadingFactor(10); // Facteur d'étalement 7 est la valeur par défaut. Permet de discriminer deux émissions
  LoRa.receive();
  Serial.println("init ok");
  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);

  delay(1500);
}

void loop() {

  int packetSize = LoRa.parsePacket();
  if (packetSize) {   
      
    while (LoRa.available()) {
      //Serial.println("Paquets recus ");

      compteur++ ;
      //Serial.println(compteur);

      LoRa.readBytes((uint8_t *)&data1R, packetSize);
      Data1 += data1R[0]; //Lit les données l'une après l'autre (+=)
      Data1 = Data1.toFloat();
      NumRuche = data1R[0];
      tempINT = data1R[1];
      tempEXT = data1R[2];
      humEXT = data1R[3];
      poids = data1R[5];
      Volts = data1R[6];
      /*     Serial.print("Tension :");
           Serial.println (Volts);
           Serial.print("Numero de ruche :");
           Serial.println (NumRuche);
           Serial.print("Température INT :");
           Serial.println (tempINT);
           Serial.print("Température EXT :");
           Serial.println (tempEXT);
           Serial.print("Humidite EXT :");
           Serial.println (humEXT);
        //      Serial.println("Humidite INT :");
        //      Serial.println (humidityDHT11);
           Serial.print("Poids :");
           Serial.println (poids);*/

      //json
      // on créee un tableau
      /* JsonArray liste = doc.createNestedArray("DHT22");
        liste.add(tempEXT);
        liste.add(tempINT);
      */
      // on construit le JSON
        doc["Température EXT"] = tempEXT;
        doc["Température INT"] = tempINT;
        doc["Humidité EXT"] = humEXT;
        doc["Numéro de ruche"] = NumRuche;
        doc["Tension"] = Volts;
        doc["Poids"] = poids;


      // on l'imprime
      serializeJsonPretty(doc, Serial);


      //Gestion du bouton
      etatbouton = digitalRead(bouton);
      if (etatbouton == 0 || memoirebouton == 1 )
      {
        memoirebouton = 1;

        //Gestion de l'écran
        display.clear();
        display.setTextAlignment(TEXT_ALIGN_LEFT);
        display.setFont(ArialMT_Plain_10);

        display.drawString(0, 0, "Numero de ruche :");
        display.drawString(90, 0, String(NumRuche));
        display.drawString(0, 15, "Tint/ext: ");
        display.drawString(90, 15, String(tempINT));
        display.drawString(45, 15, String(tempEXT));
        display.drawString(0, 30, "Humidite EXT: ");
        display.drawString(90, 30, String(humEXT));
        display.drawString(0, 45, "Poids: ");
        display.drawString(90, 45, String(poids));
        display.display();
      }
      if ((millis() - temps) > 300000) // 5 min
        {
          memoirebouton = 0;
          display.clear();
          display.display();
          temps = millis();
        }
    }

  }


}

Bonjour à tous, ça y est, j'y suis arrivé en regardant cette video : Débuter avec l’Arduino et Node-RED. Enregistrer et afficher des mesures en JSON depuis le port série - YouTube.

Du coup j'ai créé une trame "artificiellement". Voici le extrait du code:

//Envoi en json                                                //Selon la video https://www.youtube.com/watch?v=nJ1wtUtcLfM
                                                                     //Verification de la trame avec: https://jsonlint.com/

      Serial.print("{\"Numruche\":");
      Serial.print(NumRuche);
      Serial.print(",\"Tension\":");
      Serial.print(Volts);
      Serial.print(",\"Temperature_INT\":");
      Serial.print(tempINT);
      Serial.print(",\"Temperature_EXT\":");
      Serial.print(tempEXT);
      Serial.print(",\"Humidite\":");
      Serial.print(humEXT);
      Serial.print(",\"Poids\":");
      Serial.print(poids);
      Serial.println("}");

Merci encore et bonne journée !

là c'est envoyé sur le port série... c'est ce que vous voulez ??

Oui c'est ça!

pour parler à Nodered ? je pensais que vous passiez par internet

Pour le moment je passe en serie pour me faire la mains.

Après il est possible que je passe en wifi mais alors là c'est une autre paire de manche pour moi ! :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.