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?
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
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.
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.
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.
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.
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.
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
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?
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
}
}
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.
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.
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 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");
}