Une Girouette Arduino Basique

nous allons voir ici le principe de réalisation d’une girouette Arduino basique.

l’idée est de combiner l’utilisation d’un codage type CODE GRAY avec des diodes émettrice/réceptrices infrarouge.

sur la base de 4 couples de diodes , on a un codage sur 16 secteurs soit une position angulaire tous les 22,5 ° ce qui est déjà tres largement suffisant pour une girouette de station météo basique DIY.

concernant le codage GRAY , voici le schéma du codeur utilisé , il diffère de celui trouvé sur WIKIPEDIA parce qu’il permet d’avoir un calcul simple de l’angle correspondant en fonction des valeurs “binaires” combinées (voir plus bas dans le pgme C++) en utilisant le principe de décomposition binaire <=> décimal ( dans le programme plus bas, le résultat est arrondi a l’entier sans la décimale) .

voici le tableau binaire correspondant avec en partie basse la valeur décimale correspondant:

pour la réalisation, il aurait été possible d’utiliser des bloc OPB704 ( voir ici ) mais pour rendre le montage plus pratique , une roue codeuse imprimée 3D a été réalisée pour utiliser directement des diodes émettrices et réceptrices. l’idée c’est d’intégrer le codeur GRAY dans le plateau supérieur et de coller derrière une feuille de papier alu de cuisine comme réflecteur .

le programme ARDUINO:

cette version permet un affichage de l’angle directement sur ecran LCD I2C:

# include <Wire.h>
# include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);

void setup() { 
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  Serial.begin(9600); 
  lcd.init();
  lcd.backlight(); 
}

void loop() {
  int x1 = digitalRead(2);
  int x2 = digitalRead(3);
  int x3 = digitalRead(4);
  int x4 = digitalRead(5);
  int A = 360 -((x1*8 + x2*4 + x3*2 + x4)*22.5);
  lcd.clear() ;
  lcd.setCursor(9,1);
  lcd.print(A);
  delay (50);   
}

et pour conclure ce petit tuto , une petite video de démo:

STATION METEO Arduino basique

petit montage a base d’ ARDUINO pour faire une station météo avec 3 fonctions basiques: température , pression et hygrométrie et une fonction d’enregistrement des données sur carte SD.

MATERIEL:

  • un Arduino Uno
  • un SD RTC shield (DeekRobot ou Adafruit)
  • une carte SD
  • un module DHT 22
  • un module BMP280
  • alimentation par pile 9V et cordon jack

SD RTC SHIELD:

sa fonction est de proposer sur un shield les fonctions lecture/écriture sur carte SD ainsi qu’une horloge temps réelle a pile de sauvegarde. cette carte a été abordée de façon plus détaillée ici .

le module DHT 22

c’est le même type de module que le DHT11 utilisé en exemple dans la rubrique ARDUINO SD RTC shiel mais avec des caractéristiques plus performantes ( plage de température et précision). comme le DHT 11 , il délivre la température et l’hygrométrie

le module BMP280

le module BMP280 délivre lui 2 informations ; une température et une pression

CABLAGE

broche out du DHT22 sur la broche 2 de l’arduino et Vcc et GND sur 5V et GND arduino

pour le BMP280, nous allons l’utiliser en mode I2C . il faut donc brancher GND et Vcc sur GND et 5V arduino et SCL et SDA du BMP280 sur les broche SCL et SDA de l’arduino uno . l’arduino UNO possede 2 paires de broches I2C ( SCL + SDA)=> voir le pinout ICI

le SD RTC shield doit etre “pluggué” sur l’arduino UNO puis les 2 composants (DHT22 et BMP280) ainsi que la pile reliés a l’UNO ( le SD shield n’est pas représenté sur le schéma fritzing ci dessus) : pour le DHT22 et le BMP280 , utiliser une petite platine proto .

NOTA: attention, une pile type 9V ne permet un fonctionnement que de quelques heures. pour une station météo d’observatoire , il faudra soit une alim secteur soit une alim batterie sur panneau solaire.

PROGRAMME ARDUINO

