Faire varier une sortie PWM en fonction de la temperature

Bonjour,

Je voudrai faire varier une sortie PWM en fonction de la temperature d’un capteur en entrée
J’utilise un ESP32 S3 avec esphome

Mon capteur de temperature est un atlas EZO-RTD
J’ai reussi à le calibrer avec une temperature de 30°c

Je voudrais par exemple dire que si ma temperature varie de 20°c à 30°c sur mon EZO-RTD
ma tension de sortie de mon PWM passe de 0 à 100%

J’arrive a gerer une sortie PWM avec Plaform: ledc mais je ne sais pas faire le lien entre rtd_ezo et sortie_pwm_temp pour gerer cette proportionnalité

Est ce que quelqu’un peu me guider ?

Merci

Cédric

# Declaration capteur temperature
  - platform: ezo
    id: rtd_ezo
    name: "Temperature Measurement"
    address: 102
    accuracy_decimals: 2
    unit_of_measurement: "°C"
    update_interval: 10s


# export temperature pour automate
output:
  - platform: ledc
    pin: GPIO0
    id: sortie_pwm_temp  
    frequency: 1000 hz

fan:
  - platform: speed
    output: sortie_pwm_temp
    name: "sortie_pwm_temp"
    id: pwm_temp 
    

Hello,

J’ai fait comme ça

sensor:

  - platform: pulse_counter
    pin: GPIO13              # Ventilateur 1 - Tachymètre
    name: "PWM Fan 1 RPM"
    id: fan1_pulse
    unit_of_measurement: 'RPM'
    filters:
      - multiply: 0.5
    count_mode:
      rising_edge: INCREMENT
      falling_edge: DISABLE
    update_interval: 3s
  - platform: pulse_counter
    pin: GPIO14              # Ventilateur 2 - Tachymètre
    name: "PWM Fan 2 RPM"
    id: fan2_pulse
    unit_of_measurement: 'RPM'
    filters:
      - multiply: 0.5
    count_mode:
      rising_edge: INCREMENT
      falling_edge: DISABLE
    update_interval: 3s
  - platform: pulse_counter
    pin: GPIO16              # Ventilateur 3 - Tachymètre
    name: "PWM Fan 3 RPM"
    id: fan3_pulse
    unit_of_measurement: 'RPM'
    filters:
      - multiply: 0.5
    count_mode:
      rising_edge: INCREMENT
      falling_edge: DISABLE
    update_interval: 3s
  - platform: pulse_counter
    pin: GPIO17              # Ventilateur 4 - Tachymètre
    name: "PWM Fan 4 RPM"
    id: fan4_pulse
    unit_of_measurement: 'RPM'
    filters:
      - multiply: 0.5
    count_mode:
      rising_edge: INCREMENT
      falling_edge: DISABLE
    update_interval: 3s
  - platform: pulse_counter
    pin: GPIO18              # Ventilateur 5 - Tachymètre
    name: "PWM Fan 5 RPM"
    id: fan5_pulse
    unit_of_measurement: 'RPM'
    filters:
      - multiply: 0.5
    count_mode:
      rising_edge: INCREMENT
      falling_edge: DISABLE
    update_interval: 3s

  - platform: dht
    pin: 27
    temperature:
      name: "Temperature"
      id: rack_temperature
      accuracy_decimals: 2
      device_class: "temperature"
      filters:
        - offset: -5.0
        # Filtre pour ignorer les valeurs aberrantes
        - filter_out: nan
        - heartbeat: 60s  # Si pas de mise à jour pendant 60s, garde la dernière valeur
        - sliding_window_moving_average:
            window_size: 3
            send_every: 1
      # Logique de contrôle de température
      on_value:
        then:
          - if:
              condition:
                # Vérifier que la valeur est valide (entre 0 et 50°C)
                lambda: 'return !isnan(x) && x > 0.0 && x < 50.0;'
              then:
                - if:
                    condition:
                      lambda: 'return x < 25.0;'
                    then:
                      # Température < 24°C : arrêt des ventilateurs
                      - fan.turn_off: fan1
                      - fan.turn_off: fan2
                      - fan.turn_off: fan3
                      - fan.turn_off: fan4
                      - fan.turn_off: fan5
                      - logger.log: "Température basse, ventilateurs arrêtés"
                    else:
                      - if:
                          condition:
                            lambda: 'return x >= 25.0 && x <= 30.0;'
                          then:
                            # Température entre 25°C et 30°C : contrôle proportionnel
                            - lambda: |-
                                float temp = x;
                                // Calcul du pourcentage : 0% à 25°C, 100% à 30°C
                                float percentage = (temp - 25.0) / (30.0 - 25.0);
                                percentage = max(0.2f, min(1.0f, percentage)); // 20% minimum
                                
                                // Appliquer la vitesse aux 5 ventilateurs
                                auto call1 = id(fan1).turn_on();
                                call1.set_speed(percentage * 100);
                                call1.perform();
                                
                                auto call2 = id(fan2).turn_on();
                                call2.set_speed(percentage * 100);
                                call2.perform();
                                
                                auto call3 = id(fan3).turn_on();
                                call3.set_speed(percentage * 100);
                                call3.perform();
                                
                                auto call4 = id(fan4).turn_on();
                                call4.set_speed(percentage * 100);
                                call4.perform();
                                
                                auto call5 = id(fan5).turn_on();
                                call5.set_speed(percentage * 100);
                                call5.perform();
                                
                                ESP_LOGI("main", "Température: %.1f°C, Ventilateurs: %.0f%%", temp, percentage * 100);
                          else:
                            # Température > 30°C : ventilateurs à 100%
                            - fan.turn_on:
                                id: fan1
                                speed: 100
                            - fan.turn_on:
                                id: fan2
                                speed: 100
                            - fan.turn_on:
                                id: fan3
                                speed: 100
                            - fan.turn_on:
                                id: fan4
                                speed: 100
                            - fan.turn_on:
                                id: fan5
                                speed: 100
                            - logger.log: "Température élevée, ventilateurs à 100%"
              else:
                # Valeur invalide détectée, on ignore
                - logger.log: 
                    format: "Lecture température invalide ignorée: %.1f"
                    args: [ 'x' ]
