Servus zusammen, ich habe mir am Wochenende überlegt, ob ich meinen Heizungslüfter (Spaltpolmotor) nicht mit einer Wellenpaketsteuerung ausrüsten soll, da dies an anderen Heizungen mit entsprechendem Thermostad bereits geschieht. Ich wollte das ganze mit einem ESP8266 steuern und hab mal angefangen zu basteln, bis zu einem gewissen punkt hat auch alles funktioniert, ich habe ein Wellenpaket raus bekommen und alles hat funktioniert. Allerdings möchte ich immer die gleiche Anzahl an Halbwellen bekommen, damit ich dem Motor keine Gleichspannung zumuten muss, Leider ist der ESP8266 wohl zu langsam für 2 Interrupts mit der Geschwindigkeit von 50Hz, jetzt habe ich mir überlegt das ganze mit einer externen Schaltung zu realisieren. Leider habe ich grade keinen plan wie ich das realisieren könnte. Ich hab schon über einen Zähler nachgedacht der immer 2 Halbwellenzählt oder mit einem Zero Crossing Optokoppler, aber die zündende Idee fehlt mir noch. Hat von euch schon mal jemand eine Wellenpaketsteuerung gebaut oder villeicht schon mal ein ähnliches Problem gehabt und schon eine Lösung parat? Ich hoffe jemand kann mir helfen LG Chris :)
:
Bearbeitet durch User
Moin, wenn Du ein SSR, das im Nulldurchgang schaltet nimmst, sollte es eigentlich gehen. Die Impulsdauer und Pausendauer sollten dabei ein vielfaches von 20 mSec. betragen. Damit triffst Du immer 2 Halbwellen. Nur, wenn die Impulse genau den Nulldurchgang treffen, könnte es kurzzeitig Abweichungen geben, bis die Netzfrequenz etwas weiter läuft. Das wirst Du nicht merken. Für meine Phasenabschnittssteuerung habe ich einen ATTiny 4313 mit 6 MHz genommen und einen Zähler mit 100Hz vom Netz synchronisiert. Das schafft der locker. Da Dein ESP viel schneller läuft, sollten die 2 INT kein Problem sein. Gruß Carsten
Chris H. schrieb: > Leider ist der ESP8266 wohl zu langsam für 2 Interrupts mit der > Geschwindigkeit von 50Hz Bestimmt nicht - das muss am Programm liegen.
Chris H. schrieb: > damit ich dem Motor keine Gleichspannung zumuten muss, Leider ist der > ESP8266 wohl zu langsam für 2 Interrupts mit der Geschwindigkeit von > 50Hz, Sicher nicht. > mit einem Zero Crossing Optokoppler, aber die zündende Idee fehlt mir https://www.mikrocontroller.net/articles/230V#Nulldurchgangsdetektoren > villeicht schon mal ein ähnliches Problem gehabt und schon eine Lösung > parat? Mach's einfach richtig. Richtiger Nulldurchgangsdetektor, der die Phaseninformation erhält, der Rest ist bissel Logik in der Software. Der ESP32 langweilt sich dabei zu Tode.
Rainer W. schrieb: > Chris H. schrieb: >> Leider ist der ESP8266 wohl zu langsam für 2 Interrupts mit der >> Geschwindigkeit von 50Hz > > Bestimmt nicht - das muss am Programm liegen. Da hast du wohl recht, mein Programm funktioniert solange ich kein Display angeschlossen habe, mit Display entsteht manchmal eine Gleichspannung. Liegt wohl am Display program, aber wie kann ich das ganze beschleunigen, ich denke dass die Übertragung zum Display zu lange dauert. Es handelt sich um ein Display mit SH1106 Treiber.
:
Bearbeitet durch User
Beitrag #7854412 wurde vom Autor gelöscht.
Der Haken beim ESP8266 ist dass das eigene Programm mehrmals pro Sekunde vom WLAN Teil unterbrochen wird. Die Unterbrechungen dauern bei schlechtem Empfang und bei Funkstörungen manchmal über 100ms.
Sherlock 🕵🏽♂️ schrieb: > Der Haken beim ESP8266 ist dass das eigene Programm mehrmals pro > Sekunde vom WLAN Teil unterbrochen wird. Die Unterbrechungen dauern bei > schlechtem Empfang und bei Funkstörungen manchmal über 100ms. Deswegen wollte ich die Wellenpaketsteuerung über einen IC machen, damit der ESP nur sagen muss wie viele wellen er durchlassensoll.
Chris H. schrieb: > Leider ist der ESP8266 wohl zu langsam für 2 Interrupts mit der > Geschwindigkeit von 50Hz, Das ist er nicht, es hapert eher mit deinen Programmierfähigkeiten.
Michael B. schrieb: > Chris H. schrieb: >> Leider ist der ESP8266 wohl zu langsam für 2 Interrupts mit der >> Geschwindigkeit von 50Hz, > > Das ist er nicht, es hapert eher mit deinen Programmierfähigkeiten. ist möglich ich habe nicht gesagt dass ich perfekt programmieren kann, aber ich wüsste nicht wie ich mein Display schneller ansteuern kann. Ich habe kein Delay im Display loop. Aber evtl kannst du mir ja helfen meinen loop zu verbessern. void Displayloop() { if (millis() - vorherigeMillisDisplay >= displayIntervall) { vorherigeMillisDisplay = millis(); bool updateNeeded = false; // Wird auf true gesetzt, wenn sich etwas geändert hat display.setTextSize(2); display.setTextColor(SH110X_WHITE); // Temperatur nur aktualisieren, wenn sich der Wert geändert hat if (TempBME != prevTempBME) { prevTempBME = TempBME; display.fillRect(0, 0, 128, 16, SH110X_BLACK); // Bereich überschreiben display.setCursor(0, 0); display.print(F("IST ")); display.print(TempBME); display.print(F("C")); updateNeeded = true; } // Counter nur aktualisieren, wenn sich der Wert geändert hat if (counter != prevCounter) { prevCounter = counter; display.fillRect(0, 20, 128, 16, SH110X_BLACK); display.setCursor(0, 20); display.print("Soll"); updateNeeded = true; } // Dimmersollwert nur aktualisieren, wenn sich der Wert geändert hat if (DimmersollWert != prevDimmersollWert) { prevDimmersollWert = DimmersollWert; display.fillRect(0, 40, 128, 16, SH110X_BLACK); display.setCursor(0, 40); display.print(DimmersollWert); updateNeeded = true; } // Display nur aktualisieren, wenn sich was geändert hat if (updateNeeded) { display.display(); } } }
:
Bearbeitet durch User
Moin, ein Vorschlag zur Lösung: Nimm einen kleinen ATTiny 84 o.Ä. und takte den mit 3,27800MHz. Der hat einen 16 Bit Timer, den Du als „Vorteiler“ nimmst und in Mode4 CTC einstellst. Mit OCR1A legst Du die Länge der Wellenpakete fest und lässt den Ausgang OCR1A toggeln. Dann verbindest Du den Ausgang PA6 mit dem Eingang vom 8 Bit Timer 0 PA3 (T0) zum Triggern. Den stellst Du auf Mode4 Fast PWM und kannst mit OCR0A Deine gewünschte Leistung in 255 Stufen einstellen. Den Datenaustausch zum ESP kannst Du über die serielle Schnittstelle machen. Zusätzlich sind genügend Eingänge für Taster zum manuellen Bedienen vorhanden. Viel Erfolg Carsten
Chris H. schrieb: > Michael B. schrieb: >> Chris H. schrieb: >>> Leider ist der ESP8266 wohl zu langsam für 2 Interrupts mit der >>> Geschwindigkeit von 50Hz, >> >> Das ist er nicht, es hapert eher mit deinen Programmierfähigkeiten. > > ist möglich ich habe nicht gesagt dass ich perfekt programmieren kann, > aber ich wüsste nicht wie ich mein Display schneller ansteuern kann. > Ich habe kein Delay im Display loop. > Aber evtl kannst du mir ja helfen meinen loop zu verbessern. Wieso? Wenn man WIRKLICH einen Interrupt nutzt, hat der IMMER Priorität und kann das laufende Hauptprogramm unterbrechen. Wo ist der bei dir?
Falk B. schrieb: > Chris H. schrieb: >> Michael B. schrieb: >>> Chris H. schrieb: >>>> Leider ist der ESP8266 wohl zu langsam für 2 Interrupts mit der >>>> Geschwindigkeit von 50Hz, >>> >>> Das ist er nicht, es hapert eher mit deinen Programmierfähigkeiten. >> >> ist möglich ich habe nicht gesagt dass ich perfekt programmieren kann, >> aber ich wüsste nicht wie ich mein Display schneller ansteuern kann. >> Ich habe kein Delay im Display loop. >> Aber evtl kannst du mir ja helfen meinen loop zu verbessern. > > Wieso? Wenn man WIRKLICH einen Interrupt nutzt, hat der IMMER Priorität > und kann das laufende Hauptprogramm unterbrechen. Wo ist der bei dir? mein Programm ist zu groß um das ganze hier zu posten, der interrupt ist in einem anderen Programmteil untergebracht //Programm das bei interrupt ausgeführt wird /Positivehalbwelle void IRAM_ATTR Positiv() { // Wenn die Verzögerung noch nicht vergangen ist, den Interrupt ignorieren if (millis() - last_positiv_time >= debounce_positiv) { positiv++; // Zähler erhöhen last_positiv_time = millis(); // Speichern der aktuellen Zeit } } //Programm das bei interrup ausgeführt wird/Negativehalbwelle void IRAM_ATTR Negativ() { if (millis() - last_negativ_time >= debounce_negativ) { negativ++; // Zähler erhöhen last_negativ_time = millis(); // Speichern der aktuellen Zeit } }
Chris H. schrieb: >> Wieso? Wenn man WIRKLICH einen Interrupt nutzt, hat der IMMER Priorität >> und kann das laufende Hauptprogramm unterbrechen. Wo ist der bei dir? > > mein Programm ist zu groß um das ganze hier zu posten, Glaub ich nicht, man kann hier mehrere MB anhängen . . . > der interrupt ist > in einem anderen Programmteil untergebracht > //Programm das bei interrupt ausgeführt wird /Positivehalbwelle > void IRAM_ATTR Positiv() { > // Wenn die Verzögerung noch nicht vergangen ist, den Interrupt > ignorieren > if (millis() - last_positiv_time >= debounce_positiv) { > positiv++; // Zähler erhöhen > last_positiv_time = millis(); // Speichern der aktuellen Zeit > } > } Auch wenn das hier nicht das zentrale Problem ist, sollte man die aktuelle Zeit nur einmal lesen und dann damit arbeiten. now = millis(); Aber ich sehe hier keinerlei Aktion zum Phasenanschnitt! Eigentlich muss hier eine Verzögerung per Timer gestartet werden, die dann nach xx ms den Phasenanschitt einschaltet. Diese Aktion muss ebenfall mit einem Interrupt passieren, damit das nahezu verzögerungsfrei zu jeder Zeit gemacht werden kann. Man kann NICHT in der Hauptschleife hoffen, daß man den Zeitpunkt schon irgendwie gut genug erwischt! Eine Abfrage mit dem Konzept millis() ala Arduino ist hier untauglich! Hier muss man an die echten Timer des Controllers ran! Die sind nur manuell konfigurierbar und nutzbar. Oder man findet eine Bibliothek, die das macht. Außerdem fehlt die Logik für die gerade Anzahl der Halbwellen.
Chris H. schrieb: > Da hast du wohl recht, mein Programm funktioniert solange ich kein > Display angeschlossen habe, mit Display entsteht manchmal eine > Gleichspannung. Liegt wohl am Display program, aber wie kann ich das > ganze beschleunigen, ich denke dass die Übertragung zum Display zu lange > dauert. Dein Display wird nicht alle paar Millisekunden neu beschrieben, vermute ich mal. Dein Motor hat eine mechanische Trägheit. Du könntest als Workaround die Ansteuerung des Motors sperren, solange das Display beschrieben wird, was ja wohl nur alle XX-Sekunden passieren muß. Bei mir, andere Umgebung / andere Anwendungen, vergleiche ich Werte und beschreibe das Display nur bei Änderungen anstatt permanent zyklisch.
Chris H. schrieb: > Aber evtl kannst du mir ja helfen meinen loop zu verbessern. Wenn dieser code nicht innerhalb eines Interrupts abläuft, ist er ja durch Interrupts untebrechbar, sollte also nicht Ursache des Problems sein. Allerdings weiss man nicht, ob irgendwelche Klassenfunktionen von display die Interupts sperren, z.B. display.display() wäre so ein Kandidat. Insgesamt ist der Code enorm aufwändig, jede der aufgerufenen Klassenfunktionen isg ja extrem mächtig, z.B. display.print(). Aber, wenn die Interrupts nicht gesperrt werden und dir die Performance reicht, ist es letztlich egal.
Michael B. schrieb: > Chris H. schrieb: >> Aber evtl kannst du mir ja helfen meinen loop zu verbessern. > > Wenn dieser code nicht innerhalb eines Interrupts abläuft, ist er ja > durch Interrupts untebrechbar, sollte also nicht Ursache des Problems > sein. > > Allerdings weiss man nicht, ob irgendwelche Klassenfunktionen von > display die Interupts sperren, z.B. display.display() wäre so ein > Kandidat. > > Insgesamt ist der Code enorm aufwändig, jede der aufgerufenen > Klassenfunktionen isg ja extrem mächtig, z.B. display.print(). > > Aber, wenn die Interrupts nicht gesperrt werden und dir die Performance > reicht, ist es letztlich egal. ich hab jetz mal alles unnötige deaktiviert aber immer noch das selbe problem, villeicht liegts tatsächlich an meinem Programm, scheinbar tritt der fehler auch nur bei längeren wellenpaketen auf, jedenfalls habe ich mim Oszi die wellen bis 20 Wellen gezählt, dort passt alles, aber wenn ich bei 98 halbwellen bin (Laut programm) dann schneidet er mir nur noch eine Halbwelle ab und nicht 2 Halbwellen void Wellenpacketsteuerungsetup(){ pinMode(Dimmer, OUTPUT); WP = 100; //größe des Wellenpaketes } void Wellenpacketsteuerung(){ DimmersollWert = counter; Halbwellen=positiv+negativ+1; //muss 1 sein, da wenn dass Programm startet, befindet sich die Phase bereits in der ersten halbwelle und wird sonst nicht gezählt //Wird benötigt wenn der Sollwert auf 1% geht, da diese sonst nicht ausgegeben werden. if (DimmersollWert==1){ DimmersollWert=2; } else if (counter < 0){ counter = 0; } else if (counter > WP){ counter = WP; } // Dimmer einschalten für die ersten 10 Halbwellen if (DimmersollWert > 0){ if (Halbwellen < DimmersollWert) { digitalWrite(Dimmer, HIGH); // Dimmer ein //Serial.println(Halbwellen); } else { // Dimmer ausschalten nur bei geraden Wellen if ((Halbwellen & 1) == 0) { digitalWrite(Dimmer, LOW); // Dimmer aus //Serial.println("AUS" + String(Halbwellen)); } } } else { digitalWrite(Dimmer, LOW); // Dimmer aus //Serial.println("AUS"); } // Nach 100 Halbwellen zähler zurücksetzen if ((Halbwellen >= WP) || (DimmersollWert==0)) { positiv = 0; negativ = 0; } }
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.