le programme est un “melting-pot” de plusieurs programmes d’exemples joints avec les différentes librairies utilisées.

très synthétiquement, on charge les différentes librairies nécessaires ( wire.h pour l’I2C, SPI.h pour le lecteur SD, SD.h pour l’utilisation de la carte SD, RTClib.h pour l’horloge temps réel, Adafruit_BMP.h pour le BMP280, DHT.H pour le DHT22), puis on defini quelques constante et brochage . le programme void setup lance les differentes fonctions et parametres liées aux librairies, la boucle “void loop” lit les données des capteurs et les stocke dans des variables ainsi que année, mois, jour et heures/minutes/secondes de l’horloge RTC.

pour la temperature , on recuperer les 2 temperatures t1 et t2 des 2 capteurs et on calcule la moyenne des 2 => ligne ” tm = (t1+t2)/2

une serie de parametres “filename[x] permet de definir chaque caractère du nom de fichier d’enregistrement des données => un fichier par jour de l’année suivant la syntaxe : année mois jour. puis le fichier est ouvert , les données enregistrées dedans sous forme string CSV et le fichier est refermé , le programme attends 60 secondes puis recommence => un enregistrement de données toutes les minutes.

#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <RTClib.h>
#include <Adafruit_BMP280.h>
#include "DHT.h"
const int chipSelect = 10;
#define DHTPIN 2 
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 RTC;
Adafruit_BMP280 bmp; // I2C

char filename [] = "00000000.CSV";

void setup() {
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  // ligne suivante pour initialiser l'heure du RTC/PC  la premiere fois 
  // decocher les // , telecharger , puis remettre les // 
  // RTC.adjust(DateTime(__DATE__, __TIME__));
  dht.begin();
  bmp.begin(); 
   /* config par defaut suivant datasheet */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     
                  Adafruit_BMP280::SAMPLING_X2,     
                  Adafruit_BMP280::SAMPLING_X16,    
                  Adafruit_BMP280::FILTER_X16,     
                  Adafruit_BMP280::STANDBY_MS_500); 
  SD.begin(chipSelect);               
}

void loop() { 
  float h = dht.readHumidity();
  float t1 = dht.readTemperature();
  float t2 = bmp.readTemperature();
  float p = bmp.readPressure();
  float  tm = (t1+t2)/2 ;   
  DateTime now = RTC.now();
  uint16_t year1 = now.year();
  uint16_t month1 = now.month();
  uint16_t day1 = now.day();
  uint16_t hour1 = now.hour();
  uint16_t minute1 = now.minute();
  uint16_t second1 = now.second();
  filename[0] = (year1/1000)%10 + '0';
  filename[1] = (year1/100)%10 + '0';
  filename[2] = (year1/10)%10 + '0';
  filename[3] = (year1)%10 + '0';
  filename[4] = month1/10 + '0'; 
  filename[5] = (month1)%10 + '0'; 
  filename[6] = day1/10 + '0'; 
  filename[7] = (day1)%10 + '0';
  filename[8] = '.';
  filename[9] = 'c';
  filename[10] ='s';
  filename[11] ='v';
  File dataFile = SD.open(filename, FILE_WRITE);
  String dataReg = String(year1) + "/" + String( month1) + "/" + String(day1) +";" + String(hour1) + ":"+ String(minute1) + ":" + String(second1) + ";" + String(tm) + ";" + String(h) + ";" + String(p) + ";" ; 
  dataFile.println(dataReg);
  dataFile.close();
  delay(60000);
}

voici un exemple de données enregistrées:

fichier CSV ouvert avec wordpad: date ; heure ; température ; humidité ; pression (en pascals)

le même fichier CSV ouvert avec LibreOffice ou Excel , l’enregistrement avec des “;” séparant les paquets de données permet de récupérer chaque paquet dans une colonne différente sur le tableur.

AMELIORATION

nous allons améliorer la station météo en ajoutant un écran LCD I2C 4 lignes de 20 caractères pour y afficher , date et heure sur la première ligne, température sur la deuxième ligne , humidité et pression sur la troisième ligne. la quatrième ligne est en réserve pour la vitesse et la direction du vent .