output:
  - platform: ledc
    pin: GPIO12
    frequency: 20000 Hz
    id: fan1_pwm
  - platform: ledc
    pin: GPIO19
    frequency: 20000 Hz
    id: fan2_pwm
  - platform: ledc
    pin: GPIO21
    frequency: 20000 Hz
    id: fan3_pwm
  - platform: ledc
    pin: GPIO22
    frequency: 20000 Hz
    id: fan4_pwm
  - platform: ledc
    pin: GPIO23
    frequency: 20000 Hz
    id: fan5_pwm

fan:
  - platform: speed
    output: fan1_pwm
    name: "PWM Fan 1"
    id: fan1
  - platform: speed
    output: fan2_pwm
    name: "PWM Fan 2"
    id: fan2
  - platform: speed
    output: fan3_pwm
    name: "PWM Fan 3"
    id: fan3
  - platform: speed
    output: fan4_pwm
    name: "PWM Fan 4"
    id: fan4
  - platform: speed
    output: fan5_pwm
    name: "PWM Fan 5"
    id: fan5

sous les 25°C les ventilos sont off et au dessus ça commence à souffler à 20% jusque 100% à 30°C et plus

1

cdt

1 « J'aime »

Bonsoir,

Merci pour le partage mais j’ai besoin de faire une solution avec des floats pour suivre l’évolution de la tension de mon capteur de temperature. Avec des seuils ca ne va pas fonctionner.

J’ai essayé avec ledc mais les floats ne sont pas pris en compte et mes competences sont limitées

Si vous avez une idée…

En tout cas merci de ton aide
Cédric

1 « J'aime »

Re,

Faudrait tester, j’ai pas creusé

on_value:
  then:
    - lambda: |-
        float t = x;

        // Vérifier la validité
        if (isnan(t) || t < 0 || t > 80) {
          ESP_LOGW("temp", "Valeur invalide ignorée: %.2f", t);
          return;
        }

        // ---- Courbe proportionnelle  ----
        // 0% à 20°C, 100% à 40°C
        float speed = (t - 20.0f) / (40.0f - 20.0f);

        // Limitation entre 0 et 1
        speed = clamp(speed, 0.0f, 1.0f);

        // ---- Application de la vitesse ----
        id(fan1).set_speed(speed * 100);
        id(fan2).set_speed(speed * 100);
        id(fan3).set_speed(speed * 100);
        id(fan4).set_speed(speed * 100);
        id(fan5).set_speed(speed * 100);

        // Log
        ESP_LOGI("control", "T=%.2f°C → PWM=%.0f%%", t, speed * 100);

exponentielle

float speed = pow((t - 20.0f) / 20.0f, 2);
speed = clamp(speed, 0.0f, 1.0f);

logarithmique

float speed = log1p(max(0.0f, t - 20.0f)) / log1p(20.0f);
speed = clamp(speed, 0.0f, 1.0f);

cdt