Moin Ich hatte es gestern schon mal hier gepostet, jetzt kann ich das Problem aber wohl auf den ESP8266 schieben. Aufbau: ESP steuert über 4 Pins mittels PWM 4 KSQ (TP4115) an denen je 9 3W LED hängen. Funktion: Die LED sollen langsam bis zur vollen Helligkeit hochgefahren werden Problem: gerade bei geringen Frequenzen gibt es ein helles Aufblitzen der LED Das Problem scheint bekannt: https://www.bountysource.com/issues/27026077-pwm-flickering-with-small-analogwrite-values Und zwei der Lösungsvorschläge habe ich auch schon getestet: Die PWM Frequenz auf 200Hz verringern, default sind 1kHz. analogWriteFreq(200); Die Taktfrequenz des ESP (in der ArduinoIDE) von 80 auf 160MHz erhöhen. Beide Maßnahmen brachten eine eindeutige Verbesserung, aber leider keine vollständige. Dann gibt es noch diese Möglichkeit: https://github.com/StefanBruens/ESP8266_new_pwm aber leider verstehe ich aber nicht was ich machen soll. Kann mir damit jemand helfen? oder habt ihr eine andere Lösung für das Problem? Danke und Gruß Kolja
:
Bearbeitet durch User
Kolja L. schrieb: > Problem: gerade bei geringen Frequenzen gibt es ein helles Aufblitzen > der LED > Die PWM Frequenz auf 200Hz verringern, default sind 1kHz. > analogWriteFreq(200); Die Aussagen wiedersprechen sich! Was macht denn dein ESP sonst noch so? Ich habe hier auch gerade einen RGB-Controller zusammengebaut 3x PWM, IR, WLAN. Zuvor hab ich mal getestet mit 3xPWM, I2C-OLED-Laufschrift alle 15ms aktualisiert und per UDP neuen Text fürs Display gesendet. Mit dem Logikanalysator ist auf der PWM auch dabei nur ein minimaler Jitter festzustellen. Sascha
Hallo Sascha Sascha W. schrieb: > Die Aussagen wiedersprechen sich! Wegen dem Wort Frequenz? Wenn ja, dann verstehe ich was du meinst. Mit "geringe Frequenzen" meinte ich den geringen Tastgrad. Also n etwa so: analogWrite(PIN1, 100); Sascha W. schrieb: > Was macht denn dein ESP sonst noch so? Nix, das ist der ganze Sketch:
1 | int brightness = 0; // how bright the LED is |
2 | int fadeAmount = 2; // how many points to fade the LED by |
3 | unsigned long currentTime; |
4 | unsigned long loopTime; |
5 | |
6 | void setup() |
7 | { |
8 | Serial.begin(115200); |
9 | pinMode(14, OUTPUT); |
10 | pinMode(12, OUTPUT); |
11 | pinMode(4, OUTPUT); |
12 | currentTime = millis(); |
13 | loopTime = currentTime; |
14 | // analogWriteFreq(200); |
15 | } |
16 | |
17 | void loop() { |
18 | currentTime = millis(); |
19 | if (currentTime >= (loopTime + 1000)) |
20 | { |
21 | analogWrite(14, brightness); |
22 | analogWrite(12, brightness); |
23 | analogWrite(4, brightness); |
24 | Serial.println(brightness); |
25 | |
26 | brightness = brightness + fadeAmount; |
27 | |
28 | if (brightness == 0 || brightness == 1000) |
29 | { |
30 | fadeAmount = -fadeAmount ; |
31 | } |
32 | loopTime = currentTime; // Updates loopTime |
33 | } |
34 | |
35 | } |
Gruß und Danke schon einmal Kolja
Hi Tritt das Flackern ca. alle Sekunde auf? Ja -> dann verschluckt sich der PWM für die analoge Spannung, da Dieser jede Sekunde neu gestartet wird. Gibt's im Arduino eine Möglichkeit, nur das Tastverhältnis des PWM anzupassen? Also NICHT wie hier, durch den neuen Befehl den PWM immer wieder neu anzustoßen. MfG
Patrick J. schrieb: > Tritt das Flackern ca. alle Sekunde auf? Nein, ehr bei bestimmten Werten. Habe gerade einen Wert zwischen 450 und 500 in Verdacht. Patrick J. schrieb: > Gibt's im Arduino eine Möglichkeit, nur das Tastverhältnis des PWM > anzupassen? Nicht dass ich wüsste. Zumindest habe ich es noch nirgendwo gesehen. Im Gegensatz zu den ArduinoBoards kann der ESP eine PWM mit 10 Bit, nur falls es jemand wundert, dass die Werte über 254 gehen.
Kolja L. schrieb: > Im Gegensatz zu den ArduinoBoards kann der ESP eine PWM mit 10 Bit, > nur falls es jemand wundert, dass die Werte über 254 gehen. und wo hast du den PWM-Range gesetzt? Ich sehe nichts in deinem Code. Sascha
:
Bearbeitet durch User
Sascha W. schrieb: > und wo hast du den PWM-Range gesetzt? Wenn ich es richtig verstanden habe, ist die per default fest auf 1kHz. Ich hatte sie mal testweise auf 200Hz runtergesetzt: // analogWriteFreq(200);
Sascha W. schrieb: > und wo hast du den PWM-Range gesetzt? Meinst du diese Zeile if (brightness == 0 || brightness == 1000) ?
Kolja L. schrieb: > Sascha W. schrieb: >> und wo hast du den PWM-Range gesetzt? > > Meinst du diese Zeile > if (brightness == 0 || brightness == 1000) ? Nein - beim ESP gibts da AnalogWriteRange() um die Auflösung der PWM einzustellen. Sascha
Ist auch auf default: Analog output analogWrite(pin, value) enables software PWM on the given pin. PWM may be used on pins 0 to 16. Call analogWrite(pin, 0) to disable PWM on the pin. value may be in range from 0 to PWMRANGE, which is equal to 1023 by default. PWM range may be changed by calling analogWriteRange(new_range). PWM frequency is 1kHz by default. Call analogWriteFreq(new_frequency) to change the frequency. Quelle:http://esp8266.github.io/Arduino/versions/2.0.0-rc2/doc/reference.html#analog-output
Hallo, konnte das Problem jetzt nachvollziehen! Tritt beim langsamen ändern der PWM-Werte bei mehreren aktivierten Kanälen auf. Problem ist ein Fehler in der core-Bibliothek "core_esp8266_wiring_pwm.c" die mit Version 2.3.0 noch als aktuell eingebunden wird, obwohl die lib in auf Github schon überarbeitet wurde.
1 | void ICACHE_RAM_ATTR pwm_timer_isr(){ |
2 | static uint8_t current_step = 0; |
3 | static uint8_t stepcount = 0; |
4 | static uint16_t steps[17]; |
5 | static uint32_t masks[17]; |
6 | if(current_step < stepcount){ |
7 | // T1L = (pwm_steps[current_step+1] * pwm_multiplier); //<-Fehler
|
8 | T1L = (steps[current_step+1] * pwm_multiplier); //<-richtig |
9 | TEIE |= TEIE1; |
10 | if(masks[current_step] & 0xFFFF) GPOC = masks[current_step] & 0xFFFF; |
11 | if(masks[current_step] & 0x10000) GP16O = 0; |
12 | current_step++; |
13 | } else { |
14 | current_step = 0; |
15 | stepcount = 0; |
16 | if(pwm_mask == 0) return; |
17 | T1L = (pwm_steps[current_step] * pwm_multiplier); |
18 | TEIE |= TEIE1; |
19 | if(pwm_mask & 0xFFFF) GPOS = pwm_mask & 0xFFFF; |
20 | if(pwm_mask & 0x10000) GP16O = 1; |
21 | stepcount = pwm_steps_len; |
22 | memcpy(steps, pwm_steps, (stepcount + 1) * 2); |
23 | memcpy(masks, pwm_steps_mask, stepcount * 4); |
24 | }
|
25 | }
|
Obwohl die Tabelle der Timerschritte doppelt gepuffert ist und nur beim Nulldurchgang aktualisiert wird, wird beim Durchlauf der ISR auf die ungepufferten Daten zugegriffen die durch zwischenzeitliches verändern der PWM-Werte nicht mehr mit der Maske für die Ausgänge übereinstimmt. Kleine Korrekur - siehe oben - und schon ist der Fehler weg. Sascha
Sascha W. schrieb: > Kleine Korrekur - siehe oben - und schon ist der Fehler weg. Das kann ich leider nicht bestätigen. Bei mir flackert es trozdem. Ich habe alles auf default. Bei meinem Sketch ist allerdings noch ein AMS2301 dran und er sendet jede Minute seine Temp Daten an eine Datenbank. Der Status wird an eine Website (wenn er abgefragt wird) gesendet (ca. jede Minute). Da wird was mit dem Interupt nicht stimmen, denke ich. Evtl. kann man das ja umgehen wenn man einen Arduino dazwischen schaltet, aber das ist ja wie mit Kanonen auf Spatzen schiessen. Sven P.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.