Von einem Arbeitskollegen habe ich zwei alte Funk-Steckdosen abgestaubt (Typ MBO Telecommander 01). "Kannst du damit etwas anfangen?" hat er gefragt.
Er hatte nur noch einen Sender und der wird mit teuren kleinen 12 V Batterien betrieben. Direkt kann man das Gerät nicht mehr wirklich verwenden. Moderne Funksteckdosen sind außerdem preiswert zu erhalten. Aber vielleicht kann man doch etwas damit machen.
Also erst einmal aufschrauben. Das befriedigt zumindest die Neugier. |
Der extrem preiswerte ESP8266 brachte mich auf die Idee, die Steckdose so umzubauen, dass sie über das WLAN angesteuert werden kann.
Sehr schnell kann man die wesentlichen Schaltungsblöcke identifizieren:
Der HF-Teil ist uninteressant. Die beiden anderen Blöcke kann man evtl. weiter verwenden. Deshalb habe ich für diese beiden den Schaltplan ermittelt.
Relais-Treiber | Stromversorgung | Positionierung der Blöcke | HF-Teil und Decoder entfernt |
Ist BLYNK zur Steuerung geeignet? Oder OpenHAB? Oder MQTT?
Gibt es schon:
Plan:
Siehe: esp-arduino-apboot
Stabiler HTTP 1.1 WLAN Webserver mit dem ESP8266 Microcontroller
Hier steht etwas zum initialen Verhalten der GPIOs. Wenn das korrekt ist, muss ich mir noch etwas einfallen lassen. Z.B. per Inverter?
Die elektrische Leistung berechnet sich aus dem Produkt der Augenblickswerte von Spannung und Strom P = U · I. Bei einer Wechselspannung ändert sich dieser Wert von einem Zeitpunkt zum nächsten. Bei periodischen Vorgängen ist es deshalb praktischer mit den Effektivwerten zu arbeiten. Hier wird der Mittelwert über eine Periode herangezogen. Der Effektivwert der Netzspannung liegt konstant bei 230 Volt. Deshalb reicht zur Leistungsbestimmung die Messung des geräteabhängigen effektiven Stroms: P = Ueff · Ieff. Der Strom wird über einen definierten Zeitraum in konstanten Zeitabständen gemessen und die (Absolut-) Beträge werden summiert (Integration). Die sich so ergebende Summe sollte proportional zur Leistungsaufnahme des angeschlossenen Verbrauchers sein.
Anmerkung 1: Anstatt die Absolutbeträge zu addieren müsste man eigentlich zur Ermittlung der Effektivwerte vor der Summierung die einzelnen Messwerte quadrieren und zum zum Schluss die Quadratwurzel aus der Summe ziehen. Auch dieses habe ich versucht. Es ändert sich nicht viel. Der Proportionalitätsfaktor ist ein anderer und die Standardabweichung sinkt.
Anmerkung 2: Genau genommen müsste man auch die Phasenlage zwischen Strom und Spannung berücksichtigen. Sind Spannung und Strom nicht in Phase, ist die Wirkleistung geringer: P = Ueff · Ieff · cos φ (cos φ ≤ 1). Da es in diesem Projekt nur darum geht, den Verbrauch des angeschlossenen Geräts abzuschätzen (an oder aus, Glühbirne oder Kochplatte), wird die Phasenlage nicht berücksichtigt, d.h. es wird eigentlich die Scheinleistung bestimmt.
Die Zeitabstände zwischen den einzelnen Messungen müssen so klein sein, dass die Stromverlaufskurve noch gut nachvollzogen werden kann. Bei einer Netzfrequenz von 50 Hz sollten die Messfrequenz bei 500-1.000 Hz liegen. Dann hätte man 5-10 Messpunkte pro Halbwelle. Der ESP8266 schafft gut 2.000 Hz (s. hier).
Die Anzahl der Messpunkte sollte so groß sein, dass sich Störungen (Rauschen) herausmitteln. Die Messung über 100 Messpunkte (entsprechend 5-10 Perioden) sollte ausreichen.
Da das Einstellen der Parameter auf dem ESP8266 nicht besonders komfortabel ist, sollen Details zunächst sollen über eine Simulation geklärt werden (s.u.).
Für die Strommessung gibt es verschiedene Methoden. Für dieses Projekt kommen allerdings nur solche Stromsensoren in Frage, die eine galvanische Trennung von der Netzspannung sicherstellen. Durch Zufall bin ich auf diese preiswerten kleinen Boards zur Strommessung gestoßen (Stückpreis 2-3 €). Sie beinhalten einen ACS712T, einen linearen Stromsensor auf Hall-Effekt-Basis.
Der Sensor liefert eine zum durchfließenden Strom proportionale Ausgangsspannung zwischen 0 und 5 V. Dabei entsprechen 2,5 V einem Strom von 0 A. 5 V Ausgangspannung werden bei maximalem Strom in positiver und 0 V bei maximalem Strom in negativer Richtung geliefert. Es gibt Versionen für 5 A, 20 A und 30 A Maximalstrom. Die Chips sind bis zum Fünffachen des Maximalstroms belastbar.
Mit der 5A-Variante lassen sich Wechselspannung-Effektiv-Ströme von 5 A / √2 ~ 3,5 A ermitteln. Bei 230 V lassen sich somit Leistungen bis zu 230 V * 3,5 A ~ 800 W uneingeschränkt messen. Bei Leistungen über etwa 800 W können die Stromspitzenwerte nicht mehr ausgewertet werden, sie werden gekappt. Werte bis zu 2,5 kW können durchaus noch gut abgeschätzt werden. Dies zeigt die im Folgenden beschriebene Simulation.
Das Simulationsprogramm besteht aus drei Komponenten:
Die Daten für die Simulation liefert die Klasse ElectricDevice. Dem Konstruktor der Klasse wird die Nominal-Leistung des zu simulierenden Geräts übergeben. Da man nie genau weiß, zu welchem Zeitpunkt, d.h. bei welchem Phasenwinkel, die Messung erfolgt, besteht die Möglichkeit, diesen zufällig festzulegen. Anhand des übergebenen Leistungswertes wird die Amplitude des Stroms ermittelt.
Sub New(Name As String, Power As Double, Optional RandomTimeOffset As Boolean = True)
...
CurrentEff = Power / VoltageEff
CurrentAmplitude = CurrentEff * Math.Sqrt(2) ' Amplitude
If RandomTimeOffset Then
PhaseOffset = StaticRandom.NextDouble() * 20
Else
PhaseOffset = 0
End If
End Sub
Die Methode AnalogRead liefert verrauschte Messwerte zu einem beliebigen Zeitpunkt. Der ADC des ESP8266 ist für 10 Bit ausgelegt, liefert also Werte im Bereich 0..1023. Der Null-Wert liegt bei 512.
Public Function AnalogRead(Time As Integer) As Integer
Const cPhi As Double = 2 * Math.PI / 20 ' Phasenwinkel: 50 Hz => 20 ms Periodendauer (entspricht 2*Pi)
Const cSensorConstant = 512 / 5 ' Messwert 512 bei 5 A
Dim mValue = CurrentAmplitude * Math.Sin((Time + PhaseOffset) * cPhi) * cSensorConstant * mNrand.Next()
mValue += 512 ' 0 Ampere = 512
If mValue > 1023 Then mValue = 1023
If mValue < 0 Then mValue = 0
Return mValue
End Function
Das Rauschen liefert die Klasse GaussianRandom. Die Methode Next liefert normalverteilte Zufallszahlen nach der Box-Muller-Methode. Es wird die Polar-Form verwandt. Das Objekt dieser Klasse, das den Rauschanteil liefert, ist als Faktor (Mittelwert = 1) mit einem 10%-Rauchanteil (StdDev = 0,1) ausgelegt. 10% Rauschanteil sollte die möglichen Störungen im Echtbetrieb abdecken können.
Die Klasse StaticRandom stellt eine statische Instanz der Random-Klasse bereit. Die Verwendung einer gemeinsamen Instanz der Random-Klasse vermeidet das Problem der ansonsten immer gleichen Startwerte der Zufallsfolgen. Verwendet man mehrere Instanzen, müssen diese zufällig initialisiert werden (Methode seed). Doch wo bekommt die Zufallszahlen für die Initialisierung her? Bei der Initialisierung über die System-Ticks (New Random(CInt(Date.Now.Ticks And &HFFFF))) muss wegen der hohen Taktrate des Systems vor jeder Instanziierung der Thread für eine mehr oder weniger lange zufällige Zeit angehalten werden (Thread.Sleep). Das führt zu erheblichen Geschwindigkeitseinbußen des Programms.
Die Form Simu1 im Projekt AnalogReadSimulation1 stellt die Sensorwerte im Zeitverlauf dar. Wesentlicher Aspekt hierbei ist, die Datenqualität und den Clipping-Effekt bei einem Strom von 5 A beurteilen zu können. In dieser Simulation wird der Sensor 200 mal ausgelesen. Die nominale Leistung des simulierten Geräts und die Taktrate der Messung können mit den Steuerelementen im unteren Teil eingestellt werden. Ebenfalls kann eingestellt werden, ob eine zufällige Phasenlage des Signals angenommen werden soll.
Die obere Grafik zeigt die originalen Sensorwerte. Man sieht deutlich das überlagerte Rauschen und das Abschneiden der Amplitudenwerte. In der unteren Grafik wurde das Signal gleichgerichtet. Die aufsummierten Werte dieses Signals (Integration) werden in der Textbox unterhalb der Grafik angezeigt.
Dim mCurrent = mDevice.AnalogRead(mTime)
Dim mRectified As Integer
If mCurrent >= 512 Then
mRectified = mCurrent - 512
Else
mRectified = 512 - mCurrent
End If
mSum += mRectified
Die Form Simu2 im Projekt AnalogReadSimulation2 liefert Messwerte zu verschiedenen Leistungswerten.
Zu 20 verschiedenen Leistungswerten zwischen 5 und 5000 Watt werden 20 mal (cSampleCount) jeweils 100 Messwerte (cReadingsCount) integriert. Dies jeweils einmal mit einer Abtastrate von 1 bzw. 2 Millisekunden (TimeStep). Das Ergebnis wird in einer TextBox ausgegeben und kann mit einer Tabellenkalkulation weiter verarbeitet werden.
Der Programm-Output:
Der Programmteil, der für die Werte-Ermittlung zuständig ist:
Const cSampleCount = 20 ' Anzahl Versuche pro Leistung
Const cReadingsCount = 100 ' Anzahl Messpunkte, an denen gemessen wird
Public ReadOnly PowerSet() = {5, 10, 20, 50, 100, 200, 500, 600, 700, 800, 900, 1000, 1200, 1500, 1700, 2000, 2500, 3000, 4000, 5000}
Sub DoSampling()
tbSampleData.Text = ""
For TimeStep = 1 To 2 ' Anzahl Millisekunden zwischen zwei Messungen
For Each Power In PowerSet ' für die verschiedenen Leistungswerte
tbSampleData.Text &= Power & vbTab & TimeStep ' Leistungswert und Taktrate ausgeben ...
tbSampleData.Refresh() ' ... und anzeigen
For Sample = 0 To cSampleCount - 1 ' Die verschiedenen Messreihen starten
Dim mD As New ElectricDevice("Test", Power) ' Für jede Messreihe die Varisbelen initialisieren
Dim mSum As Double = 0
Dim mTime As Integer = 0
For Reading = 0 To cReadingsCount - 1 ' Werte an cReadingsCount Messpunkten ermitteln
Dim mCurrent = mD.AnalogRead(mTime) ' Wert auslesen
Dim mRectified As Integer ' "gleichrichten"
If mCurrent >= 512 Then
mRectified = mCurrent - 512
Else
mRectified = 512 - mCurrent
End If
mSum += mRectified ' integrieren. Alternativ: mRectified * mRectified
mTime += TimeStep
Next Reading 'Eine Messung beendet
tbSampleData.Text &= vbTab & mSum ' ausgeben. Alternativ: Cint(Math.Sqrt(mSum))
Next Sample
tbSampleData.Text &= vbCrLf
Next Power
Next TimeStep
End Sub
Messungen realer Ströme
Im ersten Schritt: Messung ohne Verbraucher (Arduino Leonardo, weil kein passender ESP8266 griffbereit). Jeweils 200 Messpunkte im Abstand von 1 ms.
Messreihe 1:
517, 511, 527, 509, 513, 514, 507, 515, 516, 519, 515, 515, 516, 506, 514, 514, 516, 517, 511, 516, 514, 520, 515, 514, 507, 516, 516, 520, 516, 521, 522, 508, 517, 518, 520, 512, 515, 517, 512, 511, 505, 517, 518, 524, 514, 519, 501, 519, 514, 510, 520, 514, 510, 515, 513, 517, 516, 515, 513, 516, 518, 513, 515, 515, 515, 516, 515, 510, 509, 507, 515, 516, 513, 518, 516, 516, 516, 520, 511, 503, 514, 515, 518, 517, 511, 518, 514, 518, 514, 515, 517, 507, 516, 513, 516, 516, 515, 512, 515, 515, 518, 518, 516, 511, 506, 514, 511, 515, 513, 512, 514, 521, 519, 523, 515, 518, 518, 518, 513, 512, 517, 515, 513, 511, 515, 520, 511, 519, 516, 509, 517, 519, 515, 519, 509, 510, 516, 515, 510, 519, 513, 520, 516, 512, 522, 515, 520, 508, 517, 518, 508, 514, 521, 511, 516, 513, 510, 516, 516, 519, 512, 519, 514, 513, 509, 508, 513, 514, 514, 516, 507, 520, 512, 524, 518, 514, 514, 509, 509, 510, 520, 509, 512, 514, 511, 514, 521, 513, 516, 508, 514, 517, 514, 514, 514, 519, 508, 511, 511, 518
Messreihe 2:
516, 512, 518, 515, 508, 526, 521, 514, 515, 515, 514, 515, 512, 512, 517, 514, 519, 519, 511, 517, 516, 509, 516, 507, 505, 523, 519, 502, 515, 523, 513, 510, 519, 507, 515, 512, 514, 511, 519, 509, 510, 512, 518, 520, 515, 510, 518, 516, 517, 511, 520, 522, 509, 514, 514, 511, 516, 514, 516, 516, 520, 508, 506, 506, 517, 516, 513, 512, 510, 519, 504, 519, 512, 518, 503, 519, 519, 520, 515, 521, 510, 522, 514, 512, 515, 508, 519, 518, 519, 520, 513, 514, 510, 515, 518, 511, 522, 517, 519, 514, 520, 511, 512, 509, 514, 516, 515, 518, 514, 517, 515, 517, 515, 521, 512, 521, 515, 516, 510, 519, 516, 522, 512, 511, 519, 521, 521, 515, 515, 517, 516, 511, 515, 511, 523, 521, 522, 519, 515, 517, 517, 517, 519, 515, 524, 512, 518, 515, 513, 519, 518, 516, 523, 525, 515, 518, 521, 511, 512, 513, 512, 515, 511, 518, 517, 511, 518, 516, 514, 513, 515, 510, 513, 516, 519, 525, 516, 513, 517, 514, 521, 515, 521, 520, 518, 521, 519, 522, 522, 518, 516, 511, 516, 519, 511, 511, 517, 518, 517, 514
Der Sensor zeigt etwa um 3 Einheiten zu hohe Werte an (Erwartungswert 512, gemessen etwa 515). Das Rauschen (σ) liegt bei etwa 4 Einheiten.
Switcher – A WiFi Open Source Power Switch and Socket Based on ESP8266
Adding RF to a non-RF ITEAD Sonoff
hackaday.io: laundrify (Waschmascine-Aktivitätsmonitor)