le schéma de câblage avec l’écran I2C devient:

le programme deviens (évolutions en bleu):

#include <Wire.h>
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>
#include <RTClib.h>
#include <Adafruit_BMP280.h>
#include "DHT.h"
const int chipSelect = 10;
#define DHTPIN 2 
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 RTC;
Adafruit_BMP280 bmp; // I2C
LiquidCrystal_I2C lcd(0x27,20,4);
char filename [] = "00000000.CSV";
void setup() {
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  Wire.begin();
  RTC.begin();
  // ligne suivante pour initialiser l'heure du RTC/PC  la premiere fois 
  // decocher les // , telecharger , puis remettre les // 
  // RTC.adjust(DateTime(__DATE__, __TIME__));
  dht.begin();
  bmp.begin(); 
   /* config par defaut suivant datasheet */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     
                  Adafruit_BMP280::SAMPLING_X2,     
                  Adafruit_BMP280::SAMPLING_X16,    
                  Adafruit_BMP280::FILTER_X16,     
                  Adafruit_BMP280::STANDBY_MS_500); 
  SD.begin(chipSelect);               
}
void loop() { 
  float h = dht.readHumidity();
  float t1 = dht.readTemperature();
  float t2 = bmp.readTemperature();
  float p = bmp.readPressure();
  float tm = (t1+t2)/2;  
  DateTime now = RTC.now();
  uint16_t year1 = now.year();
  uint16_t month1 = now.month();
  uint16_t day1 = now.day();
  uint16_t hour1 = now.hour();
  uint16_t minute1 = now.minute();
  uint16_t second1 = now.second();
  filename[0] = (year1/1000)%10 + '0';
  filename[1] = (year1/100)%10 + '0';
  filename[2] = (year1/10)%10 + '0';
  filename[3] = (year1)%10 + '0';
  filename[4] = month1/10 + '0'; 
  filename[5] = (month1)%10 + '0'; 
  filename[6] = day1/10 + '0'; 
  filename[7] = (day1)%10 + '0';
  filename[8] = '.';
  filename[9] = 'c';
  filename[10] ='s';
  filename[11] ='v';  
  String date = String(day1) + "/" + String(month1) + "/" + String(year1);
  String time = String(hour1) + ":" + String(minute1) + ":" + String(second1);
  lcd.setCursor(0,0);
  lcd.print(date) ;
  lcd.setCursor(11,0);
  lcd.print(time) ;
  lcd.setCursor(7,1);
  lcd.print(tm) ; 
  lcd.setCursor(12,1);
  lcd.print(char(223)) ;
  lcd.setCursor(13,1);
  lcd.print("C") ;     
  lcd.setCursor(0,2);
  lcd.print(h) ;
  lcd.setCursor(5,2);
  lcd.print("%Hu") ; 
  int roundp =  int(p);
  lcd.setCursor(9,2);
  lcd.print(p) ;
  lcd.setCursor(18,2);
  lcd.print("Pa") ;  
  File dataFile = SD.open(filename, FILE_WRITE);
  String dataReg = String(year1) + "/" + String( month1) + "/" + String(day1) +";" + String(hour1) + ":"+ String(minute1) + ":" + String(second1) + ";" + String(tm) + ";" + String(h) + ";" + String(p) + ";" ; 
  dataFile.println(dataReg);
  dataFile.close();
  delay(60000);
}

et visuellement , le montage fini en fonctionnement , ressemble a cela:

la version finale de la station integrera un anemometre et une girouette

pour rendre la station autonome , elle sera alimentée par un panneau solaire 12V – 5 watts alimentant une batterie 12V.

STATION METEO SERVEUR

une station météo ARDUINO en réseau privé via votre BOX c’est possible avec un Ethernet Shield . nous allons voir comment.

