DeltaLab est une association ‘loi 1901’ d’intérêt général, dont l’objectif est la création d’un espace dédié à l’innovation, à la production numérique au prototypage et à l’«expression artistique».
Le principe fondateur de l’association est d’apprendre à faire soi-même, pour passer de l’idée à l’objet.
Deltalab se spécialise en Objets Connectés, et est en train de créer un vaste «écosystème numérique» entre Drôme et Vaucluse, pour répondre à des besoins non couverts, mettre à disposition ressources et équipements pour usage professionnels et instaurer des partenariats avec les autres structures et initiatives numériques existantes.
Deltalab est aussi un FabLab (Fabrication Laboratory / Laboratoire de Fabrication ), un tiers-lieu de type makerspace où se trouve un atelier qui dispose de machines de fabrication comme des Imprimantes 3D ou des découpeuses Laser.
Deltalab se veut ouvert à tous publics : étudiants, professionnels, associations, inventeurs, designers, artistes, etc.
Un des projets à moyen termes de DeltaLab est l’installation d’un réseau LoRaWAN permettant la collecte et le traitement d’un grand nombre de données, et ce sur une grande zone s’étendant sur l’enclave des Papes et la Drôme Provençale.
Ce projet présente l'utilisation d'un capteur de CO2, et de l'envoi des données en LoRaWAN.
A DeltaLab, un projet d'Aquaponie est en projet, et ce capteur sera évidemment utilisé dès le début.
Ce projet a pour but de présenter l'utilisation d'un capteur de qualité de l'air composé d'un capteur TVOC (Total Volatile Organic Compound) et d'un capteur de CO2, dans le but de les intégrer à un système plus grand.
Le projet se décompose en 2 parties distinctes : le capteur et la carte TTGO associée, et le serveur Node-RED.
Les fonctionnalités proposées par ce projet sont les suivantes :
Récupération des données des capteurs
Affichage dans Node-RED
Arduino IDE : téléchargeable à www.arduino.cc/en/main/software
Node-RED : on assume que vous en avez un, sinon installez-le avec ceci.
TTGO : Fichier > Préférences > URL du gestionnaire de cartes. Entrez l’URL
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
Puis, dans Arduino, Outils> Type de Carte > Gestionnaire de cartes, recherchez ESP32 et installez la carte correspondante. Choisissez ensuite TTGO_LoRa_32-OLED comme Type de Carte.
Librairies :
MCCI_LoRaWAN_LMIC : pour LoRaWAN
dans Arduino : Outils > gérer les bibliothèques
entrez LMIC et installez la librairie MCCI_LoRaWAN_LMIC_Library
important : allez dans votre dossier arduino (défaut : Documents\Arduino) et allez dans la configuration de la librairie pour activer la bonne fréquence ( libraries > MCCI_LoRaWAN_LMIC_Library > project_config > lmic_project_config.h ).
Dans ce fichier, décommentez (enlevez le ' // ') la ligne #define CFG_eu868 1 (fréquence européenne) et commentez (mettez un ' // ') la ligne qui était décommentée (par défaut #define CFG_us915 1, fréquence américaine).
Si vous avez un problème de définition pour hal_init ajoutez #define hal_init LMICHAL_init dans libraries > MCCI_LoRaWAN_LMIC_Library > project_config > lmic_project_config.h.
Adafruit_CCS811 : pour le capteur
dans Arduino : Outils > gérer les bibliothèques
entrez CCS811 et installez la librairie Adafruit_CCS811_Library
VCC --> 3.3V
GND --> GND
SCL --> 22
SDA --> 21
WAK --> GND
Les bibliothèques utilisées sont:
MCCI_LoRaWAN_LMIC
Adafruit_CCS811_Library
Copiez-collez le code ci-dessous dans un fichier arduino:
//Librairies
#include <lmic.h>
#include <hal/hal.h>
#include "Adafruit_CCS811.h"
//Constantes
#define SCK 5 // GPIO5 -- SX1278's SCK
#define MISO 19 // GPIO19 -- SX1278's MISnO
#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)
Adafruit_CCS811 ccs;
//Variables
double CO2;
double TVOC; // Total Volatile Organic
osjob_t sendjob;
const unsigned TX_INTERVAL = 2 ;
// Données à envoyer
typedef union {
float f[2];
unsigned char bytes[8];
} donnees;
donnees datas;
// Application EUI : en 'lsb' (little endian format)
static const u1_t PROGMEM APPEUI[8]={ /*disponible lors de la création de l'objet sur TheThingsNetwork */ };
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}
// Device EUI : même chose qu'au dessus
static const u1_t PROGMEM DEVEUI[8]={ /*disponible lors de la création de l'objet sur TheThingsNetwork */ };
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}
// Application Key : vous pouvez la copier telle qu'elle depuis TTN
static const u1_t PROGMEM APPKEY[16] = { /*disponible lors de la création de l'objet sur TheThingsNetwork */ };
void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}
//Pin Mapping
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst = 14,
.dio = {26, 33, 32},
};
// Gestionnaire des évenements de TTN
void onEvent (ev_t ev) {
switch(ev) {
case EV_JOINING:// recherche d'une antenne LoRaWAN pour se connecter à TTN
Serial.println(F("EV_JOINING - antenne cherchée"));
break;
case EV_JOINED:// connection à TTN établie
Serial.println(F("EV_JOINED - antenne connectée"));
LMIC_setLinkCheckMode(0);
break;
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE - message envoyé"));
// Envoi du message contenant les données
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), Send);
break;
default:
Serial.print(F("Unknown event: ")); // Par défaut, il sera affiché un évènement inconnu
Serial.println((unsigned) ev);
break;
}
}
// Envoi des données à TTN
void Send(osjob_t* j){
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending"));
} else {
// Insertion des données dans le tableau de données qui sera envoyé
datas.f[0] = CO2; //temperature
datas.f[1] = TVOC; //pression
LMIC_setTxData2(1, datas.bytes, 8, 0);
Serial.println(F("Packet queued"));
}
}
// SetUp : démarrage du capteur, initialisation de LMIC et de la boucle d'envoi
void setup() {
Serial.begin(115200); // Démarrage du moniteur série
if(!ccs.begin()){ //Message d'erreur si le capteur n'est pas connectée
Serial.println("Echec detection capteur CCS811");
while(1);
}
// Attente que le capteur soit pret ...
while(!ccs.available());
Serial.println(F("Starting"));
os_init();
LMIC_reset();
LMIC_setClockError(MAX_CLOCK_ERROR * 10/100);
Send(&sendjob);
}
// Boucle automatique
void loop() {
if(ccs.available()){
if(!ccs.readData()){
CO2 = ccs.geteCO2(); // Récupération de la donnée de CO2
TVOC = ccs.getTVOC(); // Récupération de la valeur total des composés organiques volatiles
//Affichage des données
Serial.print("CO2 : ");
Serial.print(ccs.geteCO2());
Serial.print("ppm, TVOC : ");
Serial.println(ccs.getTVOC());
}
}
os_runloop_once();
}
Avant de lancer le programme, il faut créer la réception des données sinon le code tournera en boucle sans rien faire.
Sur The Things Network, il est possible d'enregistrer son objet pour voir le flux de données.
Avant cela, si vous n'avez pas d'antenne LoRaWAN pour recevoir les données allez ici.
Sur TTN (www.thethingsnetwork.org/), connectez-vous (ou créez un compte), allez dans la console en cliquant sur votre profil, allez dans Applications et Ajoutez une nouvelle appli. Renseignez un ID, un nom et une description (facultatif).
Dans cette application, ajoutez un nouveau End Device. Renseignez les informations de votre objet connecté dans la section Manually.
LoRaWAN version : MAC V1.0
Sélectionnez la fréquence dans Frequency plan dont l'endroit correspond à la région où sera placé votre objet. En Europe, on prendra la fréquence Europe 863-870 MHz(SF9 for RX2-recommended).
L’AppEUI devrait être renseigné par le fabricant ou remplissez avec des zéros.
Le DevEUI est soit renseigné par le fabricant ou imprimé sur le paquet ou générer par le bouton juste à droite.
L’Appkey est soit renseigné par le fabricant ou générer par le bouton juste à droite.
Dans l'overview de votre End Device , vous avez accès aux EUIs et à l’AppKey nécessaires dans le programme. Pour les EUIs, cliquez sur les chevrons à droite de chacun d'eux, ils seront au format msb.
Et ça tombe bien, sur Arduino les EUIs sont au format msb. Vous pouvez les copiez et les collez dans le code.
Pour l' AppKey, il faudra la rendre visible en cliquant sur l'œil et dans le code remplacez seulement les chiffres après les 0x.
On utilise un décodeur sur TTN car les données qui sont créées par les objets sont au format binaire donc illisible pour l’homme.
On utilisera le langage Javascript pour créer notre propre décodeur.
Dans Application > End devices > votre device > Payload Formatters et dans Uplink sélectionnez Javascript dans le menu déroulant. Copiez-collez le code ci-dessous dans la zone 'Formatter parameter'. Et cliquez sur Save changes pour sauvegarder. Et vérifiez l'indentation sinon cela ne fonctionnera pas.
function B2F32(bytes) { // Convertit les données binaires en nombres à virgules
var sign = (bytes & 0x80000000) ? -1 : 1;
var exponent = ((bytes >> 23) & 0xFF) - 127;
var significand = (bytes & ~(-1 << 23));
if (exponent == 128)
return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);
if (exponent == -127) {
if (significand === 0) return sign * 0.0;
exponent = -126;
significand /= (1 << 22);
} else significand = (significand | (1 << 23)) / (1 << 23);
return sign * significand * Math.pow(2, exponent);
}
function Decoder(bytes, port) { // Envoi du message de donnée au serveur MQTT
var CO2= bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
var TVOC = bytes[7] << 24 | bytes[6] << 16 | bytes[5] << 8 | bytes[4];
return{
CO2: B2F32(CO2) , TVOC: B2F32(TVOC)
}; }
Maintenant vous pouvez upload votre programme, si vous voulez suivre ce que le programme fait allez dans Outils et cliquez sur Moniteur série.
Pour que l’on puisse récupérer les données avec Node-RED, nous allons créer un serveur MQTT.
Toujours dans TheThingsNetwork dans votre Application, allez dans Integrations > MQTT. Cliquez sur Generate new API key et copiez-la car elle ne sera plus visible si vous quittez la page. L' API key servira de mot de passe.
Ça y est, on peut maintenant traiter les données avec Node-RED.
Le capteur envoie ses données et TTN les récupère. Node-RED les lit ensuite grâce à la node mqtt-in.
Les données sont ensuite récupérées par les nodes de dashboard qui permettent de les afficher : des jauges pour le CO2 et le TVOC (TCOV en français: Total des Composés Organiques Volatiles).
Chaque fois que vous finissez de configurer un node, cliquez sur Done.
ATTENTION : pour enregistrer vos modifications, cliquez sur Deploy.
Pour commencer, on va vouloir récupérer les données reçu par l’antenne LoRaWAN via TTN. Prenez ce node, double-cliquez dessus.
Dans le menu de sélection Server, prenez Add new mqtt-broker et cliquez sur le bouton à côté.
Dans la partie Security, entrez les identifiants en accord avec ceux lors de la création du serveur MQTT.
Dans la partie Connection, précisez l’adresse du serveur MQTT de la Console The Things Stack. Et dans Protocol, sélectionnez MQTT V3.1.1.
Revenez dans les propriétés. Le topic sert à préciser de quel objet on veut traiter les données. Voici le format du topic : v3/username/devices/device_id/up. Faites attention à ce qu’il n’y est pas d’espace surtout au début et à la fin.
Sélectionnez le QoS que vous voulez (privilégiez le 2).
Et dans Output, prenez a parsed JSON object.
Pour finir, branchez une node de debug pour voir si les données de l’objet choisi arrive bien.
N'hésitez pas à connectez des nodes de debug, cela permet de savoir si vos données arrive bien et au bon format.
Pour voir les données là où vous avez connecté des debug, cliquez sur le petit insecte en haut à droite de l'écran, puis all nodes puis current flow pour voir le flux du flow sur lequel vous travaillez.
Pour l'état du capteur, cliquez sur add en bas à gauche de Rules.
Mettez la première règle sur Set. Entrez topic, puis la_variable_à_choisir en-dessous.
Ajoutez une deuxième règle et mettez-la sur Move, entrez payload.uplink_message.decoded_payload.CO2 (TVOC) dans le premier champ et payload dans le deuxième.
N’oubliez pas de faire attention à ne pas laisser d’espace.
Pour les jauges, prenez trois de ce node et connectez-les au mqtt-in et configurez-les de cette manière :
Group: créez un nouveau groupe
ui_tab : créez une nouvelle table
width(largeur) : à votre guise
name : celui que vous voulez
Type: gauge
Label: CO2, TVOC
Value format:
CO2: {{msg.payload}}
TVOC: {{msg.payload}}
Echelle:
CO2: 0 à 29206, unité : ppm (parties par million)
TVOC: 0 à 32768, unité : ppb (parties par milliard)
L'intérêt de tout ceci est pour la visualisation des données. Node-RED permet ceci avec une interface utilisateur.
Pour y accéder, avec le moteur de recherche que vous voulez, tapez l'ip du serveur Node-RED, puis deux points, puis le numéro port puis /ui (XXX.XXX.XXX.XXX:YYYY/ui).
Pour mettre en forme l'interface utilisateur, retournez dans Node-RED
Cliquez sur les trois barres en haut à droite, allez dans View puis cliquez sur Dashboard.
En mettant le curseur sur le nom du groupe des jauges et du graphe, cliquez sur layout.
Sur la droite réglez la largeur de l'interface sur Width. Ensuite cliquez sur Done, puis sur Deploy et revenez dans le layout pour faire la mise en forme.
Pour modifier la taille des composants, cliquez sur le cadenas en haut à droite du composant et une double flèche apparait en bas à droite de ce dernier. Maintenez le clique dessus pour modifier la taille.