PWM sur ESP32

Bonjour

J'ai un ventilateur ARTIC F12 PWM PST que j'ai raccorder sur un ESP WROOM 32 comme ceci :


Avec ce code (sans la connection du "PWM") la vitesse de rotation par minute est bien retourner dans le terminal, il descend bien quand je freine le ventilateur avec le doigt.

#include <Arduino.h>
#define PIN_HALL 4

unsigned long previousMillisRpm = 0;
const long intervalCompteur = 1000;
long rpm;
uint32_t compteur = 0;

void IRAM_ATTR blinkFan() {
  compteur += 1;
}

void setup()
{
  Serial.begin(250000);
  pinMode(PIN_HALL, INPUT_PULLUP);
  attachInterrupt(PIN_HALL, blinkFan, RISING);
}


void loop()
{
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillisRpm >= intervalCompteur)
  {
    rpm = ((compteur * 60 * 1000 ) / intervalCompteur) / 2;
    compteur = 0;
    Serial.print("   rpm =");
    Serial.println(rpm);
    previousMillisRpm = currentMillis;
  }
}

mais lorsque je veut contrôler le PWM de celui ci en connectant la pin GPI02 avec ou sans ce code :

#include <Arduino.h>
#define PIN_BUTTON 4

volatile uint32_t DebounceTimer = 0;
unsigned long previousMillisRpm = 0;
const long intervalCompteur = 1000;
long rpm;
uint32_t compteur = 0;

void IRAM_ATTR blinkFan() {
  compteur += 1;
}

void setup()
{
  Serial.begin(250000);
  pinMode(PIN_BUTTON, INPUT_PULLUP);
  attachInterrupt(PIN_BUTTON, blinkFan, RISING);
  ledcAttachPin(2, 0); // broche, canal
  ledcSetup(0, 1000, 12); // canal, fréquence, resolution
}


void loop()
{
  unsigned long currentMillis = millis();
  ledcWrite(0, 500); //canal,PWM
  if (currentMillis - previousMillisRpm >= intervalCompteur)
  {
    rpm = ((compteur * 60 * 1000 ) / intervalCompteur) / 2;
    compteur = 0;
    Serial.print("   rpm =");
    Serial.println(rpm);
    previousMillisRpm = currentMillis;
  }
}

le rpm est erratique ou disproportionné .

De plus je ne comprend pas la ligne :

ledcSetup(0, 1000, 12); // canal, fréquence, resolution

j'ai parcouru cette page mais je n'ai pas compris la fréquence et la résolution....

Si quelqu'un peut corrigé mon erreur et m'expliquer la definition de ces 2 variables ?

Merci

compteur devrait être volatile

la résolution c’est la granularité avec laquelle vous allez découper “la tension” de sortie (en pratique le duty-cycle)

si vous dites

ledcSetup(0, 1000, 12); // canal, fréquence, resolution

vous aurez 212 valeurs possibles (4096) pour choisir entre 0V et 3.3V la sortie donc quand vous ditesledcWrite(0, 500); vous demandez 3.3V x 500/4096 = 0,4V (équivalent)

la fréquence, c’est l’inverse de la période. c’est le nombre de fois par seconde que le module va répéter le signal “modulé” (HIGH pendant le duty Cycle et LOW le reste du temps)

Ok je viens de comprendre merci j'ai modifier le ledcSetup avec une fréquence à 25000 comme conseillé sur le site de ritonduino et j'ai abaissé la résolution à 8, car 255 niveau suffisait sur le montage avec l'AVR .

par contre cela ne résout pas mon premier problème à savoir quand je gère le PWM les valeurs ne sont plus du tout bonne.

exemple :

PWM=46 rpm =32910
PWM=83 rpm =47940
PWM=176 rpm =232500
PWM=230 rpm =321630
PWM=255 rpm =341700

avec un Arduino cela fonctionne parfaitement :

PWM25 rpm=150
PMW255 rpm=1410

edit sur l'ESP je vois bien que le rpm descendre physiquement/visuellement sur le ventilateur il semble proche en PWM égal.

Comme dit précédemment la variable compteur devrait être volatile

L’avez vous changée ?

Bonjour

oui c’est la 1ere chose que j’ai faites hier soir :

#include <Arduino.h>
#define PIN_BUTTON 4


volatile uint32_t compteur = 0;
unsigned long previousMillisRpm = 0;
const long intervalCompteur = 1000;
long rpm;


void IRAM_ATTR blinkFan() {
  compteur += 1;
}

void setup()
{
  Serial.begin(250000);
  pinMode(PIN_BUTTON, INPUT_PULLUP);
  attachInterrupt(PIN_BUTTON, blinkFan, RISING);
  ledcAttachPin(2, 0); // broche, canal
  ledcSetup(0, 1000, 12); // canal, fréquence, resolution
}


void loop()
{
  unsigned long currentMillis = millis();
  ledcWrite(0, 500); //canal,PWM
  if (currentMillis - previousMillisRpm >= intervalCompteur)
  {
    rpm = ((compteur * 60 * 1000 ) / intervalCompteur) / 2;
    compteur = 0;
    Serial.print("   rpm =");
    Serial.println(rpm);
    previousMillisRpm = currentMillis;
  }
}

lorsque vous faites les maths il faut faire cela en section critique ou alors avec une copie de la valeur car vous pouvez encore avoir des interruptions qui viennent mettre le bazar sur vos 4 octets pendant le calcul.

un truc un peu comme cela (tapé ici, totalement non testé)

#include <Arduino.h>
#define PIN_BUTTON 4

const unsigned long intervalCompteur = 1000; // ms
volatile uint32_t compteur = 0;
unsigned long previousMillis, currentMillis;
unsigned long rpm;

void IRAM_ATTR blinkFan() {
  compteur++;
}


void setup()
{
  Serial.begin(250000);
  pinMode(PIN_BUTTON, INPUT_PULLUP);
  attachInterrupt(PIN_BUTTON, blinkFan, RISING);
  ledcAttachPin(2, 0); // broche, canal
  ledcSetup(0, 1000, 12); // canal, fréquence, resolution
  ledcWrite(0, 500); //canal,PWM
}


void loop()
{
  uint32_t copieCompteur;
  currentMillis = millis();
  uint32_t deltaT = currentMillis - previousMillis;
  if (deltaT >= intervalCompteur) {
    noInterrupts();
    copieCompteur = compteur;
    compteur = 0;
    interrupts();
    previousMillis = currentMillis;
    rpm = (copieCompteur * 30 * deltaT) / intervalCompteur;
    Serial.print("   rpm =");  Serial.println(rpm);
  }
}

avez vous essayé avec d’autres fréquences ?

Bonsoir

j'ai rajouter une resistance de pullup entre le pwm et le 3.3v et c'est bon.

Merci d'avoir pris le temps de répondre.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.