Une Box Indispensable

Altimètre, Baromètre, Thermomètre, Accéléromètre, Niveau 3 axes et encore et encore

Accel vue

 

Eh bien, voici une petite boîte que l'on devrait trouver dans le sac à main de toutes les dames ! Rendez-vous compte que pour un billet 8,5 $ de matériel (Chinois bien sûr!) vous allez avoir une thermomètre, un baromètre, un altimètre, un niveau sur 3 axes (x longueur, y largeur, z verticalité), que même les maçons portugais n'ont pas ... Avec en plus : une accéléromètre 3 axes également, et 3 mesures d'écart 'accélération (très utile pour le transport de nitroglycérine ) .

La simplicité du montage est déconcertante ! Un module GY-88 qui inclut sur quelques cm² d'époxy un sensor BMP085 pour la mesure de la température, pression atmosphérique, et l'altitude, accessible par adressage I2C, ainsi qu'un capteur MPU6050 gyroscopique, magnétomètre et accéléromètre sur les 3 axes perpendiculaires, lui aussi accessible par une adresse de protocole I2C .

Accel gy88

Il ne reste plus qu'a y atteler un Arduino Nano pour faire le travail d'exploitation et un afficheur 2 lignes 8 caractères, rétro-éclairé, pour nous montrer le résultat ! Un bouton poussoir permet de passer successivement les menus et une mise en veille, pour l'économie de pile, est inclue dans les 3 derniers . Une pression sur le bouton ou une variation d'accélération, sortira le montage de sa léthargie .

Le tour de la propriété:

Le schéma:

Accel sch

 

Devant la facilité de mise en oeuvre des modules Arduno, je n'allais pas me prendre la tête à réinventer le monde ! et la puissance du Nano est largement suffisante pour gérer une ligne I2C, un afficheur et quelques entrées/sorties. Commençons par l'afficheur; les instructions et caractères sont envoyés sur quatre lignes de datas en 2 mots de 4 bits validés lors de la présence par l'entrée E et sélectionnés en "fonction" ou "caractère" par le changement d'état de la ligne de pilotage RS. Le contraste est ajusté par une résistance variable de 10k (R5) qui vient polariser la broche VO du display. Les Leds du rétro-éclairage son limitées en courant par une résistance (R3) ; ici 470 ohms mais qui peut varier en fonction de la référence de l'afficheur . Ce rétro-éclairage passe par un transistor 2N2222 piloté en PWM (modulation de largeur d'impulsions) pour régler, atténuer ou couper  son éclairement en économie de piles. La base du 2N2222 est limitée en courant par la résistance de 22k (R4). Voila pour l'affichage.

Le bouton S2 permet de se déplacer dans les menus par pressions successives. Une résistance de pull down de 47k (R2) est ajouté pour ne pas laisser l'entrée 'en l'air' au repos. Rien n'empêche d'utiliser la résistance interne de l'Arduino (INPUT_PULLUP) en inversant la référence du commun bouton, mais je ne l'ai pas fait car j'envisageait de remplacer le bouton par une photo-résistance, occultée par le doigt, et cela nécessitait de pouvoir ajuster la valeur du pull down....

Le module GY-88 est alimenté sous 3,3 Volts par le régulateur intégré de l'arduino; pourquoi s'en priver. La communication I2C est assuré par les lignes standards SDA/SCL et les résistances de tirage du bus sont inclues sur le module ; génial, non ? Les adresses des accès sont utilisées dans les 'librarys' de l'asservissement du composant à l'Arduino ; Hé ben comme ça c'est fait, hein ?

 

Le Circuit Imprimé & l'Implantation des Composant :

Accel cmp

 

Accel brd

 

Les composants sont, pour beaucoup, de types CMS, donc implantés côté 'cuivre'... Un bon éclairage, des lunettes loupes, un fer à souder fin, des brucelles de qualité et un petit coup de vin blanc pour ceux qui tremblent et la soudure des CMS ne pose pas trop de problèmes . On étame une pad, on approche le composant à la brucelles et on soude le premier bout; quand c'est refroidi, demi tour à l'horizontal du circuit et on soude l'(es) autre(s) pinuche(s) .

