Tuto pas à pas C++ : utiliser un capteur d'humidité avec votre Gamebuino Meta

On va voir étape par étape comment utiliser le capteur d’humidité.

Le tuto est destiné à être réalisé avec le matériel fourni dans le pack d’accessoires Gamebuino

Pour ce tutoriel, il vous faut :

  • une console Gamebuino META
  • un capteur d’humidité du sol
  • un ordinateur avec l’environnement de développement l’IDE Aduino installé

Si ce n’est pas encore fait, reportez vous à la fiche
Premiers pas (C++ 1/5) : Installation rapide du logiciel - Gamebuino pour installer l’IDE Arduino.

Si vous savez déjà coder sans les roulettes, ou que vous ne vous sentez pas de suivre ce tuto pour une raison ou une autre vous pouvez trouver le code complet du programme réalisé ici dans le Mini-code : capteur d’humidité

Les branchements :

Capteur Backpack Couleur Description
AOUT A1 JAUNE Sortie de signal
VCC 3V3 ROUGE Alimentation
GND GND BRUN Masse


Etape 1 : bien commencer

Cette étape est identique sur la plupart des tutos car elle constitue la base indispensable de n’ilmporte quel programme pour Gamebuino.

Pour commencer, ouvrez l’éditeur Arduino préconfiguré pour la Gamebuino

-Vous devriez avoir ceci sur votre écran :

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}

Pour l’instant, le code est un peu vide, mais on va le compléter.

  • En premier lieu on a besoin d’ajouter au tout début du fichier la ligne suivante :
#include <Gamebuino-Meta.h>

C’est ce qu’on appelle une “librairie”, elle va nous permettre d’utiliser tout un tas de fonctions sans avoir à les programmer à la main. Cette librairie contient toutes les fonctions de la Gamebuino et est très utile pour la suite.
On va ajouter deux fonctions pour que notre programme puisse fonctionner :

  • Dans la fonction setup() on ajoute un appel à la fonction gb.begin() comme suit :
void setup() {
  // put your setup code here, to run once:
  gb.begin();
}

La fonction gb.begin() permet d’initialiser la console : sans cela rien ne fonctionnera !

void loop() {
  // put your main code here, to run repeatedly:
  while (!gb.update());
}

La fonction while(!gb.update()) permet de rafraichir le contenu de l’écran (c’est à dire dessiner dessus), gère la lecture des sons, les appuis sur les touches, bref tout ce qui donne vie à votre Gamebuino.

On a à présent une structure de programme fonctionnelle, même si elle ne fait encore rien de concret.

Etape 2 : récupérer la mesure du capteur d’humidité.

  • Pour cela on va déclarer une fonction get_sensor() comme ceci :
int get_sensor() {

}

Le capteur d’hummidité contient une carte électronique qui renvoie un signal analogique proportionnel à l’humidité. Pour lire cette mesure avec la Gamebuino, nous allons utiliser la fonction Arduino analogRead(). La fonction analogRead() permet d’utiliser le Convertisseur Analogique vers Numérique (CAN) du processeur qui va transformer une grandeur analogique (c’est à dire une mesure physique) en une valeur numérique entre 0 et 1023 compréhensible par le processeur.

  • Il faut indiquer à la fonction analogRead() sur quelle broche on désire lire la valeur : comme on a branché le capteur sur la broche A1, on va lire la valeur sur la broche A1 avec la fonction analogRead(A1) :
int get_sensor() {
  int i32_sensor_value = analogRead(A1); // lecture de l'entrée analogique A1
  return i32_sensor_value ;               // retourne la mesure 
}

Etape 3 : affichage de la valeur

  • On va créer une petite fonction d’affichage avec la librairie Gamebuino :
void  draw_sensor_output( int i32_value ) {
  gb.display.clear();
  gb.display.print( "mesure = " );  // affiche le texte "mesure = "
  gb.display.print( i32_value );    // affiche le contenu de la variable i32_value 
}

La fonction gb.display.clear() efface l’écran. Sans cela les images “s’empileraient” les unes sur les autres et deviendraient rapidement ilisibles.
La fonction gb.display.print() permet d’afficher une variable ou un texte à l’écran.

Notre fonction draw_sensor_output() permet d’afficher une ligne de texte et une valeur (de mesure).

Nous pouvons maintenant appeler nos deux fonctions get_sensor() et draw_sensor_output() dans la fonction principale loop(). Comme son nom l’indique, la fonction loop() est appelée indéfiniment en boucle.