le tuto est basé sur l’utilisation d’un Shield ethernet Keyestudio mais le principe est le même avec d’autre shield Ethernet. l’avantage du shield Keyestudio est qu’il comporte en plus un slot pour carte micros SD. outre la transmission Ethernet des données, il sera donc également possible de les sauvegarder sur carte micro SD.

petit problème global avec les Shield Ethernet , contrairement au shiel SD , ils n’ont pas d’Horloge RTC intégrée , il va donc falloir en ajouter une. dans ce tuto , on utilisera un module TinyRTC I2C. mais tout autre module RTC peut convenir.

par ailleurs , nous allons profiter de ce module pour notre premier exemple de transmission de données via câble réseau Ethernet en affichant tout simplement la date et l’heure récupérée sur le module dans une page de navigateur .

LE MONTAGE :

pas besoin de schéma fritzing , ici la connexion est simple , on relie les broche Vcc et GND du module RTC aux borches GND et 5V de l’arduino uno et les broches SCL et SDA respectivement au broche Analogiques A5 et A4 de l’Arduino UNO.

LE PROGRAMME :

#include <SPI.h>
#include <Ethernet.h>
#include "RTClib.h"
RTC_DS1307 rtc;
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 15);
EthernetServer server(80);

void setup() {
  rtc.begin();
  SPI.begin();
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop() {  
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
          DateTime time = rtc.now();
          client.print("DATE: ");
          client.println(time.timestamp(DateTime::TIMESTAMP_DATE));
          client.print("TIME: ");
          client.println(time.timestamp(DateTime::TIMESTAMP_TIME));
          break;
     }
    delay(100);
    client.stop();
  }
}

les librairies sont standard , si pas disponibles dans votre IDE , une petite recherche internet vous permettra de les récupérer. en début de programme , via les instruction byte mac[] et IPadress on fixe l’adresse Mac et l’adresse IP du shield ( a modifier suivant les données de votre Box internet) . ensuite la partie void setup , démarre les librairies , et la partie void loop ouvre le serveur puis la boucle while exécute les lignes suivantes tant que la connexion est OK . dans la boucle on lit les données date et heure du module TinyRTC puis on les imprime sur le serveur client via une instruction type “client.print() “

ne reste plus qu’a lire tout ça a l’adresse IP avec un navigateur Web . pas très compliqué , ouvrir votre navigateur préféré et tapez l’adresse IP (ici 192.168.1.15) et vous devriez voir apparaitre quelque chose comme ci dessous:

bien entendu , si vous utilisez votre smartphone connecté en WIFI a votre réseau domestique, ça marche aussi avec l’explorateur web du smartphone.

le problème avec l’affichage obtenu c’est que la structure est extrêmement minimale et surtout la page ne se régénère pas automatiquement , il faut la régénère à la main pour voire l’heure évoluer.

nous allons donc mettre en place une page web basique en HTML avec régénération automatique. et rajouter des test pour la connexion. le programme plus bas est une modification pure et simple d’un programme exemple livré avec la bibliothèque “Ethernet.h” que l’on trouve sous l’IDE ARDUINO dans le chemin:

Fichier/example/Ethernet/Webserver

STRUCTURE MINIMALE D’UNE PAGE HTML

première chose a intégrer , la structure minimale standard obligatoire d’une page web en HTML . ci dessous un petit schéma qui montre les éléments (balises) constitutifs d’une page web standard minimale.

  • <!DOCTYPE html> est la balise qui précise le langage utilisé .
  • <html> est la balise délimite le début la zone de contenu html
  • </html> est la balise qui symbolise la fin de la zone html
  • a l’intérieur de cette zone html , on va trouver deux types de balises:
  • <head> et </head> pour définir debut et fin de la zone des données d’entête
  • <body> et</body> qui délimitent la zone de texte (corps) de la page web

la zone d’entête doit comporter le titre de la page entre les balises <title> et </title>

et le type d’encodage utilisé ici <meta charset=”utf-8″>

petite particularité , sous C++ ARDUINO , concernant la rédaction, il faudra écrire:

<meta charset=\”utf-8\”> </meta>