Dès que les CMS sont soudés, ne pas oublier les deux straps sous l'afficheur ! quand le display est soudé c'est trop tard ! (Ces deux straps permettent de nous affranchir d'un circuit double faces ) Puis on soude le reste des composants ...

 

Accel print

(Ne faites pas comme moi sur le circuit, où le trait de scie s'approche exagérément du bord gauche ! Grrrrrrr....)

 

 

Le Sketch : (puisque l'on appelle ainsi les programmes sous Arduino)

Le gros avantage de l'Open Source, c'est que l'on a pas à réinventer le monde à chaque fois ! il existe des librarys de composants développées et disponibles sur le réseau, et il n'y a qu'a les télécharger pour s'en servir : elle n'est pas belle la vie ?

Je ne vais pas trop m'étendre sur le descriptif du sketch  puisque qu'il est abondamment commenté !  (presque trop).

 

 

/* Thermomètre, baromètre, Altimètre, Inclinomètre, accéléromètre

 *  avec module Arduino Nano, Accéléromètre GY88 et LCD 2lignes x 8Caractères.

 *  B.LECLERC 08/17

 */

#include <LiquidCrystal.h> //Library du LCD

#include <Adafruit_BMP085.h> //Library de thermomètre et baromètre

#include <MPU6050.h> //Library de l'accéléromètre et gyroscope

 

Adafruit_BMP085 bmp; //Déclaration Data du baromètre

MPU6050 accelgyro; //Déclaration Data accéléromètre & gyroscope

 

int16_t ax, ay, az; //Variables accéléromètre

int16_t gx, gy, gz;

 

 

int mx; //Mémorisation de la valeur accélération x,y,z

int my;

int mz;

int dx; //Mémorisation du delta entre ancienne mesure et nouvelle mesure d'accélération x,y,z

int dy;

int dz;

int n; //Compteur de boucle

int mesure = 13; //Déclaration de la Led rouge de l'arduino pendant la mesure

int led = 6; // LED du rétro-éclairage du LCD connectée à la sortie digitale pin 6

int button = 7; // Bouton connecté à l'entrée digitale pin 7

 

//Déclarations et fonctions des pin de connexion du LCD

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

 

void setup() {

  pinMode(led, OUTPUT); //Rétro-éclairage en sortie

  pinMode(mesure, OUTPUT); //Led de mesure en sortie

  pinMode (button, INPUT); //Bouton en entrée dans pull up par arduino

 

  //Initialisation de l'accéléromètre

     accelgyro.initialize();

    

  // Défini les colonnes et rangées du LCD 

    lcd.begin(8, 2);

  // Allume le rétro-éclairage

    digitalWrite(led, HIGH);  

  // Message d'accueil sur la 1°ligne

    lcd.print(" Nanard ");

  // positionne le curseur colonne 0, ligne 1

    lcd.setCursor(1, 1);

  // Ecrit le message sur la ligne du bas du LCD 

    lcd.print("08/17");

    delay (1000);  //Pause de 1"

 

 

  //Initialisation du BMP085 pour toujours

    if (!bmp.begin()) {

  while (1) {}

  }

}

 

 

void loop() {

  digitalWrite(led, HIGH);   // Allume le rétro-éclairage

/* Acquisition et affichage de la température ambiante par le module BMP085

 *  La première mesure est la plus vraie, car le module s'échauffe et la température

 *  à tendance à s'élever...

 */

  Temp:

    lcd.setCursor(0,0);// positionne le curseur colonne 0, ligne 0

      lcd.print("Temp =   ");// Message d'entête sur la 1°ligne

        lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

          digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

        lcd.print(bmp.readTemperature(),1);// Mesure de la température et affichage à 1 décimale après la virgule

      digitalWrite(mesure,LOW);// Eteind la led 13 pour marquer la fin de mesure

    lcd.print(" *C  ");//Affichage de l'unité (* a la place de ° car non reconnu)

  delay (2000);//Pause de 2"

  if (digitalRead(button)) { // lit l'état du bouton

    goto Press; // Et passe au menu suivant si actif

  }

  goto Temp; //On boucle avec le début du menu si pas d'action sur le bouton

 

 

/* Acquisition et affichage de la Pression atmosphérique par le module BMP085

 *  Le baromètre affiche la pression en Pascal (Pa)! une haute pression garanti du beau temps

 *  Et une basse pression, une dégradation en cours ...

 */

Press:

  lcd.setCursor(0,0);// positionne le curseur colonne 0, ligne 0

    lcd.print("P.Atmo. ");// Message d'entête sur la 1°ligne

      lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

        digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

      lcd.print(bmp.readPressure());// Mesure de la pression atmosphérique et affichage

    digitalWrite(mesure,LOW);// Eteint la led 13 pour marquer la fin de mesure

  lcd.print(" Pa   ");//Affichage de l'unité

delay (2000);//Pause de 2"

  if (digitalRead(button)) { // lit l'état du bouton

    goto Alti; // Et passe au menu suivant si actif

  }

goto Press; //On boucle avec le début du menu si pas d'action sur le bouton

 

 

/* Acquisition et affichage de l'altitude du lieu par le module BMP085

 *  L'Altimètre affiche la hauteur du lieu au dessus du niveau de la mer!

 *  L'altitude est affichée en mètres ...

 */

Alti:

  lcd.setCursor(0,0);// positionne le curseur colonne 0, ligne 0

    lcd.print("Altitude");// Message d'entête sur la 1°ligne

      lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

        digitalWrite(mesure,HIGH); // Allume la led 13 pour marquer la mesure

      lcd.print(bmp.readAltitude(),0);// Mesure de l'Altitude et affichage

    digitalWrite(mesure,LOW);// Eteint la led 13 pour marquer la fin de mesure

  lcd.print(" Mtr   ");//Affichage de l'unité

delay (2000);//Pause de 2"

  if (digitalRead(button)) { // lit l'état du bouton

      lcd.clear();// effacement du LCD

    lcd.print("Horizon.: ");// Message d'entête sur la 1°ligne

    goto Hori_x;  // Et passe au menu suivant si actif

  }

goto Alti;//On boucle avec le début du menu si pas d'action sur le bouton

 

 

/* Acquisition et affichage d'une variation d'horizon dans le sens de la longueur

 * La variation est notée en positif ou négatif suivant le sens

 */

Hori_x:

      digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

        accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);// Acquisition des 6 valeurs

      digitalWrite(mesure,LOW);// Eteint la led 13 pour marquer la fin de mesure

     lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

   lcd.print(ax/185);lcd.print(" x   ");//Affichage de la mesure et de l'axe

  delay (500); //Pause de 1/2"

if (digitalRead(button)) { // lit l'état du bouton

  goto Hori_y; // Et passe au menu suivant si actif

  }

goto Hori_x;//On boucle avec le début du menu si pas d'action sur le bouton

 

 

/* Acquisition et affichage variation d'horizon dans le sens de la largeur du boitier

 * La variation est notée en positif ou négatif suivant l'inclinaison par rapport à l'horizon

 * Une grande précision mécanique assure des mesures plus précises ...

 */

Hori_y:

      digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

        accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);// Acquisition des 6 valeurs

      digitalWrite(mesure,LOW);// Eteint la led 13 pour marquer la fin de mesure

    lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

  lcd.print(ay/184);lcd.print(" y   ");//Affichage de la mesure et de l'axe

  delay (500); //Pause de 1/2"

if (digitalRead(button)) { // lit l'état du bouton

  goto Hori_z;  // Et passe au menu suivant si actif

  }

goto Hori_y;//On boucle avec le début du menu si pas d'action sur le bouton

 

 

/* Acquisition et affichage variation d'inclinaison dans le sens de la verticalité du boitier

 * La variation est notée en positif ou négatif suivant l'inclinaison par rapport à l'axe vertical

 * Une grande précision mécanique assure des mesures plus précises ...

 */

Hori_z:

      digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

        accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);// Acquisition des 6 valeurs

      digitalWrite(mesure,LOW);// Eteind la led 13 pour marquer la fin de mesure

    lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

  lcd.print(az/167);lcd.print(" z    ");//Affichage de la mesure et de l'axe

  delay (500); //Pause de 1/2"

if (digitalRead(button)) { // lit l'état du bouton

  lcd.clear();// effacement du LCD

  lcd.print("Accel.: ");// Message d'entête sur la 1°ligne

    goto Accel_x;  // Et passe au menu suivant si actif

  }

goto Hori_z;//On boucle avec le début du menu si pas d'action sur le bouton

 

 

 

/* Aquisition et affichage variation Gyroscopique dans l'axe de la longueur du boitier

 * La variation est notée en positif ou négatif

 * La mesure est effectuée deux fois par seconde ...

 */

Accel_x:

    lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

      digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

        accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);// Acquisition des 6 valeurs

      digitalWrite(mesure,LOW);// Eteint la led 13 pour marquer la fin de mesure

    lcd.print(gx);lcd.print(" x    ");//Affichage de la mesure et de l'axe

  delay (500); //Pause de 1/2"

