[TUTORIEL] Station météo connectée

Forum de support et d'échange sur la carte Akeru (carte compatible Arduino développée par Snootlab et intégrant la technologie Sigfox) et du shield Akene pour Arduino (shield pour Arduino développée par Snootlab et intégrant la technologie Sigfox)

[TUTORIEL] Station météo connectée

Message non lude Laetitia » Mar 24 Fév 2015 16:52

MAJ le 28.07.2016 pour la sortie de la librairie Akeru v4 >> Voir post suivant

Bonjour,

Aujourd'hui nous allons monter une station météo connectée. Les données ambiantes seront relevées à partir d'une photorésistance (luminosité) et d'un capteur DHT11 (température et humidité), puis envoyées sur le réseau grâce à l'Akeru.
Nous utiliserons l'horloge RTC DS1307 du shield Mémoire pour gérer le timing entre deux envois, pour ceux qui n'en ont pas à disposition vous pouvez commenter les lignes concernant l'horloge et décommenter celles qui utilisent la fonction millis().

- MATÉRIEL -

- Akeru
- Shield Mémoire
- Capteur de température et d'humidité DHT11
- Photorésistance

Librairies à installer :
- Akeru
- DHT
- RTClib

- SCHÉMA DU MONTAGE -

StationMeteo.png
StationMeteo.png (95.59 Kio) Vu 2283 fois

Le shield Mémoire est monté sur l'Akeru, les capteurs dessus. Les mêmes branchements peuvent être réalisés sans le shield.

- EXPLICATIONS -

Ce tutoriel présente le même montage que la station météo que je vous avais présentée il y a quelques temps. Le code est également identique pour la partie purement "Arduino", c'est à dire le relevé des données en provenance des capteurs. Je vous invite donc à lire ce tutoriel si vous souhaitez plus d'explications sur le capteur DHT11 ou l'horloge DS1307... car ici nous allons nous intéresser d'un peu plus près à l'envoi des données avec l'Akeru :geek:

    Mais je sais déjà faire un Akeru.send()...
Il est tout à fait possible d'envoyer les données une par une, mais Actoboard permet de traiter toute une chaîne de valeurs si vous lui indiquez le format des données à recevoir. Aussi, vous pouvez créer des structures contenant plusieurs variables pour simplifier à la fois l'écriture du code et leur envoi par l'Akeru.

Imaginons que vous vouliez stocker des données ayant un lien entre elles. Il peut s'agir d'un repère temporel, comme dans le cas de notre station météo, ou un paramètre quelconque. Lorsque l'on a des données de même type, il suffit de créer un tableau, et l'on accède à ses différents éléments avec l'indice qui lui est associé. Mais lorsque l'on veut manipuler ensemble des types de variables différents, on crée une structure !

    Comment ça marche ?
Le plus simple c'est encore de prendre un exemple :

Code: Tout sélectionner
typedef struct
{
  int age;
  float taille;
  float poids;
} Personne;

Décortiquons un peu :
- typedef struct, ce sont les mots-clés indiquant que l'on va créer une structure, contenant les variables qui seront définies entre les crochets qui suivront,
- age, taille et poids sont les trois variables que l'on va renseigner, remarquez qu'elles sont de type différents (float et int),
- Personne est le nom que vous attribuez au type de structure que vous venez de créer.

Nous avons donc un nouveau type de variable à manipuler, que l'on déclare de la même manière, en renseignant son type et son nom :

Code: Tout sélectionner
Personne John;

Ensuite, vous accédez aux différentes variables de la structure en appelant les champs définis plus tôt :

Code: Tout sélectionner
John.age = 25;
John.taille = 1.89;
John.poids = 80.0;

    Quel est le rapport avec l'Akeru ?
La fonction Akeru.send() permet d'envoyer des données en indiquant l'adresse de la variable concernée ainsi que son format. Mais il doit s'agir d'un format "règlementaire", et vous ne pouvez indiquer qu'un seul format, pas moyen de dire à l'Akeru, en une seule commande, qu'on va lui faire envoyer un int, puis un float, etc.

C'est là que les structures deviennent utiles ! Lorsque vous déclarez votre structure, un espace mémoire lui est réservé. Cet espace mémoire fait la taille de toutes les variables qu'elle contient, et elles seront rangées dans l'ordre que vous avez indiqué.
Donc... envoyer une structure à la place d'une variable classique permet d'envoyer toutes les données qu'elle contient ! Il ne vous reste plus qu'à renseigner dans Actoboard les types de variables attendus, dans le même ordre que dans votre code.

Passons-y, justement :

- CODE -