pour demander la régénération de la page , il faudra insérer Refresh: x avec X le temps de rafraichissement.

passons au programme modifié avec en violet les rajouts par rapport au programme initial .

#include <SPI.h>
#include <Ethernet.h>
#include "RTClib.h"
RTC_DS1307 rtc;
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 15);
EthernetServer server(80);

void setup() {
  rtc.begin();
  SPI.begin();
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop() {  
  EthernetClient client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // cloture connexion
          client.println("Refresh: 10");  // rafraichissement de page toute les 10s
          client.println();
          client.println("<!DOCTYPE HTML>");  // specifie le type de document=HTML
          client.println("<html>");  // debut de la page
              client.println("<head>");
                  client.println("<meta charset=\"utf-8\"></meta>"); //encodage page
                  client.println("<title>METEO LOCALE</title>");  // titre de la page
              client.println("</head>");
              client.println("<body>"); // debut de zone du contenu visible
                    DateTime time = rtc.now();
                    client.print("DATE: ");
                    client.print(time.timestamp(DateTime::TIMESTAMP_DATE));
                    client.print("  TIME: ");
                    client.print(time.timestamp(DateTime::TIMESTAMP_TIME));
              client.println("</body>"); // fin de zone du contenu 
          client.println("</html>");   // fin de la page         
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1000);
    // close the connection:
    client.stop();
  }
}

une fois le programme déversé dans l’arduino , si l’on ouvre le navigateur et que l’on saisi l’adresse 192.168.1.15 , voici ce que donne l’affichage :

on remarque que maintenant la page a un titre “METEO LOCALE” , date et heure sont sur la même ligne et sont mises a jour toutes les 10″ ( seule l’heure varie apres mise a jour).

AJOUT DES CAPTEURS METEO

pour l’étape suivante , ne reste plus qu’a connecter vos capteur météo, pour changer de la version développée ici , nous allons simplifier le montage et remplacer les 2 capteur DHT22 et BMP280 , par un capteur BME280 qui intègre les 3 fonctions; température, pression et Humidité sur un seul module .

c’est un capteur I2C dont le câblage sera donc extrêmement simple, il viendra en parallèle de l’Horloge RTC elle même branchée sur l’I2C. comme toujours avec l’I2C , il faudra contrôler les adresses I2C de chaque composant ( Ici 0x76 pour le capteur BME280 et 0x50 pour l’horloge RTC) et vérifier dans les fichiers des bibliothèques utilisées que les adresses sont les bonnes et faire les modif le cas échéant).

pour cela , on ouvre la bibliotheque “SParFunBME.h” et son fichier complémentaire “SparkFunBME280.cpp” avec un simple editeur de texte genre blocnote de windows, on découvre en general que l’adresse I2C dans la librairie CPP est 0x77 . il faut donc la remplacer par 0x76 et enregistrer le fichier . puis on recompile/televerse le pgme dans l’arduino qui pilote le montage de façon a recuperer la bonne adresse I2C pour le compileur du pgme.

NOTA: la librairie BME280 est en general dans le repertoire “user/nomuser/documents/arduino/librairies”.

voyons maintenant le programme :

par rapport a la version précédente du programme , en violet les ajouts/évolutions concernant le capteur , et pour rendre les données plus visible sur la page , la taille des caractères a été augmentée => ajout d’une ligne ” client.print(“<font size=’10’>”);

pour aérer la page , chaque information est affichée sur une ligne différente , le saut de ligne se fait par l’envoi d’un client.print(“<br/>”);

#include <Wire.h>
#include <SPI.h>
#include <Ethernet.h>
#include "RTClib.h"
#include <SparkFunBME280.h>
RTC_DS1307 rtc;
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 15);
BME280 mySensor;
EthernetServer server(80);

void setup() {
  Wire.begin();
  rtc.begin();
  SPI.begin();
  Ethernet.begin(mac, ip);
  server.begin();
  mySensor.beginI2C();
}