if (digitalRead(button)) { // lit l'état du bouton

  goto Accel_y;  // Et passe au menu suivant si actif

}

goto Accel_x;//On boucle avec le début du menu si pas d'action sur le bouton

 

 

/* Aquisition et affichage variation Gyroscopique dans l'axe de la largeur du boitier

 * La variation est notée en positif ou négatif

 * La mesure est effectuée deux fois par seconde ...

 */

Accel_y:

    lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

      digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

        accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);// Acquisition des 6 valeurs

      digitalWrite(mesure,LOW);// Eteint la led 13 pour marquer la fin de mesure

    lcd.print(gy);lcd.print(" y    ");//Affichage de la mesure

  delay (500); //Pause de 1/2"

if (digitalRead(button)) { // lit l'état du bouton

  goto Accel_z;  // Et passe au menu suivant si actif

}

goto Accel_y;//On boucle avec le début du menu si pas d'action sur le bouton

 

 

 

/* Aquisition et affichage variation Gyroscopique dans l'axe de la hauteur du boitier

 * La variation est notée en positif ou négatif

 * La mesure est effectuée deux fois par seconde ...

 */

Accel_z:

    lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

      digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

        accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);// Acquisition des 6 valeurs

      digitalWrite(mesure,LOW);// Eteint la led 13 pour marquer la fin de mesure

    lcd.print(gz);lcd.print(" z    ");//Affichage de la mesure et de l'axe

  delay (500); //Pause de 1/2"

