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.
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?
Ohne den ESP im Detail zu kennen, manchmal reicht der interne Vorteiler einfach nicht aus für diese extrem niedrigen Raten.
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 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
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?
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.
Hallo,
siehe Bsp.
Hallo Veit,
danke, mit 5 kHz hab ich kein Problem (meine 4 kHz PWM funktionieren bei mir).
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.
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
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 |
|
2 |
|
Nüscht gefunden. Dafür so eine Art Bruteforce Sketch. Fängt mit 1 Hz an.
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
Basierend auf den structs aus <driver/ledc.h> habe ich nun die Clock auf LEDC_REF_TICK manuell gesetzt. Das funktioniert soweit auch mit 10 Bit Auflösung und nun endlich mit 1 Hz.
https://github.com/espressif/esp-idf/blob/632e0c2a/components/driver/ledc/include/driver/ledc.h#L61
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
Allerdings kann ich nicht aus Arduino heraus auf die Logik mit ledc_handle.used_channels zugreifen. Mir ist nicht klar ob ledcAttachChannel() überhaupt erkennen kann dass ich bereits einen C̶h̶a̶n̶n̶e̶l̶ a̶t̶t̶a̶c̶h̶e̶d̶ habe / Kanal belegt (für Falk)... neues Problem. ledcAttach() würde ich ja für die übrigen PWM (4 kHz) trotzdem gerne nutzen.
Wo das div_param=0 herkommt ist mir noch ein Rätsel.
Hm, war da nicht irgendwas, daß bei den LEDC Funktionen irgendwas beim neuen Arduino-Core geändert wurde?
Ich hab mal bisschen gesucht, vielleicht bin ich auf dieses Problem gestoßen und der Pin war gar nicht HIGH.
https://forum.arduino.cc/t/ledcattach-on-esp32-for-different-frequencies/1331942
Ich hab mal bisschen gesucht, vielleicht bin ich auf dieses Problem gestoßen und der Pin war gar nicht HIGH.
Der Zustand eines Pins sollte sich doch herausfinden lassen. Hänge einfach einen Pull-Up und einen gleich großen Pull-Down Widerstand dran (z.B. 4k7) und miss die Spannung.
Ich hatte auch das neue
Tooltop ET828Pro für €27,99
kurz dran aber das Gerät ist irgendwie komisch, da muss man jedesmal die Range Taste drücken und dann analysiert es erstmal 2 Sekunden bevor es skaliert. Hab dann auf LED_BUILTIN gewechselt da ich keine Hand frei hatte für die Taste und zu faul es ordentlich aufzubauen, und die LED hatte halt nur geleuchtet nicht geblinkt.
Ich hab das nun nachgeholt, aber kann nicht bestätigen dass es sich um o.g. genanntes Problem, der Channel gehöre zur selben Group und würde daher die Frequenz durch nachfolgende ledcAttach() mit 4 kHz überschreiben, handelt; der Pin bleibt wohl tatsächlich einfach HIGH. Oder das Oszi rafft es nicht.
Das Gute ist, zumindest funktioniert die manuelle Methode mit hardcoded timer=0 und channel=0 für 1 Hz in einem Sketch zusammen mit den ledcAttach() mit 4 kHz. Ob das nun Zufall ist oder Glück, zufrieden bin ich damit noch nicht.
Laut Log wird der Channel angeblich überschrieben. Aber man weiß ja nicht wie die Debugausgaben zusammengeschustert sind, oder ob ledc_handle.used_channels einfach woanders anfängt mit zählen.
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
Ich hab mir jetzt die Kommentare in den Sources noch mal durchgelesen. In esp32-hal-ledc.c steht zum einen "Need to be fixed" das ist schon mal etwas beunruhigend.
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
Dazu hab ich noch die passende Doku gefunden (ist nicht der gleiche Link wie im Eröffnungspost) da gibt es noch eine Funktion zur Auswahl der Clock, wobei da nicht steht auf was das angewendet wird:
ledcSetCLockSource(LEDC_REF_CLK);
https://docs.espressif.com/projects/arduino-esp32/en/latest/api/ledc.html
Aus den Kommentaren in ledc.h geht hervor dass die Clock für alle Timer gilt, also global, aber so ganz eindeutig ist das noch nicht da wiederum steht "except esp32"
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
In ledc_types.h ist allerdings auch von "LEDC timer-specific clock sources" die Rede, weswegen ich unsicher bin ob meine Einstellung nun global gilt oder nicht.
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
Auf jeden Fall ist erstmal geklärt dass es keinen Konflikt mit dem Channel 0 gibt, da es nur zweimal 8x Channels gibt (0-7) und nicht einmal 16x Channels (0-15) so wie der Wrapper ledcAttach() das in ledc_handle.used_channels für sich trackt. Mein hardcoded LEDC_LOW_SPEED_MODE + LEDC_CHANNEL_0 entspricht also dem Arduino Channel 8. Das erklärt warum es überhaupt funktioniert.
In den in ledc.h "brief LEDC update channel parameters" liest man noch, nicht alle GPIO können den Highspeed Mode. Ich nehme an das bezieht sich nur auf GPIO32 + GPIO33, nicht auf alle RTC Pins? Wären sonst ziemlich viele..
1 |
|
2 |
|
3 |
|
Die Wrapper Funktion ledcAttach() unterscheidet jedenfalls nicht nach High speed / Low Speed, die weißt einfach den nächstbesten freien Channel 0-15 zu, ohne Einschränkung des GPIO. Das ist meiner Meinung nach ein Bug.
1 |
|
2 |
|
3 |
|
Das Channel Mapping in ledcAttachChannel() ist wiederum ziemlich eindeutig. Das ergibt eine fixe Zuordungstabelle.
1 |
|
2 |
|
3 |
|
Ich dachte daran eine eigene ledcAttach() Wrapper-Funktion als Override im Sketch zu hinterlegen, da ich ja ein eigenes Channel-Tracking brauche wenn ich da die GPIO nach Lowspeed/Highspeed korrekt zuordnen möchte, aber da ich nicht weiß welche GPIO das betrifft und ich nur den einen GPIO32 als Lowspeed brauche, lasse ich das.
Ich werde mich nun also mit ledcAttachChannel() begnügen und den Channel 8 selbst zuweisen, notfalls noch dazu mit ledcSetCLockSource()
Wie hast du es denn probiert und welchen Wert gibt ledcAttach() zurück?
keine Rückfragen, der To möchte nur Antworten und nicht lernen.
Thread zum trollen freigegeben.
mußt du nicht extra ansagen, weiß man sofort wenn man deinen Nick liest.
Blödsinn, das war Dein Auftritt hier.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.