Code: Tout sélectionner
/*
 * Tutoriel : Station météo connectée
 * Matériel : Akeru + shield Mémoire + DHT11 -> D2 + photorésistance -> A1
 *
 * Ce sketch n'exploite que la RTC du shield Mémoire.
 * En cas d'absence du shield, commentez les lignes concernant la RTC
 * et décommentez celles permettant de gérer le délai entre deux envois
 * avec la fonction millis()
 */

    /* RELEVÉ DONNÉES MÉTÉO */
   
// Inclusion de la librairie nécessaire pour la lecture du DHT11
#include <DHT.h>

//Déclaration des pins reliées aux capteurs
#define photores 1
#define DHTPIN 2

// Déclaration du type de capteur utilisé et initialisation
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

    /* DATALOGGING */

// Inclusion des librairies nécessaires à l'utilisation de la RTC du shield Mémoire
// (Wire.h est intégrée à l'IDE Arduino)
/* à commenter en cas d'absence de shield Mémoire)*/
#include <Wire.h>
#include <RTClib.h>

// Déclaration des objets liés à l'horloge
/* à commenter en cas d'absence de shield Mémoire)*/
RTC_DS1307 RTC;
DateTime timestamp;
int updateTime;

// Déclaration des variables relatives au délai entre deux envois
/* à décommenter en cas d'absence du shield Mémoire */
// unsigned long prevMillis = 0;
// unsigned long interval = 600000; // = 10mn*60s*1000ms


// Inclusion des librairies nécessaires pour l'Akeru
#include <Akeru.h>
#include <SoftwareSerial.h>

// Déclaration de la structure permettant de stocker toutes les données
typedef struct
{
  float hum;  // humidité
  float temp; // température
  int lum;    // luminosité
} Payload;

void setup()
{
  Serial.begin(9600);
 
  // Initialisation Akeru
  Akeru.begin();
 
  // Initialisation DHT11
  dht.begin();
 
  // Initialisation RTC
  /* à commenter en cas d'absence de shield Mémoire)*/
  Wire.begin();
  RTC.begin();
 
  // Mise à l'heure suivant paramètres système
  /* à commenter en cas d'absence de shield Mémoire)*/
  RTC.adjust(DateTime(__DATE__, __TIME__));
  if (!RTC.isrunning())
  {
    Serial.println("RTC is NOT running !");
  }
 
  // Sauvegarde de l'heure de départ pour commencer l'enregistrement des données
  /* à commenter en cas d'absence de shield Mémoire)*/
  DateTime startTime = RTC.now();
  updateTime = startTime.minute();
}

void loop()
{
  Payload p;
  // Relevé des valeurs en provenance du DHT11
  p.hum = dht.readHumidity();
  p.temp = dht.readTemperature();
 
  // Relevé des valeurs en provenance de la photorésistance et conversion en pourcentage
  p.lum = analogRead(photores);
  p.lum = map(p.lum, 0, 1023, 0, 100); // Valeurs 0 et 1023 à rajuster en fonction des conditions réelles
 
  /* GESTION DE L'ENVOI DES DONNÉES AVEC LA RTC DU MÉMOIRE */
  /* Les lignes suivantes sont à commenter en cas d'absence de shield Mémoire */
 
  // Timestamp
  timestamp = RTC.now();
 
  // On regarde s'il est temps de faire un relevé sur la carte SD
  // C'est-à-dire s'il s'est écoulé plus de 10 minutes depuis le dernier relevé
  if ((timestamp.minute() - 10) == updateTime)
  {
    // auquel cas on remet à jour la variable concernée
    updateTime = timestamp.minute();
    // puis on envoie les données sur le réseau
    Akeru.send(&p, sizeof(p));
  }
  // cas particulier : lorsque le dernier relevé est à __:5_:__, le prochain doit se faire à __:0_:__
  else if ((timestamp.minute() < 10) && ((timestamp.minute() + 50) == updateTime))
  {
    updateTime = timestamp.minute();
    Akeru.send(&p, sizeof(p));
  }
 
  /* GESTION DE L'ENVOI DES DONNÉES SANS SHIELD MÉMOIRE */
  /* Les lignes suivantes sont à décommenter en cas d'absence de shield Mémoire */
 
  /*
  // S'il s'est écoulé assez de temps
  if ((millis() - prevMillis) > interval)
  {
    // On enregistre l'heure courante pour le prochain tour de loop
    prevMillis = millis();
    // Et en envoie les données sur le réseau
    Akeru.send(&p, sizeof(p));
  }
  */
}


Paramétrage de la réception des données côté actoboard :

Actoboard_DataFormat.png
Actoboard_DataFormat.png (26.35 Kio) Vu 2283 fois