void loop() {
  // put your main code here, to run repeatedly:
  while (!gb.update());
  int i32_value = get_sensor();  // on récupère la mesure du capteur
  draw_sensor_output( i32_value );        // on l'affiche à l'écran

De cette façon nos deux fonctions seront appelées et exécutées à chaque itération de notre fonction loop().

Compiler et téléverser notre programme vers la console affichera plus ou moins la chose suivante :

example03

On a maintenant une lecture continue de la valeur renvoyée par notre capteur. Seulement cette valeur n’est pas très claire. Ici on va avoir une valeur oscillant entre 0 et 1023, ce qui n’est pas vraiment parlant pour mesurer de l’humidité.

  • On va utiliser une petite formule mathématique pour modifier cette valeur en un pourcentage :
void loop() {
  // put your main code here, to run repeatedly:
  while (!gb.update());
  int i32_value = get_sensor();         // on récupère la mesure du capteur
  i32_value = (i32_value * 100) / 1023; // convertit la plage 0 à 1023 en 0 à 100 %
  draw_sensor_output( i32_value );                    // on affiche le pourcentage à l'écran

On a très facilement transformé la valeur analogique comprise entre 0 et 1023 en un pourcentage, ce qui est plus intuitif.

Dans les faits, notre capteur retourne une valeur plus élevée pour un environnement sec. Pour indiquer une humidité, on va ajouter un petit changement sur notre première variable i32_sensor_value.
Ceci permet de renvoyer une valeur plus élevée si l’humidité est plus élevée et inversement.

  • Pour régler ce petit souci c’est très simple, on inverse la valeur de retour en la soustrayant à sa valeur maximale :
int get_sensor() {
  int i32_sensor_value = analogRead(A1);       // lecture de l'entrée analogique A1 : entre 0 et 1023.
  i32_sensor_value = 1023 - i32_sensor_value ; // inverse la mesure.
  return i32_sensor_value ;               
}

Etape 4 : ajouter un visuel

Jusque là on a récupéré la valeur de notre capteur et on l’a transformée en un pourcentage qui sera plus simple à comprendre avant de l’afficher à l’écran. Pour rendre la chose encore plus claire on va ajouter une jauge qui se remplit en fonction de la valeur lue par notre capteur.
Cette partie va être très rapide mais apportera une plus value à notre programme pour un effort minimal, alors aucune raison de s’en priver.

  • Pour ça on va écrire une fonction draw_gauge() :
void draw_gauge( int i32_value ) {

}

Plutôt que d’utiliser des images complexes (ce qui fera l’objet d’autres tutos dans un avenir proche) on va utiliser les fonctions de base de la console, celles contenues dans notre librairie Gamebuino.h
Deux fonctions vont ici nous intéresser :
-La fonction drawRect() qui permet de dessiner les contours d’un rectangle
-La fonction fillRect() qui permet de dessiner un rectangle plein

  • On utilise ces deux fonctions à l’intérieur de notre fonction draw_gauge() de la manière suivante :
void draw_gauge( int i32_value ) {
  gb.display.drawRect(5, gb.display.height()-15, gb.display.width()- 10, 10);
  gb.display.fillRect(6, gb.display.height()-14, (i32_value * (gb.display.width()- 12)) / 100, 8);
}

On commence ici par dessiner un rectangle vide à 5 unités (ou pixels) du bord gauche de l’écran et à la hauteur de l’écran moins 15 unités. Sa largeur est la largeur de l’écran moins 10 unités et sa hauteur de 10 unités. On spécifie en fait la position du coin supérieur gauche du rectangle avec les deux premières valeurs et ses dimensions avec les deux dernières.

Ensuite on va dessiner un rectangle plein, on le décale d’une unité supplémentaire à partir du bord gauche pour qu’il ne dépasse pas sur le premier rectangle, sa position horizontale est donc de 6, et sa position verticale est également décalée d’une unité soit la hauteur de l’écran moins 14.
La partie la plus compliquée consiste à proportionner la longueur de ce rectangle à notre variable d’humidité. Pour cela on utilise une simple règle de 3 en multipliant la variable par la largeur de l’écran moins 12 (afin de ne pas dépasser du premier rectangle) et on divise le résultat par 100. Enfin on veut que la hauteur de notre rectangle soit de 8 unités, toujours pour ne pas dépasser du premier rectangle.

  • On doit maintenant appeler notre fonction draw_gauge() dans notre fonction loop() sans quoi elle ne sera jamais utilisée :
void loop() {
  // put your main code here, to run repeatedly:
  while (!gb.update());
  int i32_value = get_sensor();         // on récupère la mesure du capteur
  i32_value = (i32_value * 100) / 1023; // convertit la plage 0 à 1023 en 0 à 100 %
  draw_sensor_output( i32_value );      // on affiche le pourcentage à l'écran
  draw_gauge( i32_value );              // on affiche une jauge pour représenter notre valeur
  • Lancez une petite vérification de votre code et téléversez votre programme sur votre Gamebuino.
    Ca manque un peu de couleur non ?

example04

On va changer la couleur du rectangle plein pour qu’il soit plus facile de le différencier du premier qui lui sert de cadre. Et puis ça sera plus joli donc on ne va pas se priver.

  • Pour ça il suffit tout simplement d’intercaler entre le tracé de nos deux rectangles la fonction setColor() comme ceci :
void draw_gauge( int i32_value ) {
  gb.display.drawRect(5, gb.display.height()-15, gb.display.width()- 10, 10);
  gb.display.setColor(BLUE);
  gb.display.fillRect(6, gb.display.height()-14, (i32_value * (gb.display.width()- 12)) / 100, 8);
}

example05

Notez qu’ici j’utilise la couleur bleu en spécifiant à ma fonction setColor() le paramètre “BLUE”. Vous pouvez choisir une autre couleur si vous le souhaitez, la liste des couleurs est disponible sur l’API de la console en consultant la fonction setColor().

L’ensemble du code écrit jusqu’à présent devrait ressembler à peu près à ceci :

#include <Gamebuino-Meta.h>

void setup() {
  // put your setup code here, to run once:
  gb.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  while (!gb.update());
  int i32_value = get_sensor();         // on récupère la mesure du capteur
  i32_value = (i32_value * 100) / 1023; // convertit la plage 0 à 1023 en 0 à 100 %
  draw_sensor_output( i32_value );      // on l'affiche à l'écran
  draw_gauge( i32_value );              // on affiche une jauge pour représenter notre valeur
}

int get_sensor() {
  int i32_sensor_value = analogRead(A1);       // lecture de l'entrée analogique A1
  i32_sensor_value = 1023 - i32_sensor_value ; // inverse la mesure.
  return i32_sensor_value ;                    // retourne la mesure 
}

void  draw_sensor_output( int i32_value ) {
  gb.display.clear();
  gb.display.print( "mesure = " );  // affiche le texte "mesure = "
  gb.display.print( i32_value );    // affiche le contenu de la variable i32_value
}

void draw_gauge( int i32_value ) {
  gb.display.drawRect(5, gb.display.height()-15, gb.display.width()- 10, 10);
  gb.display.setColor(BLUE);
  gb.display.fillRect(6, gb.display.height()-14, (i32_value * (gb.display.width()- 12)) / 100, 8);
}

Vous avez à présent un petit programme parfaitement fonctionnel qui vous permet d’utiliser votre capteur d’humidité avec votre Gamebuino, pour prendre soin de vos plantes par exemple.

Les fonctions spécifiques de la Gamebuino sont documentées ici : Référence - Gamebuino

Bonjour Tom,

Il te manque juste comment brancher le capteur comme tu l’as expliqué sur ce post: Mini code : capteur d’humidité // Gamebuino Meta Bon c’est assez simple, le fil noir (GND) est à brancher sur le backpack sur la fiche GND (en bas à droite, partie POWER) et le fil rouge (VCC) sur la fiche du backpack 3V3. Enfin le fil jaune correspondant à AU0T correspond à la valeur mesurée. Il est à brancher sur la fiche A1 (Partie ANALOG)

Juste un autre petit truc. Dans la partie 5 tu as changé le nom des variables. Donc les utilisateurs peuvent simplement changer les déclaration des 2 entiers:

int32_t i32_raw_value;
int32_t i32_transformed_value;

par

int32_t i32_moisture_value;
int32_t i32_moisture_percent;

ou remplacer les variables dans les formules comme on préfère mais cela peut désorienter un débutant qui verrait apparaitre un message d’erreur en remplaçant la fonction sans cette modification.

//
// Demonstration programm for the moisture sensor
//
// available in accessory kit: 
// https://shop.gamebuino.com/fr/accessories/73-gamebuino-accessories-pack.html
// Programm shared by Tombuno here: 
// https://community.gamebuino.com/t/tuto-pas-a-pas-utiliser-un-capteur-dhumidite-avec-votre-gamebuino-meta
//
// Creation date: 04/2021

#include <Gamebuino-Meta.h>

#define SENSOR_PIN A1

int32_t i32_raw_value;
int32_t i32_transformed_value;

void setup() {
  // put your setup code here, to run once:
  gb.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  while (!gb.update());
  logic();
  draw();
}

void  logic(){
  i32_raw_value = 1023 - analogRead(SENSOR_PIN);
  i32_transformed_value = (i32_raw_value * 100) / 1023;
}

void  draw(){
  gb.display.clear();

  gb.display.print("sensor value = ");
  gb.display.print(i32_raw_value);
  gb.display.print("\nmoisture \% = ");
  gb.display.print(i32_transformed_value);
    gb.display.setColor(WHITE);
  gb.display.drawRect(5, gb.display.height()-15, gb.display.width()- 10, 10);
  gb.display.setColor(BLUE);
  gb.display.fillRect(6, gb.display.height()-14, (i32_transformed_value * (gb.display.width()- 12)) / 100, 8);
}

Merci de tes retours ^^.

On a apporté quelques modifications pour simplifier un peu le tuto. Tu as du tomber sur une version WIP un peu brouillonne. Je cherche une solution pour ajouter un petit visuel propre pour les branchements sur le backpack, les photos n’étant pas toujours bien lisible.

1 Like