Letzte Aktualisierung am 15. Januar 2023
Einen Teiler – z.B. zur Reduzierung von Stromzählerimpulsen, wie er hier benötigt wird – kann man alternativ zu fertigen Lösungen (z.B. industrieller Vorwahlzähler) sehr leicht und kostengünstig auf einem Arduino-Board abbilden. Im folgenden sind drei verschiedene Varianten beschrieben, wobei mal die Teil-Verhältnisse sehr einfach anpassen kann:
Variante 1:
Zähler 16 zu 1 Schaltausgang schaltet auf HIGH
Variante 2:
Zähler 16 zu 1 Schaltausgang schaltet auf LOW
Variante 3:
Zähler 16 zu 1 Schaltausgang schaltet auf LOW mit LCD-Anzeige
Anmerkung vorweg:
Wenn das Arduino-Board aus dem gleichen Netzteil versorgt wird, wie die angeschlossene Schaltung und damit die gleiche Masse benutzt, können die Arduino Ein- und Ausgänge des Arduino-Boards unmittelbar angeschlossen werden. Die nachfolgende Beschreibung geht hiervon aus. Ansonsten sollte die Ein-/ Ausgänge z.B. mit Optokopplern galvanisch getrennt werden.
Variante 1 – Zähler 16 zu 1 Schaltausgang schaltet auf HIGH
Diese Variante kann z.B. verwendet werden, um ein 3-Kanal-Funk-Schließerkontakt-Interface „HM-SCI-3-FM“ über einen Optokoppler am Ausgang des Arduino zu schalten. Auch ein fertiges Ralais-Modul, das bei HIGH (+5V) schaltet, lässt sich so ansteuern.
Bauteileliste:
1 Arduino (z.B. Arduino UNO)
1 Optokoppler oder Ralais-Modul, das bei HIGH (+5V) schaltet
1 10kΩ Widerstand
1 220Ω Widerstand
Arduino Programm (Sketch):
/* Zähler 16 zu 1 Schaltausgang HIGH für Arduino 1.0.3 (getestet mit dem Arduino UNO Klon "SainSmart UNO") Das Programm zählt die HIGH (+5V) Impulse am entprellten Pin 2. Jeder Zählimpuls wird über eine LED am Pin 13 angezeigt. Nach dem 16. Impuls werden Pin 12 für 10 Sekunden auf HIGH (+5V) und der Zähler zurück gesetzt. */ #include // Entprell-Library einbeziehen const int ledPin = 13; // Pin 13 (interne LED -> Zähltakt) const int relaisPin = 12; // Pin 12 (Schaltausgang) int inputPin = 2; // Pin 2 (Zähler-Eingang) int counter = 0; // Zähler-Variable initialisieren und auf 0 setzen Bounce bouncer = Bounce(inputPin,5); // Entprell-Objekt mit 5 Millisekunden Entprellzeit initialisieren void setup() // Setup-Routine (wird nur einmal durchlaufen) { pinMode(ledPin, OUTPUT); // Pin 13 als Output pinMode(relaisPin, OUTPUT); // Pin 12 als Output pinMode(inputPin, INPUT); // Pin 2 als Input (kann weggelassen werden, da INPUT standard für alle Pins ist) } void loop() // Schleifen-Routine (wird unendlich oft wiederholt) { if (bouncer.update()) // WENN der Eingang aktualisiert wird... { if (bouncer.read() == HIGH) // WENN der Eingang auf HIGH (+5V) steht, DANN... { counter++; // Zähler um 1 erhöhen digitalWrite(ledPin, HIGH); // Zähltakt-LED (Pin 13) einschalten delay(500); // 500 Millisekunden warten digitalWrite(ledPin, LOW); // Zähltakt-LED (Pin 13) ausschalten } } if (counter == 16) // WENN der Zähler auf 16 steht, DANN... { digitalWrite(relaisPin, HIGH); // Schaltausgang (Pin 12) +5V delay(10000); // 10 Sekunden warten digitalWrite(relaisPin, LOW); // Schaltausgang (Pin 12) 0V } counter = counter % 16; // Den Zähler beim Zählerstand 16 zurücksetzen }
Variante 2 – Zähler 16 zu 1 Schaltausgang schaltet auf LOW
Diese Variante ist z.B. erforderlich, wenn ein HM-SCI-3-FM über ein bereits fertig aufgebautes Ralais-Modul geschaltet werden soll, dessen Eingang auf Masse (LOW, 0V) geschaltet werden muss.
Solch ein Ralais-Modul ist beispielsweise das hier bei meinem Prototyp verwendete „SainSmart 2 Channel 5V Relay Module for Arduino“…
Bauteileliste:
1 Arduino (z.B. Arduino UNO)
1 Ralais-Modul, das bei LOW (0V) schaltet, z.B. „SainSmart 2 Channel 5V Relay Module for Arduino“
1 10kΩ Widerstand
Arduino Programm (Sketch):
/* Zähler 16 zu 1 Schaltausgang LOW für Arduino 1.0.3 (getestet mit dem Arduino UNO Klon "SainSmart UNO" und dem "SainSmart 2 Channel 5V Relay Module for Arduino") Das Programm zählt die HIGH (+5V) Impulse am entprellten Pin 2. Jeder Zählimpuls wird über eine LED am Pin 13 angezeigt. Nach dem 16. Impuls werden Pin 12 für 10 Sekunden auf LOW (0V) und der Zähler zurück gesetzt. */ #include // Entprell-Library einbeziehen const int ledPin = 13; // Pin 13 (interne LED -> Zähltakt) const int relaisPin = 12; // Pin 12 (Schaltausgang) int inputPin = 2; // Pin 2 (Zähler-Eingang) int counter = 0; // Zähler-Variable initialisieren und auf 0 setzen Bounce bouncer = Bounce(inputPin,5); // Entprell-Objekt mit 5 Millisekunden Entprellzeit initialisieren void setup() // Setup-Routine (wird nur einmal durchlaufen) { pinMode(ledPin, OUTPUT); // Pin 13 als Output pinMode(relaisPin, OUTPUT); // Pin 12 als Output pinMode(inputPin, INPUT); // Pin 2 als Input (kann weggelassen werden, da INPUT standard für alle Pins ist) digitalWrite(relaisPin, HIGH); // Schaltausgang (Pin 12) +5V } void loop() // Schleifen-Routine (wird unendlich oft wiederholt) { if (bouncer.update()) // WENN der Eingang aktualisiert wird... { if (bouncer.read() == HIGH) // WENN der Eingang auf HIGH (+5V) steht, DANN... { counter++; // Zähler um 1 erhöhen digitalWrite(ledPin, HIGH); // Zähltakt-LED (Pin 13) einschalten delay(500); // 500 Millisekunden warten digitalWrite(ledPin, LOW); // Zähltakt-LED (Pin 13) ausschalten } } if (counter == 16) // WENN der Zähler auf 16 steht, DANN... { digitalWrite(relaisPin, LOW); // Schaltausgang (Pin 12) 0V delay(10000); // 10 Sekunden warten digitalWrite(relaisPin, HIGH); // Schaltausgang (Pin 12) +5V } counter = counter % 16; // Den Zähler beim Zählerstand 16 zurücksetzen }
Variante 3 – Zähler 16 zu 1 Schaltausgang schaltet auf LOW mit LCD-Anzeige
Mit ein paar wenigen Euro Mehrinvestition für ein HD44780-kompatibles LCD-Display (z.B, eines vom Typ 1602), kann man den Zähler sehr einfach um eine Anzeige erweitern…
Bauteileliste:
1 Arduino (z.B. Arduino UNO)
1 LCD Anzeige 16*2 HD44780-kompatibel (z.B.Typ 1602)
1 Ralais-Modul, das bei LOW (0V) schaltet, z.B. „SainSmart 2 Channel 5V Relay Module for Arduino“
1 10kΩ Widerstand
1 220Ω Widerstand
1 10kΩ Trimmer Potentiometer
1 Schalter (optional)
Arduino Programm (Sketch):
/* Zähler 16 zu 1 Schaltausgang LOW für Arduino 1.0.3 mit LCD-Anzege getestet mit dem Arduino UNO Klon "SainSmart UNO", dem "SainSmart 2 Kanal 5V Relais Modul für Arduino" und einem HD44787-kompatiblen 16*2 LCD-Display. Das Programm zählt die HIGH (+5V) Impulse am entprellten Pin 2. Jeder Zählimpuls wird über eine LED am Pin 13 angezeigt. Nach dem 16. Impuls wird Pin 12 für 10 Sekunden auf LOW (0V) und der Zähler zurück gesetzt. */ #include // Entprell Bibliothek einbeziehen #include // LCD Bibliothek einbeziehen LiquidCrystal lcd(11, 10, 6, 5, 4, 3); //LCD Bibliothek mit den entsprechenden Pins initialisieren const int ledPin = 13; // Pin 13 (interne LED -> Zähltakt) const int relaisPin = 12; // Pin 12 (Schaltausgang) int inputPin = 2; // Pin 2 (Zähler-Eingang) int counter = 0; // Zähler-Variable initialisieren und auf 0 setzen float kwh = 0; // Variable für den Verbrauch initialisieren und auf 0 setzen Bounce bouncer = Bounce(inputPin,5); // Entprell-Objekt mit 5 Millisekunden Entprellzeit initialisieren void setup() // Setup-Routine (wird nur einmal durchlaufen) { pinMode(ledPin, OUTPUT); // Pin 13 als Output pinMode(relaisPin, OUTPUT); // Pin 12 als Output pinMode(inputPin, INPUT); // Pin 2 als Input (kann weggelassen werden, da INPUT standard für alle Pins ist) digitalWrite(relaisPin, HIGH); // Schaltausgang (Pin 12) +5V lcd.begin(16, 2); // Größe des LCD einstellen lcd.print("Zaehler bis 16"); // Begrüßungstext schreiben lcd.setCursor(0, 1); // Cursor positionieren lcd.print("fuer HomeMatic"); // Begrüßungstext schreiben delay(3000); // 3 Sekunden warten lcd.clear(); // Display löschen lcd.print("0"); // Zähler auf 0 setzen lcd.setCursor(0, 1); // Cursor positionieren lcd.print("0.00000 kWh"); // Verbrauch auf 0 setzen } void loop() // Schleifen-Routine (wird unendlich oft wiederholt) { if (bouncer.update()) // WENN der Eingang aktualisiert wird UND... { if (bouncer.read() == HIGH) // ...WENN der Eingang auf HIGH (+5V) steht, DANN... { counter++; // Zähler um 1 erhöhen kwh = (counter * 0.0104167); // Verbrauch * Zählimpulse berechnen (für Zähler mit 96 Impulsen (Umdrehungen) / kwh) lcd.setCursor(0, 0); // Cursor positionieren lcd.print(counter); // Zähler anzeigen lcd.setCursor(0, 1); // Cursor positionieren lcd.print(kwh,5); // Verbrauch anzeigen (mit 5 Nachkommastellen) lcd.print(" kWh"); // Einheit "kwh" anzeigen digitalWrite(ledPin, HIGH); // Zähltakt-LED (Pin 13) einschalten delay(500); // 500 Millisekunden warten digitalWrite(ledPin, LOW); // Zähltakt-LED (Pin 13) ausschalten } } if (counter == 16) // WENN der Zähler auf 16 steht, DANN... { lcd.setCursor(3, 0); // Cursor positionieren lcd.print("Senden an CCU"); // "Senden an CCU" anzeigen digitalWrite(relaisPin, LOW); // Schaltausgang (Pin 12) 0V delay(10000); // 10 Sekunden warten digitalWrite(relaisPin, HIGH); // Schaltausgang (Pin 12) +5V lcd.clear(); // Display löschen lcd.print("0"); // Zähler auf 0 setzen lcd.setCursor(0, 1); // Cursor positionieren lcd.print("0.00000 kWh"); // Verbrauch auf 0 setzen counter = counter % 16; // Den Zähler beim Zählerstand 16 zurücksetzen } }
Alle Varianten können leicht auf andere Teilerverhältnisse angepasst werden. Hierzu muss im Code an folgenden Stellen die Zahl „16“ geändert werden.
(…)
if (counter == 16) // WENN der Zähler auf 16 steht, DANN…
(…)
counter = counter % 16; // Den Zähler beim Zählerstand 16 zurücksetzen
(…)
Zu beachten ist dabei, dass der Zähler während der Wartezeiten (delay) nicht zählt. Wenn die Impulse vom Zähler schneller kommen, als die Programmschleife durchläuft, wird er daher nicht richtig zählen können. In diesem Fall müssen die Wartezeiten ggf. reduziert werden.
Impressionen:
Die Schaltpläne und Steckbrettbilder wurden mit Fritzing erstellt.
Zum korrespondierenden Beitrag im…