Construisez un tableau de bord de station météo cloud pour visualiser les lectures de vos capteurs ESP32 ou ESP8266 de n’importe où dans le monde. Vous visualiserez les données de vos capteurs affichées sur des jauges et sur un tableau. L’ESP32 ou l’ESP8266 fera une requête HTTP POST à un script PHP pour insérer vos données dans une base de données MySQL.

Mis à jour le 27 mars 2023
Auparavant, nous stockions les lectures des capteurs dans une base de données et les affichions sur un tableau ou des graphiques auxquels vous pouvez accéder de n’importe où en utilisant votre propre serveur. Maintenant, j’ai décidé d’aller plus loin et d’ajouter quelques informations supplémentaires à la page Web.
J’ai ajouté deux jauges pour afficher les dernières lectures de température et d’humidité ainsi que des statistiques sur les lectures minimales, maximales et moyennes à partir d’un certain nombre de lectures que vous pouvez définir. Vous pouvez également visualiser toutes les dernières lectures sur un tableau et vous pouvez sélectionner le nombre de lectures que vous souhaitez afficher.
Pour créer ce projet, vous utiliserez ces technologies :
- ESP32 ou ESP8266 programmé avec Arduino IDE
- Serveur d’hébergement et nom de domaine
- Script PHP pour insérer des données dans MySQL et les afficher sur une page Web
- Base de données MySQL pour stocker les lectures
Table des matières
Ce projet est divisé en les principales sections suivantes :
- Hébergement de votre application PHP et de votre base de données MySQL
- Préparation de votre base de données MySQL
- PHP Script HTTP POST – Recevoir et insérer des données dans la base de données MySQL
- Script PHP pour les fonctions de base de données
- Script PHP – Afficher les lectures de la base de données sur les jauges et le tableau
- Configuration de l’ESP32 ou de l’ESP8266
Regardez la démonstration vidéo
Pour voir comment fonctionne le projet, vous pouvez regarder la vidéo de démonstration suivante :

0. Télécharger le code source
Pour ce projet, vous aurez besoin de ces fichiers :
1. Hébergement de votre application PHP et de votre base de données MySQL
L’objectif de ce projet est d’avoir votre propre nom de domaine et compte d’hébergement qui vous permet de stocker les lectures des capteurs de l’ESP32 ou de l’ESP8266. Vous pouvez visualiser les lectures de n’importe où dans le monde en accédant à votre propre domaine de serveur.
Voici un aperçu de haut niveau du fonctionnement du projet :