void loop() {  
  EthernetClient client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  
          client.println("Refresh: 10");  
          client.println();
          client.println("<!DOCTYPE HTML>");  
          client.println("<html>");  
              client.println("<head>");
                  client.println("<meta charset=\"utf-8\"></meta>");
                  client.println("<title>METEO LOCALE</title>");     
              client.println("</head>");
              client.println("<body>"); 
                    DateTime time = rtc.now();
                    client.print("<font size='10'>");
                    client.print("Date: ");
                    client.print(time.timestamp(DateTime::TIMESTAMP_DATE));
                    client.print("<br/>");
                    client.print("heure: ");
                    client.print(time.timestamp(DateTime::TIMESTAMP_TIME));
                    client.print("<br/>");
                    client.print("temperature: ");
                    client.print(mySensor.readTempC());
                    client.print("<br/>");
                    client.print("pression: ");
                    client.print(mySensor.readFloatPressure());
                    client.print("<br/>");
                    client.print("Humidité: ");
                    client.print(mySensor.readFloatHumidity());        
              client.println("</body>"); 
          client.println("</html>");   
          break;
        }
        if (c == '\n') {
                   currentLineIsBlank = true;
        } else if (c != '\r') {
                    currentLineIsBlank = false;
        }
      }
    }
    delay(1000);
    client.stop();
  }
}

si tout est OK âpres compilation et déversement dans l’ARDUINO UNO , si on ouvre le navigateur sur son PC et que l’on se connecte a l’adresse 192.168.1.15 de l’arduino uno et son ethernet shield on obtient l’affichage ci dessous qui se rafraichis automatiquement toutes les 5 secondes :

STATION METEO CLIENT

après la version serveur , voyons maintenant la station client qui envoie les données a une page PHP pour enregistrer les données dans une Base De Données MySQML. on peut ensuite consulter la base de donnée ou effectuer des operations sur celle si a partir d’un site internet.

nous allons ici utiliser 3 programmes:

  • un programmeArduino: “meteoclient.ino” ( arduino uno muni de son shield ethernet) qui envoie les données capteurs a une page PHP nomée “insert.php”localisée sur le RPI en mode serveur.
  • la page php “insert.php” qui récupère les infos et les transmet a une base de donnée Mysql nomée “meteo” avec une table nommée “tablemeteo“.
  • une page php “viewtable.php” pour visualiser le contenu de la table de données .

MISE EN PLACE DE LA BDD MySQL et de sa TABLE:

a l’aide de PhpMyAdmin, nous allons créer la base de donnée nomée “meteo” et sa table “tablemeteo” dont voici la structure :

PROGRAMME ARDUINO :

pour le montage Arduino , nous allons reprendre l’ensemble décrit ICI .

  • arduino UNO + Ethernet shield
  • horloge temps reel TinyRTC I2C
  • capteur température/pression/humidité I2C BME280

le programme charge les librairies adéquates, les ouvre , configure l’adresse mac et IP du shield ethernet ( ici 192.168.1.15) puis dans la boucle void , récupère l’heure et la date du RTC puis les valeurs température , pression et humidité du capteur puis envoie tout ça au serveur RPI (adresse IP 192.168.1.18 port 80) et au fichier php “insert.php“en utilisant une syntaxe du type ci dessous:

insert.php?id=0&date=2021-10-12&heure=14:14:25&temperature=25&pression=1028&humidite=66

NOTA: la derniere ligne ” client.print(“\r\n”); ” est primordiale, elle effectue un double retour chariot, sans cette commande , l’envoi des données n’est pas opérant.

#include <Wire.h>
#include <SPI.h>
#include <Ethernet.h>
#include "RTClib.h"
#include <SparkFunBME280.h>
RTC_DS1307 rtc;
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 15);
BME280 mySensor;
EthernetClient client;
int id1 = 0;
String date1 ="";
String heure1 ="";
float temperature1 =0;
float pression1 = 0;
float humidite1 =0;

void setup() {
  Serial.begin(9600);
  Serial.println("demarrage");
  Wire.begin();
  rtc.begin();
  SPI.begin();
  mySensor.beginI2C();
  Ethernet.begin(mac, ip);
}

