Sonde de capteurs avec mémorisation des informations dans le temps...

- Catégories : Loegaux

Sonde "Intelligente"

Le but de cet article est de vous aider à réaliser une sonde permettant de :

  • Récupérer des informations de différents capteurs,
  • Envoyer ces informations périodiquement et à longue distance sur un collecteur
  • Enregistrer ces informations dans le temps (mois ou années) à des fion d'analyse
  • Permettre d'envoyer des alertes en cas d'atteinte de différents seuils
  • De récupérer les informations sur une application mobile
  • Et tout ça... sans avoir besoin de payer à abonnement quelconque.
  • Et pourquoi pas, également interagir avec les sondes pour, par exemple, activer un relai.

Et bien, c'est possible !

Comment ? En utilisant une carte de développement permettant d'envoyer des informations sur le réseau LoraWan et d'utiliser de manière combinée TTN (The Things Network) et Cayenne My Device.

Le but final est d'arriver à récupérer un dashboard lisible

Exploitable dans le temps :

Et permettant de mettre en place des alerte par mail ou SMS :

Pour commencer, les prérequis !!

Il vous faut, avant de commencer ce projet, les choses suivantes :

  • Une carte de développement type Heltec ESP32 Lora Wifi. Vous en trouverez une sur ce site ICI.
  • Des capteurs ! (pour l'exemple, nous utiliserons un capteur de température et d'humidité type AM2302)
  • Un compte sur TTN vous permettant de créer une nouvelle "Application".
  • Un compte sur Cayenne My Device pour récupérer les informations dans un dashboard.
  • Enfin, installer la dernière version de l'IDE Arduino pour programme la carte de développement.

Pour commencer sur TTN, il faut créer votre compte puis :

  • Créer une nouvelle Application,
  • Ajouter un Device à l'Application.

Pour Cayenne, il faut créer votre compte puis :

  • Ajouter un Device de type Lora/TTN/Cayenne LPP
  • Renseigner un DevEUI

Bien noter ces informations car elles vous seront utiles pour programmer votre sonde.

Il faut maintenant "Intégrer" Cayenne dans TTN. Pour cela :

  • Dans l'interface TTN de votre Application, cliquer sur "Intégration"
  • Cliquer sur "Add Integration"
  • Choisir "My Device"

Si vous rencontrez un problème pour faire votre intégration, pas de panique, les sites My Device et TTN regorge de documentation pour vous aider.

Enfin, le programme !!

Vous avez tout le nécessaire, il faut maintenant programmer !!

Il faut commencer par ajouter les librairies nécessaires pour, la connexion au réseau LoraWan TTN, à Cayenne, gérer la sonde, etc...

#include 
#include <hal/hal.h>
#include 
#include 
#include "SSD1306.h"
#include "DHTesp.h"
#include "LPPDecode.h"
  

Les variables globales du projet et configuration de base :

// Variables globales
// Taille maximum de message
#define MAX_SIZE 100

#define DHTPIN 17              // broche ou l'on a branche le capteur
DHTesp dht;

boolean TTNConnected=0;          // suis je connecté à TTN ?

uint32_t prevMillis = 0;
uint32_t TimeToWait = 20;
uint32_t WaitingFor = 0;
int TypeAff = 0;
float temp, hum, pres, uvindex, lum;    //Valeur pour la sonde.
float ValueReturn;                      // Donnée du canal 81
double d=0;
boolean LEDint = 0;
int CANAL = 11;
String DevAddr="TTN2";
String LastMsg="";

// Notre message au format LPP
CayenneLPP lpp(MAX_SIZE);

#define SDA    4
#define SCL   15
#define RST_OLED   16 //RST must be set by software
#define OLED_UPDATE_INTERVAL 500

osjob_t initjob;

SSD1306  display(0x3c, SDA, SCL);
long NbTrans = 0;

Les paramètres spécifiques pour TTN - Las informations renseignées ici viennent de la configuration de votre device dans TTN.


// This EUI must be in LSB format, so least-significant-byte
// first. When copying an EUI from ttnctl output, this means to reverse
// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
// 0x70.
static const u1_t PROGMEM APPEUI[8]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}

// This should also be in LSB format, see above.
static const u1_t PROGMEM DEVEUI[8]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}

// This key should be in big endian format (MSB) (or, since it is not really a
// number but a block of memory, endianness does not really apply). In
// practice, a key taken from ttnctl can be copied as-is.
// The key shown here is the semtech default key.
static const u1_t PROGMEM APPKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY, 16);}

Viennent les procédures de call back pour la prise en charge des transmissions vers TTN en LoraWan.


//////////////////////////////////////////////////
// APPLICATION CALLBACKS                        //
//////////////////////////////////////////////////

static osjob_t sendjob;

// Pin mapping
const lmic_pinmap lmic_pins = {
  .nss = 18,
  .rxtx = LMIC_UNUSED_PIN,
  .rst = 14,
  .dio = {26, 35, 34},
};