if (digitalRead(button)) { // lit l'état du bouton

  lcd.clear();// effacement du LCD

    lcd.print("Delta:  ");// Message d'entête sur la 1°ligne

  goto Delta_x; // Et passe au menu suivant si actif

}

goto Accel_z;//On boucle avec le début du menu si pas d'action sur le bouton

 

 

/* Acquisition et affichage de la différence de valeur entre la dernière mesure

 *  et la nouvelle dans l'axe de la longueur du boitier

 * La variation est notée en positif ou négatif

 * La mesure est effectuée une fois par seconde ...

 */

Delta_x:

n = n + 1; //Incrémentation du nombre de boucle

  mx = gx;//Recopie de la valeur en vue du stockage

    digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

      accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);// Acquisition des 6 valeurs

        digitalWrite(mesure,LOW);// Eteint la led 13 pour marquer la fin de mesure

          dx = gx - mx;// Soustraction de la nouvelle valeur de l'ancienne valeur

        if ((dx > 30)or (dx < -30)) { // Affichage si et seulement si la variation est suffisante

      lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

    lcd.print(dx);lcd.print(" x    ");//Affichage de la différence

  }

delay (500); //Pause de 1/2"

  if (digitalRead(button)) { // lit l'état du bouton

    n = 0; //RaZ de la boucle si bouton....

    goto Delta_y; // Et passe au menu suivant si actif

  }

  if (n > 100) {//Si la boucle atteint les 100 on met en veille

    goto Veille;

  }

  if ((gx > 2000) or (gy > 700) or (gz > 800) ) { (n = 0); } //RaZ de la boucle si mouvement !

goto Delta_x;//On boucle avec le début du menu si pas d'action sur le bouton

 

 

 

/* Aquisition et affichage de la différence de valeur entre la dernière mesure

 *  et la nouvelle dans l'axe de la largeur du boitier

 * La variation est notée en positif ou négatif

 * La mesure est effectuée deux fois par seconde ...

 */

 Delta_y:

 n = n + 1; //Incrémentation du nombre de boucle

  my = gy;//Recopie de la valeur en vue du stockage

    digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

      accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);// Acquisition des 6 valeurs

        digitalWrite(mesure,LOW);// Eteint la led 13 pour marquer la fin de mesure

          dy = gy - my;// Soustraction de la nouvelle valeur de l'ancienne valeur

        if ((dy > 30)or (dy < -30)) {// Affichage si et seulement si la variation est suffisante

      lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

    lcd.print(dy);lcd.print(" y    ");//Affichage de la différence

  }