Il ne vous reste plus qu'à aller tracer vos courbes ou exporter vos données... voilà ce que ça peut donner sur le dashboard, avec un aperçu des conditions météo... dans nos locaux !

Actoboard_Graph.png
Actoboard_Graph.png (37.84 Kio) Vu 2283 fois


C'est tout pour cette fois ! J'espère que ce tutoriel vous aura plu, et bonne bidouille en attendant le prochain !
"If it's itchy, scratch it !" - "DIY or die"

RTFM (À lire avant de poster) - ANDb (Arduino Noob Database)
Avatar de l’utilisateur
Laetitia
 
Messages: 296
Inscription: Mar 7 Aoû 2012 15:07
Localisation: Toulouse

[UPDATE] Station météo connectée v2 (lib v4)

Message non lude Laetitia » Jeu 28 Juil 2016 15:05

MAJ le 28.07.2016 pour la sortie de la librairie Akeru v4

La nouvelle librairie gère toute seule le timing entre deux envois, et rend l'utilisation du shield Mémoire superflue ! Le sketch est plus léger et tout aussi efficace. Le principe reste le même que ci-dessus, je détaillerai simplement les changements notoires dûs au rework de la librairie.

- MATÉRIEL -

- Akeru
- Capteur de température et d'humidité DHT11
- Photorésistance

Librairies à installer :
- Akeru
- DHT

- SCHÉMA DU MONTAGE -

Identique à celui du post précédent, sans le shield Mémoire.

- NOUVELLE LIBRAIRIE AKERU -

Changements importants, valables dans tous vos sketchs incluant la nouvelle version de la librairie :
  • Plus besoin d'inclure la librairie SoftwareSerial dans le sketch
  • La définition des RX/TX se fait directement dans le sketch et non plus dans le fichier .cpp (pour adapter plus facilement le sketch pour un Akene ou un breakout TD1208)
  • Le payload se présente sous la forme d'un objet String au lieu d'une structure struct
  • Il faut convertir les données en hexadécimal avant de les envoyer, à l'aide de la fonction toHex()
  • Plus besoin d'insérer des délais ou d'appeler la fonction isReady() pour gérer le timing entre deux messages, la fonction sendPayload() s'en charge.
- CODE -

Code: Tout sélectionner
/*
 * Tutoriel : Station météo connectée
 * Matériel : Akeru + DHT11 -> D2 + photorésistance -> A1
 * Librairie Akeru v4 : https://github.com/Snootlab/Akeru
 */   
// Inclusion de la librairie nécessaire pour la lecture du DHT11
#include <DHT.h>

//Déclaration des pins reliées aux capteurs
#define photores 1
#define DHTPIN 2

// Déclaration du type de capteur utilisé et initialisation
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// Inclusion de la librairie nécessaire pour l'Akeru
#include <Akeru.h>

// Définition des RX/TX de l'Akeru
#define TX 4
#define RX 5

// Initialisation objet
Akeru Akeru(RX, TX);

void setup()
{
  Serial.begin(9600);
 
  // Initialisation Akeru
  if (!Akeru.begin())
  {
    Serial.println("Akeru KO");
    while(1);
  }
 
  // Initialisation DHT11
  dht.begin();
}

void loop()
{
  // Relevé des valeurs en provenance du DHT11
  float hum = dht.readHumidity();
  float temp = dht.readTemperature();
 
  // Relevé des valeurs en provenance de la photorésistance et conversion en pourcentage
  int lum = analogRead(photores);
  lum = map(lum, 0, 1023, 0, 100); // Valeurs 0 et 1023 à ajuster en fonction des conditions réelles

  Serial.print("hum = ");
  Serial.print(hum);
  Serial.print("\ttemp = ");
  Serial.print(temp);
  Serial.print("\tlum = ");
  Serial.println(lum);

  // Préparation des données en vue de l'envoi
  String humidite = Akeru.toHex(hum);
  String temperature = Akeru.toHex(temp);
  String luminosite = Akeru.toHex(lum);
  String message = humidite + temperature + luminosite;

  // On envoie les données sur le réseau
  if(Akeru.sendPayload(message))
  {
    Serial.println("Message sent !");
  }

  delay(10000);
}

Paramétrage de la réception des données côté actoboard : comme précédemment.

C'est tout pour cette fois ! J'espère que ce tutoriel vous aura plu, et bonne bidouille en attendant le prochain !
"If it's itchy, scratch it !" - "DIY or die"

RTFM (À lire avant de poster) - ANDb (Arduino Noob Database)
Avatar de l’utilisateur
Laetitia
 
Messages: 296
Inscription: Mar 7 Aoû 2012 15:07
Localisation: Toulouse


Retourner vers Akeru et Akene

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité

cron