void loop() {
  if (client.connect("192.168.1.18", 80)) {
    DateTime time = rtc.now();
    date1 = time.timestamp(DateTime::TIMESTAMP_DATE);
    heure1 = time.timestamp(DateTime::TIMESTAMP_TIME);
    temperature1 = mySensor.readTempC();
    pression1 = mySensor.readFloatPressure();
    humidite1 = mySensor.readFloatHumidity();
    client.print( "GET /insert.php?id=");
    client.print("0");    
    client.print("&date=");    
    client.print(date1);
    client.print("&heure=");
    client.print(heure1);
    client.print("&temperature=");
    client.print(temperature1);
    client.print("&pression=");
    client.print(pression1);
    client.print("&humidite=");
    client.print(humidite1);
    client.print("\r\n");
    delay(30000);     
  } else {
    Serial.println("echec de la connexion");
    delay(3000);
  }
}

PROGRAMME PHP de transfert ARDUINO => MySQL:

le programme php lui est extrêmement simple: le fichier ci dessous devra etre sauvegardé avec l’extension php au lieu de txt dans le répertoire var/www/html du RPI.

en premiere ligne il se connecte a la BDD “meteo” sur le serveur local avec l’identifiant “root” , le mot de passe “motdepasse” ( ces paramètres sont éventuellement a changer en fonction des vôtres).

en deuxième ligne il envoi la commande d’insertion des paramètres arduino .

la ligne “mysqli_query ($dbconnect,$sql);” effectue la requête de connexion et d’envoi des données.

<?php
$dbconnect = mysqli_connect("localhost", "root", "motdepasse", "meteo"); 
$sql = "INSERT INTO tablemeteo (id, date, heure, temperature, pression, humidite) VALUES ('".$_GET['id']."', '".$_GET['date']."', '".$_GET['heure']."', '".$_GET['temperature']."', '".$_GET['pression']."', '".$_GET['humidite']."')";
mysqli_query($dbconnect,$sql);
?>

VISUALISATION DU RESULTAT :

pour visualiser le résultat de l’envoi des données a la table de la BDD meteo , nous allons ajouter un script php dans le répertoire var/www/html du RPI.

le fichier ci dessous au format .txt devra y etre copié avec l’extension.php

<?php
$link = mysqli_connect("localhost", "root", "motdepasse", "meteo");
if($link === false){
    die("ERROR: Could not connect. " . mysqli_connect_error());
}
$sql = "SELECT * FROM tablemeteo";
if($result = mysqli_query($link, $sql)){
    if(mysqli_num_rows($result) > 0){
        echo "<table>";
            echo "<tr>";
                echo "<th>ID</th>";
                echo "<th>DATE</th>";
                echo "<th>HEURE</th>";
                echo "<th>TEMPERATURE</th>";
		echo "<th>PRESSION</th>";
		echo "<th>HUMIDITE</th>";
            echo "</tr>";
        while($row = mysqli_fetch_array($result)){
            echo "<tr>";
                echo "<td>" . $row['id'] . "</td>";
                echo "<td>" . $row['date'] . "</td>";
                echo "<td>" . $row['heure'] . "</td>";
                echo "<td>" . $row['temperature'] . "</td>";
                echo "<td>" . $row['pression'] . "</td>";
                echo "<td>" . $row['humidite'] . "</td>";
            echo "</tr>";
        }
        echo "</table>";
        // Free result set
        mysqli_free_result($result);
    } else{
        echo "No records matching your query were found.";
    }
} else{
    echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}
mysqli_close($link);
?>

une fois positionné dans le répertoire du RPI , pour se connecter a la table, il suffit d’ouvrir votre navigateur internet sur votre PC connecté au réseau et de taper:

192.168.1.18/viewtable.php

si tout est ok vous devriez voir une page de ce type : attention , la page ne se régénère pas automatiquement , il faut l’actualiser a la main pour voir le nombre de lignes évoluer au fil du temps .

une petite vidéo YouTube qui résume tout ça :