Forum: Mikrocontroller und Digitale Elektronik Arduino-ESP32 LEDC API ledcAttach() resolution


von Alexander (alecxs)


Lesenswert?

Wie muss ich den ESP32 konfigurieren damit ich ein PWM von 1Hz mit 50 % 
Tastverhältnis erreiche? Ich bekomme entweder Fehler für div_param oder 
der GPIO bleibt einfach HIGH.

https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/ledc.html#arduino-esp32-ledc-api

von Rainer W. (rawi)


Lesenswert?

Alexander schrieb:
> Ich bekomme entweder Fehler für div_param oder
> der GPIO bleibt einfach HIGH.

Wie hast du es denn probiert und welchen Wert gibt ledcAttach() zurück?

von Norbert (der_norbert)


Lesenswert?

Ohne den ESP im Detail zu kennen, manchmal reicht der interne Vorteiler 
einfach nicht aus für diese extrem niedrigen Raten.

von Alexander (alecxs)


Lesenswert?

Aus dem setup() heraus. Dachte schon es liegt an falschen Datentypen, 
habe auch mal direkt alle Werte hardcoded eingetragen. Hab schon ein 
paar verschiedene Auflösungen ausprobiert. Alles unter res < 10 gibt 
Fehlermeldung mit Return Code false, ab res = 10 true. Duty immer 2^res 
/ 2 eingesetzt, auch wenn das die Doku nicht so explizit hergibt.

E (622) ledc: requested frequency and duty resolution can not be 
achieved, try reducing freq_hz or duty_resolution. div_param=0
1
#define WO GPIO_NUM_32
2
void startWatchdog(gpio_num_t wpin) {
3
  const unsigned long wfreq = 1;    // 1 Hz
4
  const unsigned char wres = 11;    // resolution 2048
5
  const unsigned long wduty = 1024; // 50%
6
  ledcAttach((uint8_t) wpin, wfreq, wres);
7
  ledcWrite((uint8_t) wpin, wduty);
8
}
9
void setup() {
10
  pinMode(WO, OUTPUT);
11
  startWatchdog(WO);
12
}
13
void loop() {
14
  // main
15
}

ledcRead() und ledcReadFreq() geben den gesetzen Wert zurück bei höheren 
Frequenzen, aber mit 1 Hz kommt Wert 0 trotz Returncode true.

Kann es sein dass ledcWrite() in die main loop() muss?

: Bearbeitet durch User
von Rainer W. (rawi)


Lesenswert?

Alexander schrieb:
> Kann es sein dass ledcWrite() in die main loop() muss?

Nein, warum willst du das Tastverhältnis mehrere tausend Mal pro Sekunde 
neu setzen?

> ledcRead() und ledcReadFreq() geben den gesetzen Wert zurück bei höheren
> Frequenzen, aber mit 1 Hz kommt Wert 0 trotz Returncode true.

Worauf werden die übergebenen Parameter denn überprüft, um den 
Returncode zu generieren?
Wie sieht das erzeugte Signal bei freq=2 und eingestelltem 
Tastverhältnis 50% aus?
Sonst probiere einfach einmal eine für LEDs angemessene PWM-Frequenz, 
z.B. 1 kHz.

: Bearbeitet durch User
von Veit D. (devil-elec)


Angehängte Dateien:

Lesenswert?

Hallo,

siehe Bsp.

von Alexander (alecxs)


Lesenswert?

Hallo Veit,

danke, mit 5 kHz hab ich kein Problem (meine 4 kHz PWM funktionieren bei 
mir).

Rainer W. schrieb:
> Wie sieht das erzeugte Signal bei freq=2 und eingestelltem
> Tastverhältnis 50% aus?

Je nach resolution entweder return false oder Pin hängt auf HIGH. Ab 10 
Hz funktioniert es.

Rainer W. schrieb:
> Worauf werden die übergebenen Parameter denn überprüft, um den
> Returncode zu generieren?

Die Funktionen ledcRead() und ledcReadFreq() geben die gesetzte wfreq = 
ledc_get_freq(group, timer); und wduty = ledc_get_duty(group, channel); 
aus, so wie ich es mit ledcAttach() und ledcWrite() eingegeben habe.

ledcAttach() ist ein Wrapper und reicht den Returncode von 
ledcAttachChannel() durch. Wenn Du dort durchblickst sag Bescheid.

https://github.com/espressif/arduino-esp32/blob/release/v3.0.x/cores/esp32/esp32-hal-ledc.c#L94

Norbert schrieb:
> Ohne den ESP im Detail zu kennen, manchmal reicht der interne Vorteiler
> einfach nicht aus für diese extrem niedrigen Raten.

Angeblich soll die Clock automatisch umschalten, es stehen 80 MHz und 1 
Mhz zur Auswahl (LEDC_REF_TICK). Der GPIO32 ist ein RTC Pin und kann nur 
LEDC_LOW_SPEED_MODE.

https://github.com/espressif/esp-idf/blob/632e0c2a/components/hal/include/hal/ledc_types.h#L75

Leider habe ich diesen `div_param` noch nicht in den Sources gefunden. 
Ich lass dann mal grep über den gesamten Rechner laufen..
1
E (622) ledc: requested frequency and duty resolution can not be 
2
achieved, try reducing freq_hz or duty_resolution. div_param=0

: Bearbeitet durch User
von Alexander (alecxs)


Lesenswert?

Nüscht gefunden. Dafür so eine Art Bruteforce Sketch. Fängt mit 1 Hz an.

https://github.com/espressif/arduino-esp32/blob/release/v3.0.x/libraries/ESP32/examples/AnalogOut/ledcFrequency/ledcFrequency.ino
1
Bit resolution | Min Frequency [Hz] | Max Frequency [Hz]
2
             1 |                489 |           40078277
3
             2 |                245 |           20039138
4
             3 |                123 |           10019569
5
             4 |                 62 |            5009784
6
             5 |                 31 |            2504892
7
             6 |                 16 |            1252446
8
             7 |                  8 |             626223
9
             8 |                  4 |             313111
10
             9 |                  2 |             156555
11
            10 |                  1 |              78277
12
            11 |                  1 |              39138
13
            12 |                  1 |              19569
14
            13 |                  1 |               9784
15
            14 |                  1 |               4892
16
            15 |                  1 |               2446
17
            16 |                  1 |               1223
18
            17 |                  1 |                611
19
            18 |                  1 |                305
20
            19 |                  1 |                152
21
            20 |                  1 |                 76

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.