- Vous avez un ESP32 ou ESP8266 qui envoie les lectures des capteurs à votre propre serveur. Pour cela, vous avez votre carte connectée à votre routeur ;
- Dans votre serveur, il y a un script PHP qui vous permet de stocker vos lectures dans une base de données MySQL ;
- Ensuite, un autre script PHP affichera la page Web avec les jauges, le tableau et toutes les autres informations ;
- Enfin, vous pouvez visualiser les lectures de n’importe où dans le monde en accédant à votre propre nom de domaine.
Services d’hébergement
Je recommande d’utiliser l’un des services d’hébergement suivants qui peuvent gérer toutes les exigences du projet :
- Bluehost (convivial avec cPanel) : nom de domaine gratuit lors de la souscription au plan de 3 ans. Je recommande de choisir l’option de sites Web illimités ;
- Digital Ocean : serveur Linux que vous gérez via une ligne de commande. Je n’ai recommandé cette option qu’aux utilisateurs avancés.
Ces deux services sont ceux que j’utilise et que je recommande personnellement, mais vous pouvez utiliser n’importe quel autre service d’hébergement. Tout service d’hébergement proposant PHP et MySQL fonctionnera avec ce didacticiel. Si vous n’avez pas de compte d’hébergement, je vous recommande de vous inscrire à Bluehost.
Obtenez un hébergement et un nom de domaine avec Bluehost »
Lors de l’achat d’un compte d’hébergement, vous devrez également acheter un nom de domaine. C’est ce qui rend ce projet intéressant : vous pourrez accéder à votre nom de domaine (https://example.com) et voir vos relevés ESP.
Si vous aimez nos projets, vous pourriez envisager de vous inscrire à l’un des services d’hébergement recommandés, car vous soutiendrez notre travail.
Remarque : vous pouvez également exécuter un serveur LAMP (Linux, Apache, MySQL, PHP) sur un Raspberry Pi pour accéder aux données de votre réseau local. Cependant, le but de ce tutoriel est de publier des lectures dans votre propre nom de domaine auquel vous pouvez accéder de n’importe où dans le monde. Cela vous permet d’accéder facilement à vos lectures ESP sans dépendre d’une plate-forme IoT tierce.
2. Préparation de votre base de données MySQL
Après avoir créé un compte d’hébergement et configuré un nom de domaine, vous pouvez vous connecter à votre cPanel ou à un tableau de bord similaire. Après cela, suivez les étapes suivantes pour créer votre base de données, votre nom d’utilisateur, votre mot de passe et votre table SQL.
Création d’une base de données et d’un utilisateur
Ouvrez l’onglet « Avancé »:

1. Tapez « base de données » dans la barre de recherche et sélectionnez « Assistant de base de données MySQL ».

2. Entrez le nom de votre base de données souhaitée. Dans mon cas, le nom de la base de données est esp_data. Ensuite, appuyez sur le bouton « Étape suivante » :

Remarque : plus tard, vous devrez utiliser le nom de la base de données avec le préfixe que votre hébergeur vous donne (mon préfixe de base de données dans la capture d’écran ci-dessus est flou). Je l’appellerai désormais example_esp_data.
3. Tapez votre nom d’utilisateur de base de données et définissez un mot de passe. Vous devez enregistrer tous ces détails car vous en aurez besoin plus tard pour établir une connexion à la base de données avec votre code PHP.

C’est ça! Votre nouvelle base de données et votre nouvel utilisateur ont été créés avec succès. Maintenant, enregistrez toutes vos informations, car vous en aurez besoin plus tard :
- Nom de la base de données : example_esp_data
- Nom d’utilisateur : example_esp_board
- Mot de passe : votre mot de passe
Création d’un tableau SQL
Après avoir créé votre base de données et votre utilisateur, revenez au tableau de bord cPanel et recherchez « phpMyAdmin ».

Dans la barre latérale gauche, sélectionnez le nom de votre base de données example_esp_data et ouvrez l’onglet « SQL ».

Important : assurez-vous d’avoir ouvert la base de données example_esp_data. Ensuite, cliquez sur l’onglet SQL. Si vous ne suivez pas ces étapes exactes et n’exécutez pas la requête SQL, vous risquez de créer une table dans la mauvaise base de données.
Copiez la requête SQL dans l’extrait de code suivant :
CREATE TABLE SensorData (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
sensor VARCHAR(30) NOT NULL,
location VARCHAR(30) NOT NULL,
value1 VARCHAR(10),
value2 VARCHAR(10),
value3 VARCHAR(10),
reading_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
Collez-le dans le champ de requête SQL (surligné d’un rectangle rouge) et appuyez sur le bouton « Go » pour créer votre table :

Après cela, vous devriez voir votre table nouvellement créée appelée SensorData dans la base de données example_esp_data, comme illustré dans la figure ci-dessous :

3. PHP Script HTTP POST – Recevoir et insérer des données dans la base de données MySQL
Dans cette section, nous allons créer un script PHP chargé de recevoir les requêtes entrantes de l’ESP32 ou de l’ESP8266 et d’insérer les données dans une base de données MySQL.
Si vous utilisez un fournisseur d’hébergement avec cPanel, vous pouvez rechercher « Gestionnaire de fichiers » :

Ensuite, sélectionnez l’option public_html et appuyez sur le bouton « + Fichier » pour créer un nouveau fichier .php.

Remarque : si vous suivez ce tutoriel et que vous n’êtes pas familier avec PHP ou MySQL, je vous recommande de créer ces fichiers exacts. Sinon, vous devrez modifier l’esquisse ESP fournie avec différents chemins d’URL.
Créez un nouveau fichier dans /public_html avec ce nom et cette extension exacts : esp-post-data.php

Modifiez le fichier nouvellement créé (esp-post-data.php) et copiez l’extrait suivant :
<!--
Rui Santos
Complete project details at https://Raspberryme.com/cloud-weather-station-esp32-esp8266/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
-->
<?php
include_once('esp-database.php');
// Keep this API Key value to be compatible with the ESP code provided in the project page. If you change this value, the ESP sketch needs to match
$api_key_value = "tPmAT5Ab3j7F9";
$api_key= $sensor = $location = $value1 = $value2 = $value3 = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$api_key = test_input($_POST["api_key"]);
if($api_key == $api_key_value) {
$sensor = test_input($_POST["sensor"]);
$location = test_input($_POST["location"]);
$value1 = test_input($_POST["value1"]);
$value2 = test_input($_POST["value2"]);
$value3 = test_input($_POST["value3"]);
$result = insertReading($sensor, $location, $value1, $value2, $value3);
echo $result;
}
else {
echo "Wrong API Key provided.";
}
}
else {
echo "No data posted with HTTP POST.";
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
4. Script PHP pour les fonctions de base de données
Créez un nouveau fichier dans /public_html responsable de l’insertion et de l’accès aux données de votre base de données. Nommez votre fichier : esp-database.php

Copiez ce script PHP :
<!--
Rui Santos
Complete project details at https://Raspberryme.com/cloud-weather-station-esp32-esp8266/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
-->
<?php
$servername = "localhost";
// REPLACE with your Database name
$dbname = "REPLACE_WITH_YOUR_DATABASE_NAME";
// REPLACE with Database user
$username = "REPLACE_WITH_YOUR_USERNAME";
// REPLACE with Database user password
$password = "REPLACE_WITH_YOUR_PASSWORD";
function insertReading($sensor, $location, $value1, $value2, $value3) {
global $servername, $username, $password, $dbname;
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "INSERT INTO SensorData (sensor, location, value1, value2, value3)
VALUES ('" . $sensor . "', '" . $location . "', '" . $value1 . "', '" . $value2 . "', '" . $value3 . "')";
if ($conn->query($sql) === TRUE) {
return "New record created successfully";
}
else {
return "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
}
function getAllReadings($limit) {
global $servername, $username, $password, $dbname;
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT id, sensor, location, value1, value2, value3, reading_time FROM SensorData order by reading_time desc limit " . $limit;
if ($result = $conn->query($sql)) {
return $result;
}
else {
return false;
}
$conn->close();
}
function getLastReadings() {
global $servername, $username, $password, $dbname;
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT id, sensor, location, value1, value2, value3, reading_time FROM SensorData order by reading_time desc limit 1" ;
if ($result = $conn->query($sql)) {
return $result->fetch_assoc();
}
else {
return false;
}
$conn->close();
}
function minReading($limit, $value) {
global $servername, $username, $password, $dbname;
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT MIN(" . $value . ") AS min_amount FROM (SELECT " . $value . " FROM SensorData order by reading_time desc limit " . $limit . ") AS min";
if ($result = $conn->query($sql)) {
return $result->fetch_assoc();
}
else {
return false;
}
$conn->close();
}
function maxReading($limit, $value) {
global $servername, $username, $password, $dbname;
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT MAX(" . $value . ") AS max_amount FROM (SELECT " . $value . " FROM SensorData order by reading_time desc limit " . $limit . ") AS max";
if ($result = $conn->query($sql)) {
return $result->fetch_assoc();
}
else {
return false;
}
$conn->close();
}
function avgReading($limit, $value) {
global $servername, $username, $password, $dbname;
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT AVG(" . $value . ") AS avg_amount FROM (SELECT " . $value . " FROM SensorData order by reading_time desc limit " . $limit . ") AS avg";
if ($result = $conn->query($sql)) {
return $result->fetch_assoc();
}
else {
return false;
}
$conn->close();
}
?>
Avant d’enregistrer le fichier, vous devez modifier les variables $dbname, $username et $password avec vos détails uniques :
// Your Database name
$dbname = "example_esp_data";
// Your Database user
$username = "example_esp_board";
// Your Database user password
$password = "YOUR_USER_PASSWORD";
Après avoir ajouté le nom de la base de données, le nom d’utilisateur et le mot de passe, enregistrez le fichier et continuez avec ce didacticiel. Si vous essayez d’accéder à votre nom de domaine dans le chemin d’URL suivant, vous verrez ce qui suit :
https://example.com/esp-post-data.php

5. PHP Script – Afficher les lectures de la base de données sur les jauges et le tableau
Vous devrez également ajouter un fichier CSS pour styliser votre tableau de bord, nommez-le : esp-style.css :

Copiez ce CSS dans votre fichier et enregistrez-le :
/**
Rui Santos
Complete project details at https://Raspberryme.com/cloud-weather-station-esp32-esp8266/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
**/
body {
width: 60%;
margin: auto;
text-align: center;
font-family: Arial;
top: 50%;
left: 50%;
}
@media screen and (max-width: 800px) {
body {
width: 100%;
}
}
table {
margin-left: auto;
margin-right: auto;
}
div {
margin-left: auto;
margin-right: auto;
}
h2 { font-size: 2.5rem; }
.header {
padding: 1rem;
margin: 0 0 2rem 0;
background: #f2f2f2;
}
h1 {
font-size: 2rem;
font-family: Arial, sans-serif;
text-align: center;
text-transform: uppercase;
}
.content {
display: flex;
}
@media screen and (max-width: 500px) /* Mobile */ {
.content {
flex-direction: column;
}
}
.mask {
position: relative;
overflow: hidden;
display: block;
width: 12.5rem;
height: 6.25rem;
margin: 1.25rem;
}
.semi-circle {
position: relative;
display: block;
width: 12.5rem;
height: 6.25rem;
background: linear-gradient(to right, #3498db 0%, #05b027 33%, #f1c40f 70%, #c0392b 100%);
border-radius: 50% 50% 50% 50% / 100% 100% 0% 0%;
}
.semi-circle::before {
content: "";
position: absolute;
bottom: 0;
left: 50%;
z-index: 2;
display: block;
width: 8.75rem;
height: 4.375rem;
margin-left: -4.375rem;
background: #fff;
border-radius: 50% 50% 50% 50% / 100% 100% 0% 0%;
}
.semi-circle--mask {
position: absolute;
top: 0;
left: 0;
width: 12.5rem;
height: 12.5rem;
background: transparent;
transform: rotate(120deg) translate3d(0, 0, 0);
transform-origin: center center;
backface-visibility: hidden;
transition: all 0.3s ease-in-out;
}
.semi-circle--mask::before {
content: "";
position: absolute;
top: 0;
left: 0%;
z-index: 2;
display: block;
width: 12.625rem;
height: 6.375rem;
margin: -1px 0 0 -1px;
background: #f2f2f2;
border-radius: 50% 50% 50% 50% / 100% 100% 0% 0%;
}
.gauge--2 .semi-circle { background: #3498db; }
.gauge--2 .semi-circle--mask { transform: rotate(20deg) translate3d(0, 0, 0); }
#tableReadings { border-collapse: collapse; }
#tableReadings td, #tableReadings th {
border: 1px solid #ddd;
padding: 10px;
}
#tableReadings tr:nth-child(even){ background-color: #f2f2f2; }
#tableReadings tr:hover { background-color: #ddd; }
#tableReadings th {
padding: 10px;
background-color: #2f4468;
color: white;
}
Enfin, créez un autre fichier PHP dans le répertoire /public_html qui affichera tout le contenu de la base de données sur une page Web. Nommez votre nouveau fichier : esp-weather-station.php

Editez le fichier nouvellement créé (esp-weather-station.php) et copiez le code suivant :
<!--
Rui Santos
Complete project details at https://Raspberryme.com/cloud-weather-station-esp32-esp8266/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
-->
<?php
include_once('esp-database.php');
if (isset($_GET["readingsCount"])){
$data = $_GET["readingsCount"];
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
$readings_count = $_GET["readingsCount"];
}
// default readings count set to 20
else {
$readings_count = 20;
}
$last_reading = getLastReadings();
$last_reading_temp = $last_reading["value1"];
$last_reading_humi = $last_reading["value2"];
$last_reading_time = $last_reading["reading_time"];
// Uncomment to set timezone to - 1 hour (you can change 1 to any number)
//$last_reading_time = date("Y-m-d H:i:s", strtotime("$last_reading_time - 1 hours"));
// Uncomment to set timezone to + 7 hours (you can change 7 to any number)
//$last_reading_time = date("Y-m-d H:i:s", strtotime("$last_reading_time + 7 hours"));
$min_temp = minReading($readings_count, 'value1');
$max_temp = maxReading($readings_count, 'value1');
$avg_temp = avgReading($readings_count, 'value1');
$min_humi = minReading($readings_count, 'value2');
$max_humi = maxReading($readings_count, 'value2');
$avg_humi = avgReading($readings_count, 'value2');
?>
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="https://www.raspberryme.com/cloud-weather-station-esp32-esp8266/esp-style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<header class="header">
<h1>???? ESP Weather Station</h1>
<form method="get">
<input type="number" name="readingsCount" min="1" placeholder="Number of readings (<?php echo $readings_count; ?>)">
<input type="submit" value="UPDATE">
</form>
</header>
<body>
<p>Last reading: <?php echo $last_reading_time; ?></p>
<section class="content">
<div class="box gauge--1">
<h3>TEMPERATURE</h3>
<div class="mask">
<div class="semi-circle"></div>
<div class="semi-circle--mask"></div>
</div>
<p style="font-size: 30px;" id="temp">--</p>
<table cellspacing="5" cellpadding="5">
<tr>
<th colspan="3">Temperature <?php echo $readings_count; ?> readings</th>
</tr>
<tr>
<td>Min</td>
<td>Max</td>
<td>Average</td>
</tr>
<tr>
<td><?php echo $min_temp['min_amount']; ?> °C</td>
<td><?php echo $max_temp['max_amount']; ?> °C</td>
<td><?php echo round($avg_temp['avg_amount'], 2); ?> °C</td>
</tr>
</table>
</div>
<div class="box gauge--2">
<h3>HUMIDITY</h3>
<div class="mask">
<div class="semi-circle"></div>
<div class="semi-circle--mask"></div>
</div>
<p style="font-size: 30px;" id="humi">--</p>
<table cellspacing="5" cellpadding="5">
<tr>
<th colspan="3">Humidity <?php echo $readings_count; ?> readings</th>
</tr>
<tr>
<td>Min</td>
<td>Max</td>
<td>Average</td>
</tr>
<tr>
<td><?php echo $min_humi['min_amount']; ?> %</td>
<td><?php echo $max_humi['max_amount']; ?> %</td>
<td><?php echo round($avg_humi['avg_amount'], 2); ?> %</td>
</tr>
</table>
</div>
</section>
<?php
echo '<h2> View Latest ' . $readings_count . ' Readings</h2>
<table cellspacing="5" cellpadding="5" id="tableReadings">
<tr>
<th>ID</th>
<th>Sensor</th>
<th>Location</th>
<th>Value 1</th>
<th>Value 2</th>
<th>Value 3</th>
<th>Timestamp</th>
</tr>';
$result = getAllReadings($readings_count);
if ($result) {
while ($row = $result->fetch_assoc()) {
$row_id = $row["id"];
$row_sensor = $row["sensor"];
$row_location = $row["location"];
$row_value1 = $row["value1"];
$row_value2 = $row["value2"];
$row_value3 = $row["value3"];
$row_reading_time = $row["reading_time"];
// Uncomment to set timezone to - 1 hour (you can change 1 to any number)
//$row_reading_time = date("Y-m-d H:i:s", strtotime("$row_reading_time - 1 hours"));
// Uncomment to set timezone to + 7 hours (you can change 7 to any number)
//$row_reading_time = date("Y-m-d H:i:s", strtotime("$row_reading_time + 7 hours"));
echo '<tr>
<td>' . $row_id . '</td>
<td>' . $row_sensor . '</td>
<td>' . $row_location . '</td>
<td>' . $row_value1 . '</td>
<td>' . $row_value2 . '</td>
<td>' . $row_value3 . '</td>
<td>' . $row_reading_time . '</td>
</tr>';
}
echo '</table>';
$result->free();
}
?>
<script>
var value1 = <?php echo $last_reading_temp; ?>;
var value2 = <?php echo $last_reading_humi; ?>;
setTemperature(value1);
setHumidity(value2);
function setTemperature(curVal){
//set range for Temperature in Celsius -5 Celsius to 38 Celsius
var minTemp = -5.0;
var maxTemp = 38.0;
//set range for Temperature in Fahrenheit 23 Fahrenheit to 100 Fahrenheit
//var minTemp = 23;
//var maxTemp = 100;
var newVal = scaleValue(curVal, [minTemp, maxTemp], [0, 180]);
$('.gauge--1 .semi-circle--mask').attr({
style: '-webkit-transform: rotate(' + newVal + 'deg);' +
'-moz-transform: rotate(' + newVal + 'deg);' +
'transform: rotate(' + newVal + 'deg);'
});
$("#temp").text(curVal + ' ºC');
}
function setHumidity(curVal){
//set range for Humidity percentage 0 % to 100 %
var minHumi = 0;
var maxHumi = 100;
var newVal = scaleValue(curVal, [minHumi, maxHumi], [0, 180]);
$('.gauge--2 .semi-circle--mask').attr({
style: '-webkit-transform: rotate(' + newVal + 'deg);' +
'-moz-transform: rotate(' + newVal + 'deg);' +
'transform: rotate(' + newVal + 'deg);'
});
$("#humi").text(curVal + ' %');
}
function scaleValue(value, from, to) {
var scale = (to[1] - to[0]) / (from[1] - from[0]);
var capped = Math.min(from[1], Math.max(from[0], value)) - from[0];
return ~~(capped * scale + to[0]);
}
</script>
</body>
</html>
Si vous essayez d’accéder à votre nom de domaine dans le chemin d’URL suivant, vous verrez ce qui suit :
https://example.com/esp-weather-station.php

C’est ça! Si vous voyez cette page Web avec des valeurs vides dans votre navigateur, cela signifie que tout est prêt. Dans la section suivante, vous apprendrez à insérer des données de votre ESP32 ou ESP8266 dans la base de données.
6. Configuration de l’ESP32 ou de l’ESP8266
Ce projet est compatible avec les cartes ESP32 et ESP8266. Il vous suffit d’assembler un circuit simple et de télécharger le croquis fourni pour insérer la température, l’humidité, la pression, etc. dans votre base de données toutes les 10 minutes. Le croquis est légèrement différent pour chaque planche.

Pièces requises
Pour cet exemple, nous obtiendrons les lectures du capteur du capteur BME280. Voici une liste des pièces dont vous avez besoin pour construire le circuit pour ce projet :
Vous pouvez utiliser les liens précédents ou accéder directement à MakerAdvisor.com/tools pour trouver toutes les pièces pour vos projets au meilleur prix !
Schémas
Le module de capteur BME280 que nous utilisons communique via le protocole de communication I2C, vous devez donc le connecter aux broches ESP32 ou ESP8266 I2C.
Câblage BME280 vers ESP32
Les broches ESP32 I2C sont :
- GPIO 22 : SCL (SCK)
- GPIO 21 : SDA (SDI)
Alors, assemblez votre circuit comme indiqué dans le diagramme schématique suivant (Guide pour ESP32 avec serveur Web BME280 et ESP32 BME280).

Lecture recommandée : Guide de référence du brochage ESP32
Câblage BME280 vers ESP8266
Les broches ESP8266 I2C sont :
- GPIO 5 (D1): SCL (SCK)
- GPIO 4 (D2) : SDA (SDI)
Assemblez votre circuit comme dans le schéma suivant si vous utilisez une carte ESP8266 (lisez le Guide pour ESP8266 avec BME280).

Lecture recommandée : Guide de référence du brochage ESP8266
Installation des bibliothèques
Nous allons programmer l’ESP32/ESP8266 à l’aide de l’IDE Arduino, vous devez donc avoir le module complémentaire ESP installé dans votre IDE Arduino.
Suivez l’un des tutoriels suivants en fonction de la carte que vous utilisez :
Code ESP32
Suivez cette section si vous utilisez un ESP32. Pour un ESP8266 cliquez ici.
Après avoir installé les modules complémentaires de carte nécessaires, copiez le code suivant dans votre IDE Arduino, mais ne le téléchargez pas encore. Vous devez apporter quelques modifications pour que cela fonctionne pour vous.
/*
Rui Santos
Complete project details at https://Raspberryme.com/esp32-esp8266-mysql-database-php/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "https://example.com/esp-post-data.php";
// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
String apiKeyValue = "tPmAT5Ab3j7F9";
String sensorName = "BME280";
String sensorLocation = "Office";
/*#include <SPI.h>
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
// (you can also pass in a Wire library object like &Wire2)
bool status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring or change I2C address!");
while (1);
}
}
void loop() {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
WiFiClientSecure *client = new WiFiClientSecure;
client->setInsecure(); //don't use SSL certificate
HTTPClient https;
// Your Domain name with URL path or IP address with path
https.begin(*client, serverName);
// Specify content-type header
https.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Prepare your HTTP POST request data
String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
+ "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature())
+ "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";
Serial.print("httpRequestData: ");
Serial.println(httpRequestData);
// You can comment the httpRequestData variable above
// then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
//String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";
// Send HTTP POST request
int httpResponseCode = https.POST(httpRequestData);
// If you need an HTTP request with a content type: text/plain
//https.addHeader("Content-Type", "text/plain");
//int httpResponseCode = https.POST("Hello, World!");
// If you need an HTTP request with a content type: application/json, use the following:
//https.addHeader("Content-Type", "application/json");
//int httpResponseCode = https.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
https.end();
}
else {
Serial.println("WiFi Disconnected");
}
//Send an HTTP POST request every 30 seconds
delay(30000);
}
Définition de vos identifiants réseau
Vous devez modifier les lignes suivantes avec vos identifiants réseau : SSID et mot de passe. Le code est bien commenté sur l’endroit où vous devez apporter les modifications.
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Définition de votre nom de serveur
Vous devez également saisir votre nom de domaine, afin que l’ESP publie les lectures sur votre propre serveur.
const char* serverName = "https://example.com/esp-post-data.php";
Maintenant, vous pouvez télécharger le code sur votre tableau.
Remarque : La plupart des serveurs nécessitent que vous fassiez des requêtes HTTPS. Le code ci-dessus rend les requêtes HTTPS conformes aux exigences de la plupart des serveurs cloud de nos jours.
Votre serveur ne supporte pas le HTTPS ? Utilisez plutôt ce code.
Comment fonctionne le code
Ce projet est déjà assez long, nous ne détaillerons donc pas le fonctionnement du code, mais voici un petit résumé :
- Importez toutes les bibliothèques pour le faire fonctionner ;
- Définissez les variables que vous voudrez peut-être modifier (apiKeyValue, sensorName, sensorLocation) ;
- L’apiKeyValue est juste une chaîne aléatoire que vous pouvez modifier. Il est utilisé pour des raisons de sécurité, de sorte que seule toute personne connaissant votre clé API peut publier des données dans votre base de données ;
- Initialisez la communication série à des fins de débogage ;
- Établissez une connexion Wi-Fi avec votre routeur ;
- Initialisez le BME280 pour obtenir des lectures ;
- Initialisez un client WiFi sécurisé.
Ensuite, dans la boucle () est l’endroit où vous effectuez réellement la requête HTTP POST toutes les 10 minutes avec les dernières lectures BME280 :
// Your Domain name with URL path or IP address with path
http.begin(serverName);
// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Prepare your HTTP POST request data
String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName + "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature()) + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";
int httpResponseCode = http.POST(httpRequestData);
Vous pouvez commenter la variable httpRequestData ci-dessus qui concatène toutes les lectures BME280 et utiliser la variable httpRequestData ci-dessous à des fins de test :
String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";
En savoir plus sur les requêtes HTTPS avec l’ESP32 : requêtes HTTPS ESP32 (Arduino IDE).
Code ESP8266
Suivez cette section si vous utilisez un ESP8266. Pour un ESP32, consultez la section ci-dessus.
Après avoir installé les modules complémentaires et les bibliothèques de cartes nécessaires, copiez le code suivant dans votre IDE Arduino, mais ne le téléchargez pas encore. Vous devez apporter quelques modifications pour que cela fonctionne pour vous.
/*
Rui Santos
Complete project details at https://Raspberryme.com/esp32-esp8266-mysql-database-php/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "https://example.com/esp-post-data.php";
// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key
String apiKeyValue = "tPmAT5Ab3j7F9";
String sensorName = "BME280";
String sensorLocation = "Office";
/*#include <SPI.h>
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
// (you can also pass in a Wire library object like &Wire2)
bool status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring or change I2C address!");
while (1);
}
}
void loop() {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
// Ignore SSL certificate validation
client->setInsecure();
//create an HTTPClient instance
HTTPClient https;
// Your Domain name with URL path or IP address with path
https.begin(*client, serverName);
// Specify content-type header
https.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Prepare your HTTP POST request data
String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
+ "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature())
+ "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";
Serial.print("httpRequestData: ");
Serial.println(httpRequestData);
// You can comment the httpRequestData variable above
// then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
//String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";
// Send HTTP POST request
int httpResponseCode = https.POST(httpRequestData);
// If you need an HTTP request with a content type: text/plain
//http.addHeader("Content-Type", "text/plain");
//int httpResponseCode = https.POST("Hello, World!");
// If you need an HTTP request with a content type: application/json, use the following:
//http.addHeader("Content-Type", "application/json");
//int httpResponseCode = https.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
https.end();
}
else {
Serial.println("WiFi Disconnected");
}
//Send an HTTP POST request every 30 seconds
delay(30000);
}
Définition de vos identifiants réseau
Vous devez modifier les lignes suivantes avec vos identifiants réseau : SSID et mot de passe. Le code est bien commenté sur l’endroit où vous devez apporter les modifications.
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Définition de votre nom de serveur
Vous devez également saisir votre nom de domaine, afin que l’ESP publie les lectures sur votre propre serveur.
const char* serverName = "https://example.com/esp-post-data.php";
Maintenant, vous pouvez télécharger le code sur votre tableau.
Remarque : La plupart des serveurs nécessitent que vous fassiez des requêtes HTTPS. Le code ci-dessus rend les requêtes HTTPS conformes aux exigences de la plupart des serveurs cloud de nos jours.
Votre serveur ne supporte pas le HTTPS ? Utilisez plutôt ce code.
En savoir plus sur les requêtes HTTPS avec l’ESP8266 : ESP8266 NodeMCU HTTPS Requests (Arduino IDE).
Manifestation
Après avoir terminé toutes les étapes, laissez votre carte ESP collecter des lectures et les publier sur votre serveur.

Si tout est correct, voici ce que vous devriez voir dans votre moniteur série Arduino IDE :

Si vous ouvrez votre nom de domaine dans ce chemin URL :
https://example.com/esp-weather-station.php
Vous devriez voir les 20 dernières lectures stockées dans votre base de données. Il y a deux jauges qui affichent les dernières lectures de température et d’humidité, et un horodatage.
Actualisez la page Web pour voir les dernières lectures :

Il y a un champ où tu peux taper le nombre de lectures à visualiser, ainsi que le nombre de lectures pour ces statistiques : minimum, maximum et moyenne. Par défaut, il est défini sur 20. Par exemple, si vous tapez 30 et appuyez sur le bouton de mise à jour, vous verrez que votre page Web se met à jour et recalcule toutes les valeurs.

La page Web est également adaptée aux mobiles, vous pouvez donc utiliser n’importe quel appareil pour y accéder :

Vous pouvez également vous rendre sur phpMyAdmin pour gérer les données stockées dans votre table SensorData. Vous pouvez le supprimer, le modifier, etc…

Conclusion
Dans ce didacticiel, vous avez appris à publier des données de capteur dans une base de données de votre propre domaine de serveur à laquelle vous pouvez accéder depuis n’importe où dans le monde. Cela nécessite que vous ayez votre propre serveur et nom de domaine (alternativement, vous pouvez utiliser un serveur Raspberry Pi LAMP pour un accès local).
Je vous encourage à modifier l’apparence de la page Web, à ajouter plus de fonctionnalités (comme les notifications par e-mail), à publier les données de différents capteurs, à utiliser plusieurs cartes ESP, et bien plus encore.
Vous aimerez peut-être aussi lire :
Apprenez-en plus sur l’ESP32 et l’ESP8266 avec nos ressources :
Merci pour la lecture.
Cette vidéo vous emmène dans l’histoire de Raspberry Pi :
