Blog Obsolet

Arduino – Einfacher Teiler

Letzte Aktualisierung am 1. Juli 2023

Dieser Beitrag ist obsolet und wird nicht mehr aktualisiert. Der Teiler steht im Zusammenhang mit meinem ersten Stromzähler aus dem Jahr 2012 und wird von mir seit Jahren nicht mehr genutzt. Das beschriebene Verfahren funktioniert aber möglicherweise nach wie vor. Die Kommentare wurden geschlossen.

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

Schaltung:

Zaehler_16_zu_1_Schaltausgang_HIGH_Schaltplan

Aufbau:

Zaehler_16_zu_1_Schaltausgang_HIGH_Steckplatine

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“…

Zaehler_16_zu_1_Schaltausgang_LOW_Prototyp_Forum

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

Schaltung:

Zaehler_16_zu_1_Schaltausgang_LOW_Schaltplan

Aufbau:

Zaehler_16_zu_1_Schaltausgang_LOW_Steckplatine

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…

LCD00

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)

Schaltung:

Zaehler_16_zu_1_Schaltausgang_LOW_mit_Display_Schaltplan

Aufbau:

Zaehler_16_zu_1_Schaltausgang_LOW_mit_Display_Steckplatine

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:

LCD01
LCD02
LCD03
LCD04
LCD05

Die Schaltpläne und Steckbrettbilder wurden mit Fritzing erstellt.

HomeMatic-Forum

Zum korrespondierenden Beitrag im…

Bitte beachten…

SMART WOHNEN in Stern’s Haus ist ein rein privates, nicht kommerzielles Projekt. Meine Hinweise, Anleitungen, Schaltungen und Software werden so angeboten, „wie sie sind“, Support kann ich nur im Rahmen meiner begrenzten Freizeit leisten, hierfür bitte ich um Verständnis.
Die Verwendung meiner Hinweise, Anleitungen, Schaltungen und Software erfolgt auf eigenes Risiko. Ich übernehme hierfür keinerlei Gewährleistung bzw. Haftung! Für die Einhaltung der einschlägigen technischen Vorschriften ist jeder Anwender selbst verantwortlich!
Creative Commons Lizenzvertrag
Copyright © Jens-Peter Stern | SMART WOHNEN in Stern’s Haus | sternshaus.de
WordPress Cookie Plugin von Real Cookie Banner