void onEvent (ev_t ev) {
String DECODE;

    display.drawString(86, 0, " ");
    display.display();
    //debug_event(ev);
    Serial.print(os_getTime());
    Serial.print(": ----------- >>>>> ");
    switch(ev) {
      // scheduled data sent (optionally data received)
      // note: this includes the receive window!
      case EV_JOINING:
            LastMsg = "J";
            Serial.println(F("EV_JOINING")); break;
            TimeToWait=60;
      case EV_JOINED:
            TTNConnected=1;
            Serial.println(F("EV_JOINED //////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\ :) YESSSSSSSSS"));
            // link check validation non supporté avec TTN
            LMIC_setLinkCheckMode(0);
  //         LMIC_setDrTxpow(DR_SF12,14);
            TimeToWait=300;     // Envoyer un message toutes les 5 mn (300 secondes)
            break;
      case EV_JOIN_FAILED:
           LastMsg = "F";
           TTNConnected=0;
           TimeToWait=20;
           Serial.println(F("EV_JOIN_FAILED, Le nœud n'a pas pu rejoindre le réseau (après une nouvelle tentative).")); break;
      case EV_LINK_DEAD:
           LastMsg = "D";
           TTNConnected=0;
           TimeToWait=20;
           Serial.println("EV_LINK_DEAD, Aucune confirmation n'a été reçue du serveur de réseau pendant une période prolongée."); break;
      case EV_LINK_ALIVE:    
           LastMsg = "A";
           TTNConnected=1;
           TimeToWait=180;
           Serial.println("EV_LINK_ALIVE, Le lien était mort, mais est maintenant en vie."); break;
      case EV_TXSTART:
           LastMsg = "Tx";
           Serial.println("EV_TXSTART, Demande de transmission initiée"); break;
      case EV_TXCOMPLETE:
          // use this event to keep track of actual transmissions
          Serial.print("---------------->   Event EV_TXCOMPLETE, time: ");
          Serial.println(millis() / 1000);
          if (LMIC.txrxFlags & TXRX_ACK)
              LastMsg="Ta";
              Serial.println(F("-------------->>> Received ack"));
          if(LMIC.dataLen) { // data received in rx slot after tx
              Serial.print(F("Received ")); Serial.print(LMIC.dataLen); Serial.println(F(" bytes of payload"));
              if (LMIC.dataLen == 4) {
                LPP_Digital(11, 25);
                LEDint = digitalRead(25);
                if (LPP_Analog(81, ValueReturn)){
                  Serial.print("Valeur sur canal 81 : "); Serial.println(ValueReturn);
                }
              }
              Serial.println(" ");
          }
          os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TimeToWait), do_send);
          AffSession();
          break;
       case EV_RXCOMPLETE:
            LastMsg = "Rx";
            // data received in ping slot
            Serial.println(F("EV_RXCOMPLETE"));
            break;
       case EV_LOST_TSYNC:
            LastMsg = "Lost";
            Serial.println(F("EV_LOST_TSYNC"));
            break;
       case EV_RESET:
            LastMsg = "Rst";
            Serial.println(F("EV_RESET"));
            break;
       default:
          NbTrans = 0 ;
          LastMsg = "?";
          Serial.print ("Ev inconnu ");
          Serial.println(ev);
          break;
    }
}


void do_send(osjob_t* j){

    temp = dht.getTemperature();
    hum = dht.getHumidity();
    Serial.print("Up Time - "); Serial.println(millis()/1000); 
    
    Serial.print("   -  Opmode check : ");
    // Check if there is not a current TX/RX job running
    if (LMIC.opmode & OP_TXRXPEND) {
      Serial.println("OP_TXRXPEND, not sending");
    } else {
        // Prepare upstream data transmission.
        if (isnan(temp) || isnan(hum))
        {
           Serial.println("Failed to read from DHT sensor!");
           WaitingFor = 2000;
           Serial.println("2 seconds waiting end");
        } 
        else
        {
           NbTrans = NbTrans + 1 ;
           lpp.reset();
           lpp.addTemperature(0, temp);
           lpp.addRelativeHumidity(1, hum);
           //lpp.addBarometricPressure(2, pres);
           lpp.addAnalogInput(3,(int)(d*4.1667));
           lpp.addAnalogInput(4,NbTrans);
           lpp.addDigitalOutput(11,LEDint);
           lpp.addAnalogOutput(81,ValueReturn);
           
           // lpp.addLuminosity(4,(int)lum);
           LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0);
           Serial.println("Send information via LoRaWan  -----------------------------------------------");
          // WaitingFor = 600000;   // Valeur normale : 600000
        }
    }
    if (LMIC.txrxFlags & TXRX_ACK)
    Serial.println(F("-------------->>> Received ack"));
    // Schedule a timed job to run at the given timestamp (absolute system time)
    // Serial.println("Next schedule time job");
    os_setTimedCallback(j, os_getTime()+sec2osticks(TimeToWait), do_send);   //pour test
 
    Serial.print("Température de la sonde : "); Serial.println(temp);
    if (TTNConnected) affTemp(); 
    else AffOled();
    AffSession();
}

Voici pour les grandes ligne de ce projet !!

Le code source complet est disponible sur le site ICI.

Partager ce contenu

Ajouter un commentaire

1 commentaires

Allarevoyure - 19/01/2023 15:31:49


Trop bien