« Optimiser la conso électrique du ESP32 » : différence entre les versions

De Wiki de Mémoire Vive
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


// Compteur
// Variable conservée même après deep sleep
volatile int tour_count = 0;
RTC_DATA_ATTR int tour_count = 0;
unsigned long last_pedal_time = 0;
 
const int cadence_window_ms = 3000;
const int cadence_window_ms = 3000;
unsigned long pedal_times[20]; // Pour une fenêtre glissante
unsigned long pedal_times[20];
int pedal_index = 0;
int pedal_index = 0;


// Cadence
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() {
   unsigned long now = millis();
   pedal_detected = true; // Marque qu'une pédale a été détectée
 
  // Éviter les rebonds ou doubles déclenchements
  if (now - last_pedal_time < 150) return;
  last_pedal_time = now;
 
  // Incrémenter le compteur
  tour_count++;
 
  // Ajouter timestamp
  pedal_times[pedal_index % 20] = now;
  pedal_index++;
 
  // LED blink
  digitalWrite(LED_PIN, HIGH);
}
}


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() {
  static unsigned long last_update = 0;
   unsigned long now = millis();
   unsigned long now = millis();


   if (now - last_update > 1000) {
   if (pedal_detected) {
     last_update = now;
     pedal_detected = false;
    last_pedal_time = now;
    last_activity_time = now;
    tour_count++;


     // Nettoyer les timestamps vieux de plus de 3 sec
     // 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


     // Éteindre LED après affichage
     esp_sleep_enable_ext1_wakeup(1ULL << GPIO_NUM_25, ESP_EXT1_WAKEUP_ALL_LOW);  // Réveil par aimant (LOW)
     digitalWrite(LED_PIN, 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);
}