« Optimiser la conso électrique du ESP32 » : différence entre les versions
Aller à la navigation
Aller à la recherche
Aucun résumé des modifications |
Aucun résumé des modifications |
||
| Ligne 21 : | Ligne 21 : | ||
#include <Adafruit_GFX.h> | #include <Adafruit_GFX.h> | ||
#include <Adafruit_SSD1306.h> | #include <Adafruit_SSD1306.h> | ||
#include <esp_sleep.h> | |||
#define SCREEN_WIDTH 128 | #define SCREEN_WIDTH 128 | ||
| Ligne 31 : | Ligne 32 : | ||
#define LED_PIN 2 | #define LED_PIN 2 | ||
// | // Variable conservée même après deep sleep | ||
RTC_DATA_ATTR int tour_count = 0; | |||
const int cadence_window_ms = 3000; | const int cadence_window_ms = 3000; | ||
unsigned long pedal_times[20]; | unsigned long pedal_times[20]; | ||
int pedal_index = 0; | int pedal_index = 0; | ||
unsigned long last_pedal_time = 0; | |||
unsigned long last_activity_time = 0; | |||
bool pedal_detected = false; | |||
float cadence_rpm = 0; | float cadence_rpm = 0; | ||
void IRAM_ATTR onPedal() { | void IRAM_ATTR onPedal() { | ||
pedal_detected = true; // Marque qu'une pédale a été détectée | |||
} | } | ||
| Ligne 68 : | Ligne 58 : | ||
Serial.begin(115200); | Serial.begin(115200); | ||
Wire.begin(); | Wire.begin(); | ||
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); | ||
display.clearDisplay(); | display.clearDisplay(); | ||
last_pedal_time = millis(); | |||
last_activity_time = millis(); | |||
} | } | ||
void loop() { | void loop() { | ||
unsigned long now = millis(); | unsigned long now = millis(); | ||
if ( | if (pedal_detected) { | ||
pedal_detected = false; | |||
last_pedal_time = now; | |||
last_activity_time = now; | |||
tour_count++; | |||
// | // Enregistrer le moment du pédalage | ||
pedal_times[pedal_index % 20] = now; | |||
pedal_index++; | |||
// Blink LED | |||
digitalWrite(LED_PIN, HIGH); | |||
delay(100); | |||
digitalWrite(LED_PIN, LOW); | |||
// Calcul cadence (nombre de tours sur 3s) | |||
int count = 0; | int count = 0; | ||
unsigned long first = 0, last = 0; | unsigned long first = 0, last = 0; | ||
for (int i = 0; i < 20; i++) { | for (int i = 0; i < 20; i++) { | ||
unsigned long t = pedal_times[i]; | unsigned long t = pedal_times[i]; | ||
| Ligne 117 : | Ligne 123 : | ||
display.setCursor(0, 50); | display.setCursor(0, 50); | ||
display.print(tour_count); | display.print(tour_count); | ||
display.display(); | |||
} | |||
// Mise en sommeil profond après 10s d'inactivité | |||
if (now - last_activity_time > 10000) { | |||
display.clearDisplay(); | |||
display.display(); | display.display(); | ||
display.ssd1306_command(SSD1306_DISPLAYOFF); // Éteint l'écran proprement | |||
// | esp_sleep_enable_ext1_wakeup(1ULL << GPIO_NUM_25, ESP_EXT1_WAKEUP_ALL_LOW); // Réveil par aimant (LOW) | ||
delay(100); // Laisse le temps au périphérique de s’éteindre proprement | |||
esp_deep_sleep_start(); // Entrée en sommeil profond | |||
} | } | ||
delay(50); // Pause légère pour alléger la boucle | |||
} | } | ||
Version du 1 août 2025 à 12:00
Les possibilités sont limitées en ESPHome mais très supérieures avec du code Arduino. Ce qui prend tout son sens lorsqu'on est avec une alimentation sur batterie.
https://youtube.com/shorts/S9HAANlcVAg?si=NyX30GI7u0vbySkP
ESPHome est très pratique pour des projets simples et rapidement connectés. Mais Arduino ouvre la voie à :
- une maîtrise totale du matériel
- une consommation minimale
- une interface UX personnalisée
et des fonctionnalités avancées (stockage, communication, veille contextuelle).
Voici 1) le code Arduino et 2) le code d'origine en ESPHome.
Arduino
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <esp_sleep.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Pins
#define HALL_SENSOR_PIN 25
#define LED_PIN 2
// Variable conservée même après deep sleep
RTC_DATA_ATTR int tour_count = 0;
const int cadence_window_ms = 3000;
unsigned long pedal_times[20];
int pedal_index = 0;
unsigned long last_pedal_time = 0;
unsigned long last_activity_time = 0;
bool pedal_detected = false;
float cadence_rpm = 0;
void IRAM_ATTR onPedal() {
pedal_detected = true; // Marque qu'une pédale a été détectée
}
void setup() {
pinMode(HALL_SENSOR_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
attachInterrupt(digitalPinToInterrupt(HALL_SENSOR_PIN), onPedal, FALLING);
Serial.begin(115200);
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
last_pedal_time = millis();
last_activity_time = millis();
}
void loop() {
unsigned long now = millis();
if (pedal_detected) {
pedal_detected = false;
last_pedal_time = now;
last_activity_time = now;
tour_count++;
// Enregistrer le moment du pédalage
pedal_times[pedal_index % 20] = now;
pedal_index++;
// Blink LED
digitalWrite(LED_PIN, HIGH);
delay(100);
digitalWrite(LED_PIN, LOW);
// Calcul cadence (nombre de tours sur 3s)
int count = 0;
unsigned long first = 0, last = 0;
for (int i = 0; i < 20; i++) {
unsigned long t = pedal_times[i];
if (now - t < cadence_window_ms) {
if (count == 0) first = t;
last = t;
count++;
}
}
if (count >= 2) {
float elapsed_min = (last - first) / 60000.0;
cadence_rpm = (count - 1) / elapsed_min;
} else {
cadence_rpm = 0;
}
// Affichage OLED
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("Cadence:");
display.setTextSize(2);
display.setCursor(0, 10);
display.print(cadence_rpm, 0);
display.print(" tpm");
display.setTextSize(1);
display.setCursor(0, 40);
display.print("Tours:");
display.setTextSize(2);
display.setCursor(0, 50);
display.print(tour_count);
display.display();
}
// Mise en sommeil profond après 10s d'inactivité
if (now - last_activity_time > 10000) {
display.clearDisplay();
display.display();
display.ssd1306_command(SSD1306_DISPLAYOFF); // Éteint l'écran proprement
esp_sleep_enable_ext1_wakeup(1ULL << GPIO_NUM_25, ESP_EXT1_WAKEUP_ALL_LOW); // Réveil par aimant (LOW)
delay(100); // Laisse le temps au périphérique de s’éteindre proprement
esp_deep_sleep_start(); // Entrée en sommeil profond
}
delay(50); // Pause légère pour alléger la boucle
}
ESPHome
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <esp_sleep.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Pins
#define HALL_SENSOR_PIN 25
#define LED_PIN 2
RTC_DATA_ATTR int tour_count = 0;
const int cadence_window_ms = 3000;
unsigned long pedal_times[20]; // tableau circulaire
int pedal_index = 0;
unsigned long last_pedal_time = 0;
unsigned long last_activity_time = 0;
bool pedal_detected = false;
float cadence_rpm = 0;
void IRAM_ATTR onPedal() {
pedal_detected = true;
}
void setup() {
pinMode(HALL_SENSOR_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
attachInterrupt(digitalPinToInterrupt(HALL_SENSOR_PIN), onPedal, FALLING);
Serial.begin(115200);
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
last_pedal_time = millis();
last_activity_time = millis();
}
void loop() {
unsigned long now = millis();
if (pedal_detected) {
pedal_detected = false;
last_pedal_time = now;
last_activity_time = now;
tour_count++;
// Stocker l'instant du pédalage
pedal_times[pedal_index % 20] = now;
pedal_index++;
// LED blink
digitalWrite(LED_PIN, HIGH);
delay(100);
digitalWrite(LED_PIN, LOW);
// Calcul de la cadence sur les 3 dernières secondes
int count = 0;
unsigned long first = 0, last = 0;
for (int i = 0; i < 20; i++) {
unsigned long t = pedal_times[i];
if (now - t < cadence_window_ms) {
if (count == 0) first = t;
last = t;
count++;
}
}
if (count >= 2) {
float elapsed_min = (last - first) / 60000.0;
cadence_rpm = (count - 1) / elapsed_min;
} else {
cadence_rpm = 0;
}
// Affichage OLED
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("Cadence:");
display.setTextSize(2);
display.setCursor(0, 10);
display.print(cadence_rpm, 0);
display.print(" tpm");
display.setTextSize(1);
display.setCursor(0, 40);
display.print("Tours:");
display.setTextSize(2);
display.setCursor(0, 50);
display.print(tour_count);
display.display();
}
// Si plus de 10s d'inactivité → deep sleep
if (now - last_activity_time > 10000) {
display.clearDisplay();
display.display();
display.ssd1306_command(SSD1306_DISPLAYOFF);
esp_sleep_enable_ext0_wakeup(GPIO_NUM_25, 0); // Réveil sur LOW (aimant)
delay(100);
esp_deep_sleep_start();
}
delay(50);
}