delay (500); //Pause de 1/2"

   if (digitalRead(button)) { // lit l'état du bouton

    n = 0; //RaZ de la boucle si bouton ....

    goto Delta_z;  // Et passe au menu suivant si actif

  }

  if (n > 100) {//Si la boucle atteint les 100 on met en veille

    goto Veille;

  }

  if ((gx > 2000) or (gy > 700) or (gz > 800) ) { (n = 0); }  //RaZ de la boucle si  mouvement  !

goto Delta_y;//On boucle avec le début du menu si pas d'action sur le bouton

 

 

 

/* Acquisition et affichage de la différence de valeur entre la dernière mesure

 *  et la nouvelle dans l'axe de la hauteur du boitier

 * La variation est notée en positif ou négatif

 * La mesure est effectuée deux fois par seconde ...

 */

Delta_z:

n = n + 1; //Incrémentation du nombre de boucle

  mz = gz;//Recopie de la valeur en vue du stockage

    digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

      accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);// Acquisition des 6 valeurs

        digitalWrite(mesure,LOW);// Eteint la led 13 pour marquer la fin de mesure

          dz = gz - mz;// Soustraction de la nouvelle valeur de l'ancienne valeur

        if ((dz > 30)or (dz < -30)) {// Affichage si et seulement si la variation est suffisante

      lcd.setCursor(0, 1);// positionne le curseur colonne 0, ligne 1

    lcd.print(dz);lcd.print(" z    ");//Affichage de la différence

  }

delay (500); //Pause de 1/2"

  if (digitalRead(button)) { // lit l'état du bouton

    n = 0; //RaZ de la boucle si bouton....

    goto Temp;  // Et passe au menu suivant si actif

  }

  if (n > 100) { //Si la boucle atteint les 100 on met en veille

    goto Veille;

  }

if ((gx > 2000) or (gy > 700) or (gz > 800) ) { (n = 0); }  //RaZ de la boucle si mouvement....  !

goto Delta_z;//On boucle avec le début du menu si pas d'action sur le bouton

  

 

/* Extinction du rétro éclairage pour réduire la consommation

 *  et retour au début si le bouton est sollicité

 *  ou si un mouvement est reçu.

 */

Veille:

  digitalWrite(led, LOW);   // éteind le rétro-éclairage .

    delay (500);//Pause de 1/2"

        digitalWrite(mesure,HIGH);// Allume la led 13 pour marquer la mesure

          accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);// Acquisition des 6 valeurs

        digitalWrite(mesure,LOW);// Eteint la led 13 pour marquer la fin de mesure

if (((digitalRead(button)) or (gx > 2000) or (gy > 700) or (gz > 800) )) { // lit l'état du bouton et du mouvement

  digitalWrite(led, HIGH);   // sets the LED on

    n = 0; //RaZ de la boucle si bouton ou mouvement....  

  goto Temp;  // Et passe au début suivant si actif

}

  delay (2000);//Pause de 2"

  goto Veille;//On boucle avec le début du menu si pas d'action sur le bouton

}

 

C'en est terminé de la partie programme; il reste ouvert à toutes personnalisations, compléments, ou autres fonctions . je vais mettre un allumage et extinction progressif sur le rétro-éclairage de l'afficheur de mon prototype !

Le programme est inclus dans le fichier zippé plus bas dans la page .

 

 

 

Et pour conclure :

Accel side

Voici le circuit terminé prêt à être inclus dans un boîtier helland . Pour fignoler la précision de l'horizon dans le sens de la longueur (x), on peut mettre une vis vérin en plastique de 3 mm dans le trou du GY-88 ... Tout en restant modéré sur le flexion afin de ne pas imposer des contraintes hors normes aux soudures des composants .

Accel vis rgl

 

Les fichiers pour la réalisation sont Zippés ci-dessous: Les schémas et circuit imprimés sous format Eagle de Cadsoft et le programme sous Arduino.

AccelAccel (27.86 Ko)

 

Accel hori

Ajouter un commentaire