A l'occasion des 80 ans de la libération de Rennes, (re)découvrez l'ensemble des
contributions autour de la Seconde Guerre mondiale et de la libération sur Wiki-Rennes.
« Fabrication d’un chargeur universel pour vélo » : différence entre les versions
(image) |
(ajouter le code pour envoyer les variables sur une page web servie par l' ESP D1) |
||
Ligne 122 : | Ligne 122 : | ||
delay(2000); // Pause de 2 secondes avant la prochaine lecture | delay(2000); // Pause de 2 secondes avant la prochaine lecture | ||
} | } | ||
</syntaxhighlight>Visualisation par serveur web<syntaxhighlight lang="c"> | |||
#include <ESP8266WiFi.h> | |||
#include <ESP8266WebServer.h> | |||
#include <ModbusMaster.h> | |||
const char* ssid = "Pixelm"; | |||
const char* password = "bienveillance"; | |||
ESP8266WebServer server(80); | |||
ModbusMaster node; | |||
// Variables pour stocker les données Modbus | |||
float voltage = 0; | |||
float current = 0; | |||
float power = 0; | |||
float energy = 0; | |||
// Constante pour le délai entre les lectures | |||
const unsigned long READ_INTERVAL = 2000; | |||
unsigned long lastReadTime = 0; | |||
void setup() { | |||
Serial.begin(9600); | |||
Serial.println("Initialisation Modbus..."); | |||
// Initialisation Modbus | |||
node.begin(1, Serial); // Adresse esclave 1, communication via le port série | |||
// Connexion Wi-Fi | |||
connectToWiFi(); | |||
// Initialisation serveur Web | |||
server.on("/", handleRoot); | |||
server.begin(); | |||
Serial.println("Serveur HTTP démarré."); | |||
} | |||
void loop() { | |||
server.handleClient(); | |||
// Lecture des données Modbus toutes les READ_INTERVAL millisecondes | |||
if (millis() - lastReadTime >= READ_INTERVAL) { | |||
lastReadTime = millis(); | |||
readModbusData(); | |||
} | |||
} | |||
void connectToWiFi() { | |||
WiFi.begin(ssid, password); | |||
Serial.println("Connexion au Wi-Fi..."); | |||
unsigned long startTime = millis(); | |||
while (WiFi.status() != WL_CONNECTED) { | |||
if (millis() - startTime > 30000) { // Limite de 30 secondes pour la connexion | |||
Serial.println("Erreur de connexion au Wi-Fi."); | |||
return; | |||
} | |||
delay(1000); | |||
Serial.print("."); | |||
} | |||
Serial.println(""); | |||
Serial.println("Connecté au Wi-Fi."); | |||
Serial.print("Adresse IP: "); | |||
Serial.println(WiFi.localIP()); | |||
} | |||
void readModbusData() { | |||
uint8_t result; | |||
uint16_t data[8]; | |||
// Lecture de 8 registres à partir de l'adresse 0x0000 | |||
result = node.readInputRegisters(0x0000, 8); | |||
if (result == node.ku8MBSuccess) { | |||
// Stocker les données dans le tableau `data` | |||
for (int i = 0; i < 8; i++) { | |||
data[i] = node.getResponseBuffer(i); | |||
} | |||
// Mise à jour des variables globales | |||
voltage = data[0] * 0.01; | |||
current = data[1] * 0.01; | |||
power = (data[3] << 16 | data[2]) * 0.1; | |||
energy = (data[5] << 16 | data[4]) * 1; | |||
// Affichage des valeurs lues sur le port série | |||
printModbusValues(); | |||
} else { | |||
Serial.print("Erreur lors de la lecture des registres: "); | |||
Serial.println(result, HEX); | |||
} | |||
} | |||
void printModbusValues() { | |||
Serial.print("Tension: "); | |||
Serial.print(voltage); | |||
Serial.println(" V"); | |||
Serial.print("Courant: "); | |||
Serial.print(current); | |||
Serial.println(" A"); | |||
Serial.print("Puissance: "); | |||
Serial.print(power); | |||
Serial.println(" W"); | |||
Serial.print("Energie: "); | |||
Serial.print(energy); | |||
Serial.println(" Wh"); | |||
} | |||
void handleRoot() { | |||
String html = "<html><head><title>Données Modbus</title></head><body>"; | |||
html += "<h1>Données Modbus</h1>"; | |||
html += "<p><strong>Tension: </strong>" + String(voltage) + " V</p>"; | |||
html += "<p><strong>Courant: </strong>" + String(current) + " A</p>"; | |||
html += "<p><strong>Puissance: </strong>" + String(power) + " W</p>"; | |||
html += "<p><strong>Energie: </strong>" + String(energy) + " Wh</p>"; | |||
html += "</body></html>"; | |||
server.send(200, "text/html", html); | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> |
Version actuelle datée du 18 septembre 2024 à 13:39
Objectif du projet
Ce projet vise à doter un vélo électrique de capacités de mesure en temps réel des courants et tensions de charge en courant continu. L'objectif est de développer un module qui s'interface entre le chargeur d'origine et la batterie (système de gestion de batterie, BMS) du vélo, afin de surveiller à distance le niveau de charge de la batterie via un réseau sans fil.
Description du prototype
Le premier prototype est conçu avec des composants à faible coût pour tester la faisabilité du projet. Il repose sur :
- Un module PZEM-003 (Peacefair) : utilisé pour mesurer des paramètres essentiels tels que la tension continue, le courant, la puissance active et la consommation d'énergie.
- Deux connecteurs mâle/femelle XLR 4 broches
- Un ESP8266 (clone D1 mini) : microcontrôleur doté d'une connexion Wi-Fi, permettant la transmission des données de mesure vers un réseau sans fil.
Modifications techniques
Pour permettre la communication entre l'ESP8266 et le PZEM-003, deux fils ont été soudés en amont de la puce MAX485 du PZEM. Ainsi, l'ESP8266 peut directement dialoguer avec le module PZEM en utilisant le protocole UART.
Cette approche offre une solution simple et économique pour surveiller à distance le niveau de charge de la batterie d'un vélo électrique.
Étapes du Projet
- Préparation du Matériel
- Composants nécessaires :
- ESP8266 : module de communication Wi-Fi
- PZEM 003 : capteur de mesure de tension et courant
- Batterie de vélo électrique : pour mesurer la consommation réelle de l'énergie
- Optocoupleur : pour isoler les parties énergie et données
- Connecteurs femelles et mâles : pour connecter les fils sans couper le chargeur
- Outils :
- Soudure, câbles, breadboard, alimentation 3.3V
- Composants nécessaires :
- Installation des Composants
- Placer le PZEM 003 entre le chargeur et la batterie de vélo électrique.
- Utiliser les connecteurs femelles et mâles pour éviter de couper les fils du chargeur.
- Souder les fils :
- Souder deux fils à la sortie de l’optocoupleur pour récupérer les données en protocole UART.
- Connexion de l'optocoupleur :
- Alimenter l'optocoupleur en 3.3V depuis la breadboard de l’ESP8266.
- Placer le PZEM 003 entre le chargeur et la batterie de vélo électrique.
- Configuration du logiciel
- Télécharger et installer l’IDE Arduino :
- Aller sur
File > Preferences
et ajouter l’URL : http://arduino.esp8266.com/stable/package_esp8266com_index.json - Activer le package ESP8266 :
Tools > Board > Board Manager
et chercher « esp82 », puis cliquer sur « Installer ». - Sélectionner la carte :
Tools > Board > LOLIN D1 mini (clone)
.
- Aller sur
- Tester la carte :
- Ouvrir un exemple :
File > Examples > ESP8266 > Blink
et cliquer sur « Upload ».
- Ouvrir un exemple :
- Télécharger et installer l’IDE Arduino :
- Programmation de l’ESP8266
- Écrire le code :
- Inclure la bibliothèque
ModbusMaster
. - Configurer le port série pour communiquer avec le l'ESP82.
- Lire les registres du PZEM et afficher les données (tension, courant, puissance, énergie).
- Inclure la bibliothèque
- Installer la bibliothèque ModbusMaster :
- Aller dans l’IDE Arduino, cliquer sur l’icône « Bibliothèque », rechercher « ModbusMaster » et l’installer.
- Téléverser le code :
- Connecter l’ESP8266 à l’ordinateur et téléverser le code.
- Écrire le code :
- Connexion et tests
- Branchement de l’alimentation :
- Côté ESP8266 : entre GND (ground) et 3.3V.
- Côté PZEM 003 : sur les bornes 5V (en 3.3V) et GND.
- Vérifier les valeurs :
- Ouvrir le
Serial Monitor
dans l’IDE Arduino (Tools > Serial Monitor
). - Réinitialiser l’ESP8266 et vérifier les valeurs affichées toutes les 2 secondes (les valeurs de courant et puissance doivent être 0 si aucune charge n’est connectée).
- Ouvrir le
- Branchement de la batterie de vélo électrique :
- Connecter la batterie aux bornes P+ et P- du PZEM 003.
- Vérifier que la batterie charge bien.
- Branchement de l’alimentation :
- Vérification finale
- Observer les données :
- Assurer que les valeurs de tension, courant, puissance et énergie sont correctement mises à jour.
- Surveiller l’évolution des valeurs pendant la charge de la batterie de vélo électrique.
- Observer les données :
#include <ModbusMaster.h>
// Crée une instance de ModbusMaster
ModbusMaster node;
void setup() {
// Initialisation de la communication série
Serial.begin(9600);
Serial.println("Initialisation Modbus...");
// Configuration du port série pour Modbus
node.begin(1, Serial); // Adresse esclave 1, communication via le port série
}
void loop() {
uint8_t result;
uint16_t data[8];
// Lecture de 8 registres à partir de l'adresse 0x0000
result = node.readInputRegisters(0x0000, 8);
if (result == node.ku8MBSuccess) {
// Stocke les données lues dans le tableau `data`
for (int i = 0; i < 8; i++) {
data[i] = node.getResponseBuffer(i);
}
// Affichage des valeurs lues
float voltage = data[0] * 0.01; // La tension est à l'adresse 0x0000
float current = data[1] * 0.01; // Le courant est à l'adresse 0x0001
float power = (data[3] << 16 | data[2]) * 0.1; // La puissance est sur 2 registres, à l'adresse 0x0002 et 0x0003
float energy = (data[5] << 16 | data[4]) * 1; // L'énergie est sur 2 registres, à l'adresse 0x0004 et 0x0005
Serial.print("Tension: ");
Serial.print(voltage);
Serial.println(" V");
Serial.print("Courant: ");
Serial.print(current);
Serial.println(" A");
Serial.print("Puissance: ");
Serial.print(power);
Serial.println(" W");
Serial.print("Energie: ");
Serial.print(energy);
Serial.println(" Wh");
} else {
Serial.print("Erreur lors de la lecture des registres: ");
Serial.println(result, HEX);
}
delay(2000); // Pause de 2 secondes avant la prochaine lecture
}
Visualisation par serveur web
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ModbusMaster.h>
const char* ssid = "Pixelm";
const char* password = "bienveillance";
ESP8266WebServer server(80);
ModbusMaster node;
// Variables pour stocker les données Modbus
float voltage = 0;
float current = 0;
float power = 0;
float energy = 0;
// Constante pour le délai entre les lectures
const unsigned long READ_INTERVAL = 2000;
unsigned long lastReadTime = 0;
void setup() {
Serial.begin(9600);
Serial.println("Initialisation Modbus...");
// Initialisation Modbus
node.begin(1, Serial); // Adresse esclave 1, communication via le port série
// Connexion Wi-Fi
connectToWiFi();
// Initialisation serveur Web
server.on("/", handleRoot);
server.begin();
Serial.println("Serveur HTTP démarré.");
}
void loop() {
server.handleClient();
// Lecture des données Modbus toutes les READ_INTERVAL millisecondes
if (millis() - lastReadTime >= READ_INTERVAL) {
lastReadTime = millis();
readModbusData();
}
}
void connectToWiFi() {
WiFi.begin(ssid, password);
Serial.println("Connexion au Wi-Fi...");
unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED) {
if (millis() - startTime > 30000) { // Limite de 30 secondes pour la connexion
Serial.println("Erreur de connexion au Wi-Fi.");
return;
}
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("Connecté au Wi-Fi.");
Serial.print("Adresse IP: ");
Serial.println(WiFi.localIP());
}
void readModbusData() {
uint8_t result;
uint16_t data[8];
// Lecture de 8 registres à partir de l'adresse 0x0000
result = node.readInputRegisters(0x0000, 8);
if (result == node.ku8MBSuccess) {
// Stocker les données dans le tableau `data`
for (int i = 0; i < 8; i++) {
data[i] = node.getResponseBuffer(i);
}
// Mise à jour des variables globales
voltage = data[0] * 0.01;
current = data[1] * 0.01;
power = (data[3] << 16 | data[2]) * 0.1;
energy = (data[5] << 16 | data[4]) * 1;
// Affichage des valeurs lues sur le port série
printModbusValues();
} else {
Serial.print("Erreur lors de la lecture des registres: ");
Serial.println(result, HEX);
}
}
void printModbusValues() {
Serial.print("Tension: ");
Serial.print(voltage);
Serial.println(" V");
Serial.print("Courant: ");
Serial.print(current);
Serial.println(" A");
Serial.print("Puissance: ");
Serial.print(power);
Serial.println(" W");
Serial.print("Energie: ");
Serial.print(energy);
Serial.println(" Wh");
}
void handleRoot() {
String html = "<html><head><title>Données Modbus</title></head><body>";
html += "<h1>Données Modbus</h1>";
html += "<p><strong>Tension: </strong>" + String(voltage) + " V</p>";
html += "<p><strong>Courant: </strong>" + String(current) + " A</p>";
html += "<p><strong>Puissance: </strong>" + String(power) + " W</p>";
html += "<p><strong>Energie: </strong>" + String(energy) + " Wh</p>";
html += "</body></html>";
server.send(200, "text/html", html);
}