Zähler

http://sites.schaltungen.at/arduino-sketch/zaehler

http://www.linksammlung.info/

http://www.schaltungen.at/

                                                                                             Wels, am 2018-05-20

BITTE nützen Sie doch rechts OBEN das Suchfeld  [                                                              ] [ Diese Site durchsuchen]

DIN A3 oder DIN A4 quer ausdrucken
*******************************************************************************I**
DIN A4  ausdrucken   (Heftrand 15mm / 5mm)     siehe     http://sites.schaltungen.at/drucker/sites-prenninger
********************************************************I*
~015_b_PrennIng-a_arduino.sketch-arduino.zaehler (xx Seiten)_1a.pdf





               Infrarot-Reflex-Lichtschranke als Zähler

Infrarot Lichtschranke mit Arduino zum Auslesen des Stromzählers

IR Leuchtdiode SFH409 oder SFH4346
Fototransistor SFH309 FA

Elektromagnetische Ferraris-Stromzähler kommen noch in vielen Haushalten zur Verbrauchsmessung zum Einsatz. Sie besitzen keine direkte Schnittstelle zur elektronischen Datenerfassung. Auf der anderen Seite hilft jedoch eine präzise und minutengenaue Erfassung des Stromverbrauchs beim Energiesparen, da sich so Standbyverbrauch und Lastspitzen besser analysieren lassen. Eine Möglichkeit, dennoch an diese Daten zu kommen, besteht in der optoelektronischen Abtastung der Zählscheibe. Die Signalerfassung erledigt dabei ein Arduino Nano.


Ferraris-Zähler

Der Ferraris-Zähler arbeitet nach dem Prinzip eines Motors. Der Stromfluss durch mehrere Spulen versetzt eine Zählscheibe in Drehung, die ihrerseits ein mechanisches Zählwerk antreibt. Die Anzahl der Umdrehungen der Scheibe ist dabei proportional zur verrichteten elektrischen Arbeit, die typischerweise in Kilowattstunden (kWh) gemessen und abgerechnet wird. So steht zum Beispiel auf meinem Zähler die Angabe 75 U/kWh, das heißt 75 Umdrehungen der Zählscheibe bedeuten einen Verbrauch von 1 kWh.

Auf der Zählscheibe ist eine rote Markierung angebracht. Mittels einer Reflex-Lichtschranke lässt sich der Durchlauf dieser Markierung durch das Sichtfenster erfassen und elektronisch weiterverarbeiten.

Arduino Lichtschranke

Die eigentliche Lichtschranke besteht aus einer Infrarot-Leuchtdiode SFH 409 (alternativ: SFH 4346) und einem Infrarot-Fototransistor SFH 309 FA (Abb. 1). Die Ansteuerung erfolgt mit einem Arduino Nano. Prinzipiell sind natürlich auch andere Modelle des Arduino geeignet, der Nano kommt hauptsächlich wegen seiner geringen Abmessungen zum Einsatz. Die Anschlussbezeichnungen in Abb. 1 beziehen sich direkt auf die Beschriftung des Arduino Boards.



Abb. 1: Schaltbild der Infrarot-Reflex-Lichtschranke

Gegenüber einem «herkömmlichen» Aufbau einer Lichtschranke mit analogen Triggerschaltkreisen oder gar diskreten Transistoren bietet die Verwendung eines Mikrocontrollers viele Vorteile. So sind neben den beiden Infrarot-Bauelementen nur zwei weitere passive Bauteile notwendig: Ein Widerstand von 120 Ω dient zur Begrenzung des Stroms durch die Leuchtdiode und der Widerstand 2,2 kΩ wandelt den durch den Fototransistor fließenden Strom in eine Spannung um. Sie gelangt direkt an den Analogeingang A7 des Arduino.

Die Anode der Leuchtdiode ist nicht direkt mit der Betriebsspannung V5V, sondern mit dem Digitalausgang D2 verbunden. Dadurch lässt sich eine wirksame Unterdrückung von störender Umgebungsstrahlung erreichen. Das Messprogramm schaltet sehr schnell über D2 die Leuchtdiode an und aus und misst jeweils die an A7 entstehende Spannung. Die anschließende Differenzbildung eliminiert das auf den Sensor treffende Umgebungslicht, das Resultat enthält ausschließlich das von der Leuchtdiode erzeugte Licht. Dieses Messprinzip ließe sich ohne einen Mikrocontroller nur sehr aufwändig realisieren.

Die beiden weiteren Bauelemente LED grün und Widerstand 560 Ω sind für die eigentliche Funktion der Lichtschranke nicht erforderlich. Sie dienen ausschließlich zur visuellen Rückmeldung der korrekten Funktion des Gerätes. Abgleichwiderstände oder Potentiometer sucht man in der Schaltung vergeblich. Die Einstellung der Triggerpegel zur Anpassung der Lichtschranke an unterschiedliche Umgebungen erfolgt per Software.

Der Preis für einen Arduino Nano bewegt sich zwischen 8 US $ für einen «China-Klon» und 50 €. Beim Einkauf lohnt daher ein Preisvergleich! Man muss auch keinen Nano nehmen, wenn man genügend Platz hat, lässt sich durchaus ein anderes Modell verwenden.



Aufbau


Abb. 2: Der Arduino Nano und die wenigen externen Bauelemente kommen in kleines Plastikgehäuse.

Die Bauteile inklusive des Arduino Nano sind auf einer Universal-Lochrasterplatte verlötet. Ihre Größe ist so gewählt, dass sie ohne weitere Befestigungselemente «saugend» in ein Standard-Plastikgehäuse passt (Abb. 2). Der Arduino ist dabei so positioniert, dass sein Mini-USB-Anschluss auch bei geschlossenem Gehäuse später noch von außen zugänglich ist.



Abb. 3: Das Gehäuse von außen. Man erkennt Infrarot-Leuchtdiode und -Fototransistor. Die Markierung hilft später bei der exakten Ausrichtung der Lichtschranke auf dem Zähler.

Infrarot-Leuchtdiode und -Fototransistor sind von der Unterseite der Platine bestückt (Abb. 2 links), damit das Infrarotlicht durch zwei in die untere Gehäuseschale gebohrte Löcher nach außen gelangen kann. Die Oberseite der Bauelemente liegt dann später genau auf Oberfläche des Zählergehäuses direkt über der Zählscheibe (Abb. 4). Die mit einem Permanentmarker aufgebrachte, auf die Gehäuseseiten verlängerte Markierung erleichtert die Positionierung auf dem Zähler (Abb. 3). Damit die Reflex-Lichtschranke funktioniert, müssen Leuchtdiode und Fototransistor so eng wie möglich beieinander sitzen, ohne dass jedoch direktes Licht von der Diode auf den Transistor treffen kann.

Die grüne Leuchtdiode ist normal von oben bestückt, sodass sie später auf der vom Zähler abgewandten Seite sichtbar ist (Abb. 2 unten rechts). Ihre Länge ist so gewählt, dass sie mit der Gehäuseoberseite abschließt.



Abb. 4: Schnittansicht der Reflex-Lichtschranke (schematisch)

Software

Ein Arduino eignet sich zwar hervorragend zur Ansteuerung der Lichtschranke und Echtzeitdatenerfassung, hat jedoch seine Grenzen, wenn es an die Langzeitspeicherung und Visualisierung der Daten geht. Aus diesem Grund besteht die Software aus zwei Teilen. Ein Teil läuft auf dem Arduino und kümmert sich um die Datenerfassung. Den zweiten Teil kann man auf einem beliebigen (vorzugsweise Linux-) Rechner installieren, der über einen permanenten Massenspeicher (zum Beispiel eine Festplatte oder SD-Speicherkarte) sowie über USB- und Netzwerkschnittstelle verfügt. Eine gute Wahl ist ein Raspberry Pi.

Da sich in meinem Keller schon ein RasPi zur Messung des Gasverbrauchs befindet, habe ich gleich diesen verwendet.

Arduino und Steuerrechner sind über ein USB-Kabel verbunden.


               Gaszähler auslesen mit Magnetometer HMC5883 und Raspberry Pi
               Permanentmagnet
               Reed-Kontakt oder Hall-Sensor = 3-Achs Magnetometer HMC5883L

               HMC 5883 3-Achsen Magnetometer - Datenblatt (PDF)
              SparkFun Triple Axis Magnetometer Breakout - HMC5883L
  https://www.sparkfun.com/products/retired/10530
             https://www.kompf.de/tech/gascountmag.html


Dieses gewährleistet zum einen die Stromversorgung des Arduino und zum anderen erfolgt hierüber die Kommunikation zwischen beiden Softwareteilen mittels eines einfachen seriellen Protokolls.

Die komplette Software steht auf Github im Repository emeir (electric meter with infrared light barrier) zur Verfügung. Eine Kopie gelangt per

git clone https://github.com/skaringa/emeir.git

in das lokale Arbeitsverzeichnis.

Die Datei arduino_sketch >ReflectorLightBarrier.ino enthält den Arduino-Sketch.

Er ist mittels der Arduino-IDE zu kompilieren und in den Programmspeicher des Arduino zu laden.

ARDUINO 1.8.5   https://www.arduino.cc/en/Main/Software

ReflectorLightBarrier.ino
https://github.com/skaringa/emeir/tree/master/arduino_sketch


Sketch > ReflectorLightBarrier.ino
/*
* Program to read the electrical meter using a reflective light sensor
* This is the data acquisition part running on an Arduino Nano.
* It controls the infrared light barrier, detects trigger
* and communicates with a master computer (Raspberry Pi)
* over USB serial.
* Copyright 2015 Martin Kompf
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/



#include <avr/eeprom.h>

const int analogInPin = A7;            // Analog input pin that the photo transistor is attached to
const int irOutPin = 2;                  // Digital output pin that the IR-LED is attached to
const int ledOutPin = 12;              // Signal LED output pin

int sensorValueOff = 0;              // value read from the photo transistor when ir LED is off
int sensorValueOn = 0;              // value read from the photo transistor when ir LED is on

                                                  // command line
#define MAX_CMD_LEN 80
char command[MAX_CMD_LEN];  // command buffer
int inCount = 0;                           // command buffer index
boolean cmdComplete = false;

                                               // Mode of serial line:
                                           // C - command, D - data output
char mode = 'D';

                                   // Data output mode:
                                   // R - raw data
                                   // T - trigger events
                                   // C - counter   Aus den beiden Datenmodi gelangt man stets mittels C wieder in den Kommandomodus.
char dataOutput = 'T';    //  = ' T '

                                      // trigger state and level
int triggerLevelLow;
int triggerLevelHigh;
boolean triggerState = false;

                                     // Address of trigger levels in EEPROM
uint16_t triggerLevelLowAddr = 0;
uint16_t triggerLevelHighAddr = 4;

/**
* Set trigger levels (low high) from the command line
* and store them into EEPROM
*/

void setTriggerLevels() {
char *p = &command[1];
while (*p != 0 && *p == ' ') {
++p;
}
char *q = p + 1;
while (*q != 0 && *q != ' ') {
++q;
}
*q = 0;
eeprom_write_word(&triggerLevelLowAddr, atoi(p));

p = q + 1;
while (*p != 0 && *p == ' ') {
++p;
}
q = p + 1;
while (*q != 0 && *q != ' ') {
++q;
}
*q = 0;
eeprom_write_word(&triggerLevelHighAddr, atoi(p));
}

/**
* Read trigger levels from EEPROM
*/

void readTriggerLevels() {
triggerLevelLow = (int)eeprom_read_word(&triggerLevelLowAddr);
triggerLevelHigh = (int)eeprom_read_word(&triggerLevelHighAddr);
Serial.print("Trigger levels: ");
Serial.print(triggerLevelLow);
Serial.print(" ");
Serial.println(triggerLevelHigh);
}

/**
* Detect and print a trigger event
*/

void detectTrigger(int val) {
boolean nextState = triggerState;
if (val > triggerLevelHigh) {
nextState = true;
} else if (val < triggerLevelLow) {
nextState = false;
}
if (nextState != triggerState) {
triggerState = nextState;
Serial.println(triggerState? 1 : 0);
// control internal LED
digitalWrite(ledOutPin, triggerState);
}
}


/**
* Read one line from serial connection and interpret it as a command
*/

void doCommand() {
                                                         // print prompt
Serial.print(">");
while (! cmdComplete) {
                                                     // read input
while (Serial.available()) {
                                                  // get the new byte:
char inChar = (char)Serial.read();
if (inChar == '\n' || inChar == '\r') {
command[inCount] = 0;
Serial.println();
cmdComplete = true;
break;                                          // End of line
} else if (inCount < MAX_CMD_LEN - 1) {
command[inCount] = inChar;
inCount++;
                                                     // echo
Serial.print(inChar);
}
}
}

                                                     // interprete command
switch (command[0]) {
case 'D':
                                                     // start raw data mode
mode = 'D';
dataOutput = 'R';
break;
case 'T':
                                                   // start trigger data mode
mode = 'D';
dataOutput = 'T';
break;
case 'S':
                                                 // set trigger levels
setTriggerLevels();
readTriggerLevels();
break;
}

                                           // clear command buffer
command[0] = 0;
inCount = 0;
cmdComplete = false;
}

/**
* Setup.
*/

void setup() {
                                                     // initialize serial communications at 9600 bps:
Serial.begin(9600);
                                                     // initialize the digital pins as an output.
pinMode(irOutPin, OUTPUT);
pinMode(ledOutPin, OUTPUT);
                                                    // read config from EEPROM
readTriggerLevels();
}

/**
* Main loop.
*/

void loop() {
if (mode == 'C') {
doCommand();
} else if (mode == 'D') {
if (Serial.available()) {
char inChar = (char)Serial.read();
if (inChar == 'C') {
                                                   // exit data mode
mode = 'C';
}
}
}
if (mode == 'D') {
                                         // perform measurement
                                         // turn IR LED off
    digitalWrite(irOutPin, LOW);
                                         // wait 10 milliseconds
    delay(10);
                                           // read the analog in value:
    sensorValueOff = analogRead(analogInPin);
                                        // turn IR LED on
    digitalWrite(irOutPin, HIGH);
    delay(10);
                                         // read the analog in value:
    sensorValueOn = analogRead(analogInPin);

    switch (dataOutput) {
    case 'R':
                                       // print the raw data to the serial monitor
    Serial.println(sensorValueOn - sensorValueOff);
    break;
    case 'T':
                                       // detect and output trigger
    detectTrigger(sensorValueOn - sensorValueOff);
    break;
    }
 

}
delay(10);
}



Nach dem Start ist die Arduino Software im Trigger data mode. Für einen ersten Funktionstest besser geeignet ist der Raw data mode, in dem die Software ununterbrochen die am Fototransistor gemessene Differenzspannung auf der seriellen Schnittstelle ausgibt. Die Umschaltung des verschiedenen Modi erfolgt durch das Senden von Kommandos vom Steuerrechner zum Arduino. Dazu kann man den Serial Monitor der Arduino-IDE oder ein Terminalprogramm wie minicom verwenden.

Das Senden des Zeichens C zum Arduino veranlasst diesen, in den Kommandomodus zu gehen. Nun reagiert er auf verschiedene Steuerbefehle:



D - Raw data mode: Die Software sendet fortlaufend Messwerte.T - Trigger data mode: Nur bei Umschaltung des Triggers wird eine 1 oder 0 gesendet.S low high - Setzen der Triggerpegel. Parameter sind zwei Integer-Werte von 0 bis 1023.C - Aus den beiden Datenmodi gelangt man stets mittels C wieder in den Kommandomodus.


Im Raw data mode gibt der Arduino ständig Messwerte auf der seriellen Schnittstelle aus. Dabei handelt es sich um den Differenzwert, den die Software wie oben beschrieben durch Subtraktion der Spannungen im ein- und ausgeschalteten Zustand der IR-Leuchtdiode berechnet. So kann man testen, ob beim Aufbau der Hardware alles glatt gegangen ist: Hält man ein Stück Papier vor die Reflex-Lichtschranke, dann sollte die Veränderung seines Abstands signifikante Unterschiede in den Messwerten bewirken.

Der für die Messwerterfassung relevante Programmausschnitt ist:



    // perform measurement    // turn IR LED off    digitalWrite(irOutPin, LOW);    // wait 10 milliseconds    delay(10);    // read the analog in value:    sensorValueOff = analogRead(analogInPin);               // turn IR LED on    digitalWrite(irOutPin, HIGH);    delay(10);    // read the analog in value:    sensorValueOn = analogRead(analogInPin);                   switch (dataOutput) {      case 'R':        // print the raw data to the serial monitor                 Serial.println(sensorValueOn - sensorValueOff);        break;      case 'T':        // detect and output trigger        detectTrigger(sensorValueOn - sensorValueOff);        break;    }

Montage und Abgleich



Abb. 5: Die gemessenen Sensorwerte (blau) beim zweimaligen Durchlauf der Zählmarkierung und die daraus bestimmten Triggerschwellen.

Die Lichtschranke ist mit zwei Streifen doppelseitigem Klebeband auf dem Zählergehäuse befestigt (siehe Bild am Artikelanfang). IR-Leuchtdiode und Fototransistor müssen dabei genau über der Zählscheibe sitzen. Bei der genauen Positionierung hilft die auf dem Gehäuse angebrachte Markierung (Abb. 3).

Bei laufendem Stromzähler erfolgt zunächst die Erfassung der Messdaten im Raw data mode. Hilfreich ist hier ein Terminalprogramm wie zum Beispiel minicom, das die über die serielle Schnittstelle laufenden Daten in eine Textdatei schreiben kann. Nach dem Import dieser Datei in ein Tabellenkalkulationsprogramm (zum Beispiel LibreOffice Calc) kann man eine Grafik ähnlich wie Abb. 5 erzeugen, die bei der Ermittlung der Triggerschwellen hilft: Im zeitlichen Verlauf der Messdaten (blau) sind eindeutig die beiden Durchläufe der Zählmarkierung zu identifizieren, denn deren rote Farbe führt zu einer signifikanten Abnahme des reflektierten Lichts. Hier ergibt sich daraus die Festlegung der beiden Triggerschwellen auf 85 (low, rot in Abb. 5) und 90 (high, gelb).

Das Kommando S 85 90 schreibt die Werte für die Triggerschwellen in den EEPROM des Arduino. Sie überleben damit das Abtrennen der Stromversorgung und einen Programmneustart.

Von nun an betreibt man die Arduino-Software im Trigger data mode. Hier erfolgt eine Ausgabe auf der seriellen Schnittstelle nur noch bei einem Triggerereignis: Bei Unterschreitung des low Triggerlevels gibt das Programm das Zeichen 0 und bei Überschreitung des high Levels eine 1 aus. Außerdem wird die grüne Leuchtdiode entsprechend geschaltet, was für eine visuelle Kontrolle der Funktion enorm hilfreich ist: Nur wenn sich die rote Zählmarkierung vor der Lichtschranke befindet, ist der Triggerzustand «0» und die Leuchtdiode ist aus, ansonsten leuchtet sie:



/** * Detect and print a trigger event */void detectTrigger(int val) {  boolean nextState = triggerState;  if (val > triggerLevelHigh) {    nextState = true;  } else if (val < triggerLevelLow) {    nextState = false;  }  if (nextState != triggerState) {    triggerState = nextState;    Serial.println(triggerState? 1 : 0);    // control internal LED    digitalWrite(ledOutPin, triggerState);  }}


Aufzeichnung von Zählerstand und Verbrauch

Auf dem Steuerrechner läuft das Python-Skript emeir.py, welches über die USB-Seriell Schnittstelle die vom Arduino gelieferten Daten empfängt. Im Trigger data mode sind das nur Nullen und Einsen, deren Umschaltung den Durchlauf der Zählmarkierung signalisiert. Da das Verhältnis von Umdrehungen der Zählscheibe zum Stromverbrauch bekannt ist, kann man somit direkt auf die verbrauchte Energiemenge schließen:


# Serial port of arduinoport = '/dev/ttyUSB0'# Revolutions per kWhrev_per_kWh = 75# ... # Open serial line ser = serial.Serial(port, 9600) trigger_state = 0 counter = last_rrd_count() trigger_step = 1.0 / rev_per_kWh while(1==1): # Read line from arduino and convert to trigger value line = ser.readline() line = line.strip() old_state = trigger_state if line == '1': trigger_state = 1 elif line == '0': trigger_state = 0 if old_state == 1 and trigger_state == 0: # trigger active -> update count rrd counter += trigger_step update = "N:%.2f:%.0f" % (counter, trigger_step*3600000.0) rrdtool.update(count_rrd, update)



Das Programm schreibt bei einer Auslösung des Triggers den neuen Zählerstand und die seit dem letzten Trigger verbrauchte Energie trigger_step = 1 / 75 (Umdrehungen pro kWh) in eine Round Robin Datenbank.

Dieses Prinzip gleicht dem in Gaszähler auslesen mit Magnetometer HMC5883 und Raspberry Pi beschriebenen Vorgehen.

Das Programm übernimmt auch das Anlegen der Datenbank emeir.rrd, die im gleichen Verzeichnis wie das Python-Skript liegt. Hierzu muss man es einmalig mit der Option -c starten:



./emeir.py -c

Eine neu angelegte Datenbank startet logischerweise mit dem Zählerstand 0.
Um ihn mit dem mechanischen Zähler zu synchronisieren, notiert man sich den mechanischen Zählerstand (zum Beispiel 132290.0) und schreibt diesen möglichst zeitnah in die Datenbank:


rrdtool update emeir.rrd N:132290.0:0


Danach ist emeir.py neu zu starten. Es liest dabei den gespeicherten Zählerwert aus der Datenbank und setzt damit die Zählung fort.

Mittels rrdtool lassen sich aus der Round Robin Datenbank ansprechende Grafiken erzeugen. Die folgenden Kommandos erzeugen die in Abb. 6 gezeigten Grafiken über den Zählerstand und Verbrauch der letzten drei Tage:


# Erzeuge Zählerstandsgrafik in counter.gif rrdtool graph counter.gif \ -s 'now -3 day' -e 'now' \ -X 0 -Y -A \ DEF:counter=emeir.rrd:counter:LAST \ LINE2:counter#000000:"Zählerstand [kWh]"# Erzeuge Verbrauchsgrafik in consum.gifrrdtool graph consum.gif \ -s 'now -3 day' -e 'now' \ -Y -A \ DEF:consum=emeir.rrd:consum:AVERAGE \ LINE2:consum#00FF00:"Verbrauch [W]"


Abb. 6: Mit rrdtool erzeugte Grafiken von Zählerstand und Stromverbrauch über drei Tage

Ein schlanker Webserver wie lighttpd «lighty» zusammen mit ein paar HTML-Seiten und Perl-Skripts stellt die Verbrauchsgrafiken komfortabel im Intranet zur Verfügung. Das Prinzip ist in den Beiträgen zur Erfassung des Gasverbrauchs und Temperaturmessung beschrieben.

Fazit

Das kleine, selbstgebaute Gerät läuft seit über einem Jahr störungsfrei und lieferte schon interessante Erkenntnisse. Signifikant ist zum Beispiel der Unterschied zwischen Urlaubs- und Anwesenheitszeiten. Deswegen sollte man auch sehr vorsichtig bei der Entscheidung sein, wem man seine Verbrauchsdaten in Echtzeit zur Verfügung stellt! Neben den Verbrauchsspitzen, für die hauptsächlich der elektrisch betriebene Küchenherd und die Warmwasserbereitung verantwortlich sind, fällt die leicht wellige Grundlast auf. Das ist dem Betrieb von Kühlschrank beziehungsweise Kühltruhe geschuldet, die sich periodisch ein- und ausschalten. Zieht man dies ab, dann bleibt ein Grundverbrauch von etwa 60 W übrig, der durch den Betrieb diverser elektronischer Geräte, wie DSL-Router, Radiowecker und natürlich auch den für die Verbrauchsmessung benutzten Arduino und Raspberry Pi (!) entsteht. Eine weitere Eingrenzung erfordert dann den Einsatz eines portablen Energiekosten-Messgeräts, das man in die Netzleitungen der einzelnen Geräte einschleift. So etwas gibt es für ambitionierte Selbermacher auch als Bausatz von ELV.




Interessante Links




Quelle:
https://www.kompf.de/tech/emeir.html






********************************************************I*
Taschenrechner-Digitalzähler


http://www.b-kainka.de/bastel50.htm




********************************************************I*
Aufbau einer Zählerschaltung mit ARDUINO
300_d_Rahner-x_8-digit Zähler - 7-Segment Anzeige - Zählerschaltung mit Arduino UNO R3_1a.pdf

Über den Aufbau und die Ansteuerung einer 7-Segment-Anzeige wurde hier an zwei Stellen bereits geschrieben -> 7-Segment-Anzeige und BASIC Stamp, 7-Segment-Anzeige und Propeller Controller.

In diesem Projekt wird eine 7-Segment-Anzeige TDSL5160 von Vishay beschaltet und als einfacher Zähler programmiert.

Anschließend wird eine 8-stellige7-Segment-Anzeige als Zeitnehmer bzw. als Uhr programmiert.

1 - Aufbau einer Zählerschaltung

Zwischen jedem LED-Segment einer 7-Segment-Anzeige und einem Arduino I/O Pin muss ein Strombegrenzungs-Widerstand eingebautwerden um die I/O-Kanäle des Kontrollers nicht zu überlasten. 

Werden alle sieben I/O Pins gleichzeitig auf 1 (3,3 Volt) gesetzt, leuchten alle Segmente der Anzeige auf, es fließt einMaximalstrom, der die vorgegebenen Belastungsdaten des Arduino-Kontrollers nicht überschreiten darf.

Jeder Widerstand zwischen 100 Ohm und 1 kOhm kann als sogenannter Vorwiderstand genommenwerden.

Dabei gilt:

je geringer der Widerstandswert, desto heller leuchtet die LED, desto größer ist aber auch der Stromfluss. Im Versuch werden Widerstände von 470 Ohm genommen.


Zählerschaltung mit einer TDSL5160 7-Segment-LED-Anzeige
Material
  • 1x  Steckbrett
  • 1x  Arduino UNO Board
  • 1x  7-Segment Anzeige (hier TDSL5160)
  • 8x  Widerstand, 470 Ohm
  • 1x  Steckernetzteil
Aufgaben
  • Baue die Schaltung nach Schaltskizze auf einemSteckbrett auf.
  • Informiere dich anhand des Datenblattes zu der7-Segment-Anzeige über die Leistungsdaten des Bausteins.
  • Entnehme dem Datenblatt die Anschlussbelegung der Pinund trage sie zusammen mit den Segmentbezeichnern in eine Tabelle ein.
  • Übertrage das Programm 7_Segment_Test1.inoin den Editor und speichere es ab.
  • Starte das Programm.
  • Überprüfe, ob die Zahlen von 0 bis 9 auf der7-Segment-Anzeige dargestellt werden.

Schaltskizze und Schaltungsaufbau









Die hier vorgenommene Pinbelegung ist willkürlich und kann jederzeit abgeändert werden.

Mit ihr wird das Prinzip der Ansteuerunggezeigt.

Wichtig ist, ob es sich bei dem vorliegenden Baustein um einen mit gemeinsamer Kathode oder Anode handelt -> siehe Datenblatt des Herstellers.

Bei gemeinsamer Kathode wird diese mit GNDauf dem Arduino Board verbunden, bei gemeinsamer Kathode mit dem 3,3V Anschluss.

Der TDSL-5160 ist nach Datenblatt mit einer gemeinsamer Kathode ausgestattet.


Abbildung 2 - Datentabelle zur 7-Segmentanzeige TDSL5160

Meine Daten zur 7-Segment-Anzeige (dem Datenblattentnommen)

Trage in die unten stehende Tabelle die Daten zu deiner 7-Segment-Anzeige ein.


2 - Zifferndarstellung und Arrays


Wie schafft man es nun, die Ziffern von 0 bis 9 auf der 7-Segment-Anzeige anzeigen zu lassen?

Hilfestellung gibt die Datentabelle(Abb. 2). Es muss herausgefunden werden, welche der 7 Dioden in einer 7-Segment Anzeige bei einer bestimmten Zifferndarstellung ein- bzw. ausgeschaltet werden müssen.

Ein Raster mit acht Spalten verschafft die Übersicht, welche Segmente einer Anzeige bei welcher Zifferndarstellung eingeschaltetwerden.

Nehmen wir zum Beispiel die Ziffer 3.

Die Segmente a, b, c, d und g müssen aufleuchten, damit diese Ziffer auf dem Display erscheint. In die untenstehende Tabelle werden in den Spalten a, b,c, d und g entsprechend Einsen geschrieben, der Rest wird mit Nullen aufgefüllt.

Auf diese Weise bekommt man für jeder der 10 Ziffern eine bestimmte binäre Darstellung.


Abbildung 3 -
Zuordnungstabelle für die 7 Segmente einer Ziffer

In einem Programm werden die zehn binären Zahlen in einem Array z[10] abgelegt und anschließend die I/O Ports des Arduino auf OUTPUTgeschaltet, die mit der LED-Anzeige verbunden sind.

Etwas trickreich ist dann die Umsetzung der Zifferndarstellung auf dem 7-Segment-Display.

Am Beispiel der Darstellung der Ziffer 4 auf der7-Segment-Anzeige soll die Idee verdeutlicht werden.

Über die achtstellige Binärzahl 01101100 wird eine Schablone mit einem Fenster von 1 Bit Breite gelegt (Abb. 4).

Schiebt man dieseSchablone von rechts nach links über die Ziffernfolge 01101100, dann sieht man jeweils nur ein Bit.

Jede Position in der binären Darstellung entspricht einem bestimmten Segment in der Anzeige.

ZumBeispiel entspricht Bit 1 dem Segment e, Bit 2 dem Segment d bei der benutzten Schaltung.

Eine 1 bedeutet, dass LED Segment geht auf HIGH, während eine Null entsprechend das LED Segment auf LOWsetzt.


 Abbildung 4 -

Schablone mit einem 1-Bit Fenster über dem Binärcode für die Darstellung der Zahl 4 auf der 7-Segment Anzeige.

Die Binärfolge 01101100 entspricht der Zuordnungstabelle (Abb. 3) fürdie 7-Segment-Anzeige



Das Programm 7_Segment_Test1.ino

 

Wie arbeitet das Programm?

Die Variable fenster (das Schablonenfenster) wird auf die Position 1 gesetzt und das Array z mit den 10 Binärzahlender jeweils anzusteuernden Segmente der 7-Segment-Anzeige gefüllt.

In der Methode setup() werden die I/O Pin 2 bis 9 auf OUTPUT gesetzt.

Ob man das in einer Schleife macht, wie hiervorgestellt, oder einzeln, Schritt für Schritt, muss jeder selbst entscheiden.

Die Methode loop() enthält zwei ineinander geschachtelte Schleifen.

Die äußere Schleife mit dem Laufparameterziffer kümmert sich um die darzustellenden Ziffern von 0 bis 9, während die innere Schleife mit Laufparameter seg jedes der acht Segmente (inklusive des Punktes) einer Anzeigeanspricht.

Die innere Schleife wird zuerst abgearbeitet, da ist ziffer in der äußeren Schleife 0 und fenster = 1.

  • if ((z[0] & fenster) >0)

Das Arrayelement z[0] wird mit fenster bitweise verglichen.

  • 0 0 1 1 1 1 1 1
  • 0 0 0 0 0 0 0 1
  • -----------------
  • 0 0 0 0 0 0 0 1 ist größer 0

 

Da die Relation z[0] & fenster > 0wahr ist, verzweigt das Programm zu

  • digitalWrite(seg, HIGH);fenster = fenster << 1;

seg ist zu diesem Zeitpunkt 2, deshalb wird das Segment am I/O Port 2 des Arduino auf HIGH gesetzt.

Anschließend wird die 1der Binärzahl 00000001 um eine Position nach links verschoben; das ergibt 00000010 (das ist das verschiebbare 1-Bit breite Fenster der Schablone).

seg wird um eins erhöht und ist jetzt 3. Der bitweise Vergleich ergibt bei der Relation wieder ein WAHR und das Programmverzweigt erneut zu

  • digitalWrite(3, HIGH);fenster = fenster << 1;

Auch das Segment am I/O Port 3 des Arduino wird auf HIGH gesetzt und die 1 in der Bitfolge von fenster wieder um einePosition nach links verschoben.

Dieser Vorgang setzt sich so lange fort, bis die innere Schleife abgearbeitet ist und die Ziffer 0 auf dem Display erscheint - alle LED der Umrandung sind auf HIGH,nur das Segment g ist auf LOW.

Jetzt erhöht die äußere Schleife ihren Laufparameter um 1 und der eben beschriebene Vorgang wiederholt sich.

3 - Programmablaufplan

Der folgende Programmablaufplan für die Methode loop() zeigt an Hand der Belegungen der im Programm benutzten Variablen, wie sich deren Werte bei jedemSchleifendurchlauf verändern.

 

 

Abbildung 5

- Programmablaufplan; rot markiert ist das 1 Bit breite Schablonenfenster, in dem die rot unterlegte Zahl mit der jeweils binären Zahldarstellung der Variablen fenster verglichen wird.

Die Schleifen werden nach dem hier vorgestellten Muster wiederholt durchlaufen und schalten die entsprechenden LED-Segmente ein bzw.aus.

Nachdem wir eine LED-Anzeige so weit gebracht haben, dass auf ihr die Ziffern von 0 bis 9 dargestellt werden können, werden imfolgenden Projekt acht 7-Segment-Anzeigen betrachtet, auf denen die Uhrzeit oder die Minuten Sekunden und Millisekunden einer Zeitmessung angezeigt werden sollen.

 

4 - LED-Anzeige mit acht Stellen

Bei dem eingesetzten Modul handelt es sich um 2 Blöcke von je 4 LED Anzeigen, die über einen MAX7219 Baustein angesteuert werden. Im Internet kann man diesenBaustein für 2 - 3 Euro erwerben.

 

 

Die Ansteuerung einer 8-stelligen 7-Segment-Anzeige kann im Prinzip auf zwei verschiedene Arten vorgenommen werden:

  1. über die Nutzung einer Bibliotheksdatei, die alle wesentlichen Funktionen zur Ansteuerung des Moduls enthält. Der Schwerpunkt liegt dabei aufder Dokumentation zur Bibliotheksdatei  und wie man die Funktionen in sein eigenes Programm einbaut.
  2. über die Entwicklung eigener Funktionen, die die Ansteuerung des LED Display Treiberbausteins MAX7219 regeln. Der Schwerpunkt in dieser Übungliegt auf dem Studium des Datenblattes des MAX7219 Treiberbausteins und dem Aufbau eines Workflow für die Erstellung eines eigenen Programms.
Die zweite Möglichkeit setzt gute Programmierkenntnisse voraus, macht unabhängig von einer Bibliothek, die andere geschrieben haben und verschafft einem selbst einen guten Einblick in die Arbeitsweise des Bauteils.

Beginnen wir mit Option 1 und dem Arduino UNO. Dazu muss die Bibliotheksdatei

HCMAX7219 von Hobby Components aus dem Internet heruntergeladen werden.

Der Schaltungsaufbau gestaltet sich einfach und ist mit 5 Verbindungskabeln schnell erledigt.


Schaltskizze und Schaltungsaufbau




Das Programm

In diesem Programm wird zuerst ein Text "Bitte nicht stoeren!!!!" als Lauftext auf dem Display ausgegeben, gefolgt von einer Zeitdarstellung in Stunden, Minuten undSekunden.

Die Sekunden werden von 0 bis 59 hochgezählt.

Das Anzeigeformat:  hh mm ss


Abbildung 9 - Programm zur Programmbibliothek HCMAX7219 von Hobby Components


5 - Die Bibliotheksdatei HCMAX7219

Die Bibliotheksdatei enthält ca. 15 Funktionen, von denen ich nur einige wenige anspreche, die im gezeigten Test-Programm benutzt werden.

  • HCMAX7219.Init()

Initialisiert die Bibliothek und sollte zu Beginn eines Programmes gestartet werden.

  • HCMAX7219.print7Seg("Text String", Offset)

Schreibt einen Text in den Ausgabepuffer der Position Offset. Offset gleich 1 beginnt mit der Textausgabe bei Digit 1, Treiber 1.

  • HCMAX7219.Clear()

Löscht den Inhalt des Ausgabepuffers. Anschließend wird die Bibliotheksfunktion refresh aufgerufen und alle LEDs abgeschaltet.

  • HCMAX7219.Refresh()

Aktualisiert alle verbundenen Driver mit dem Inhalt des Ausgabepuffers.

 

Eine vollständige Darstellung aller Funktionen findet man auf den Seiten von Hobby Components.

 

Ausblicke

Mit Hilfe der Funktionen aus der Bibliothek lassen sich verschiedene Aufgabenstellungenumsetzen:

  • Zeitmesser bauen.
  • Uhr mit Zeitangabe in HH MM SS entwickeln.
  • Zeitmesser mit gekoppelter Lichtschranke für Physikexperimente entwickeln.

---  ---

Der oben beschriebene zweite Ansatz über die Entwicklung eigener Funktionen, die den Treiberbaustein MAX7219 ansteuern und damit individuelle Programmlösungen zulassen, ist aufwändiger aber auchlehrreicher.

6 - Ansteuerung des MAX7219

Der IC MAX7219 ist ein seriell anzusteuernder Display Treiber, der sich für die Aufgabe, acht 7-Segment-Anzeigen anzusteuern, hervorragend eignet.

Voraussetzung istbei diesem Baustein, dass die Anzeigeelemente eine gemeinsame Kathode haben.

Die Leistungsmerkmale des MAX7219 in Kurzform:

  • verfügt über ein 8x8 statisches RAM
  • belegt nur 3 I/O Pin des Controllers (DIN, LOAD, CLK)
  • ermöglicht Helligkeitskontrolle über ein Kontrollregister
  • hat einen Funktionstest-Modus, der alle 7 Segmente eines Anzeigemoduls einschaltet
  • verfügt über einen internen Multiplexer
  • kann bis zu acht 7-Segment-Anzeigen oder 64 LEDs ansteuern
  • steuert die einzelnen 7-Segment Bausteine im Multiplexbetrieb mit ca. 800Hz an.

Dem Datenblatt lassen sich die folgenden Informationen entnehmen.


DIN     Eingang für die seriellen Daten vom Controller. Erwartet werden 16-Bit Pakete.CLK    Takteingang, der vom Controller generiert wird. Steigende Flanken veranlassen das Einlesen von Daten in ein Schieberegister des MAX7219. Bei fallender Flanke werden die Daten an DOUT ausgegeben. Maximal zulässig ist eine Taktrate von 10 MHz.LOAD Nach jedem 16-Bit Datenpaket, das der MAX7219 erhalten hat, wird ein kurzer negativer Impuls angelegt. Bei steigender Flanke werden die Daten in das vorher angesprochene Register geladen.

Datenformat

Die an DIN seriell eintreffenden 16-Bit Datenpakete werden mit jeder steigenden Flanke des Taktsignals (CLK) in ein internes 16-Bit Schiebregisterabgelegt; unabhängig von den Ereignissen, die auf LOAD passieren.

Anschließend werden diese Daten mit steigender Signalflanke an LOAD(CS) in ein Kontroll- oder  Digitregister (Digit 0, ..., Digit 7) geschrieben.

Nach16 CLK-Takten muss LOAD auf HIGH gehen.

Die im Schieberegister abgelegten Daten werden dann am Ausgangspin DOUT des MAX7219 mit der fallenden Flanke des Taktgebers ausgegeben.

Insgesamt gibt es 14 Register, die einzeln über ihre Adresse angesprochen werden.

Registeradressen

Abbildung 10 - Alle 14 Registeradressen des MAX 7219


  • No-Op (0x00)

Wird nur bei Nutzung mehrerer MAX7219 (Kaskadierung) beschrieben.

  • Shutdown (0x0C)

Ein LOW in 0x0C setzt alle Anoden einer 7-Segment-Anzeige auf GND; die LEDs werden ausgeschaltet.

Die Daten bleiben bei einem Shutdown erhalten.

Eine 1 in 0x0C legtalle Anoden der 7-Segment Anzeige wieder auf die internen Steuerleitungen.

  • Decode Mode (0x09)

BCD-Code oder kein Code wählen.

Abbildung 11 - Decode Mode Register mit den vier möglichen Einstellungen
  • Intensity Register (0x0A)

Steuert über PWM die Helligkeit der 7-Segment-Anzeige; 0x00 (minimal) bis 0x0F (maximal).

 

  • Scan Limit Register (0x0B)

Legt die Anzahl der Digits (wie viele 7-Segment-Anzeigen) fest. Möglich sind die Werte von 0x00 bis 0x07.

Die Helligkeit nimmt mit der Zahl der Digits ab; dieAbtastrate liegt bei 8 angeschlossenen Digits bei 800Hz.

 

  • Display Test Register (0x0F)

Dient für einen Funktionstest der angeschlossenen Anzeigemodule.

7 - Propeller Board und MAX7219


Mit Hilfe der Daten und einem Blick auf das Zeitdiagramm des MAX7219 im Datenblatt kann jetzt mit dem Programmieren begonnen werden.

Als Controllerboard wirddiesmal ein Prop-BoE oder ein Prop-AB genommen und gezeigt, wie man sich seine eigenen Zugriffsfunktionen an Hand der Daten aus dem Datenblatt entwickeln kann.

Ansteuerung einer 8-stelligen 7-Segment-Anzeige mit dem Prop BoE
Material
  • 1x  Prop-BoE  oder Prop-AB mit USB-Verbindungskabel
  • 1x  Steckernetzteil
  • 1x  8-stellige 7-Segment-Anzeige
  • 5x  Steckdraht (female - male)
Aufgaben
  • Baue die Schaltung wie in der folgenden Abbildung auf.
  • Übertrage das Programm DisplayTest1.c in den Editor und speichere es ab.
  • Bevor du das Programm startest, überlege, wie das Programm arbeitet und mache dir Notizen.
  • Starte das Programm und beobachte die Ausgabe auf dem Display. Werden zu Beginn alle Anzeigen eingeschaltet (ca. 1s) und anschließend wieder aus? Werden anschließend nur inder ersten Anzeige die Zahlen von 0 bis 9 und die Zeichen -, E, H, L, und P angezeigt?

Schaltungsaufbau



Das Programm DisplayTest1.c

Abbildungs 13 - DisplayTest1.c Programm




Wie arbeitet das Programm DisplayTest1.c?

  • Zeilen 4 - 6

Die Anschlüsse 9, 10 und 11 werden über die Textersetzung direkt nach den Anschlussbelegungen auf dem 8-stelligen 7-Segment-Anzeige-Board benannt.

In Zeile 10 erfolgt eine FORWARD-Deklaration einer Funktion an_MAX. Schauen wir uns zunächst diese Funktion genauer an.

  • Zeilen 34 - 40

Die Parameter der Funktion sind: p_out, p_clk, _bit und _data, alle vom Typ integer. p_out und p_clk beschreiben dieI/O Ports, die mit DIN bzw. CLK des 8-stelligen Moduls verbunden sind und _bit gibt die Anzahl der zu übertragenden Bits an. _data steht für die an das Modul zuübertragenden Daten.

Die Funktion setzt den I/O Port cs auf LOW und überträgt anschließend Daten an den 8-digit Anzeigemodul. Dabei wird das MSB zuerst übertragen.

Nach Abschluss derÜbertragung wird die Leitung cs sofort wieder auf HIGH gesetzt.

  • Zeilen 12 - 32

Im Hauptprogrammteil main() wird in Zeile 14 das Display Testregister (0x0F) für eine Sekunde in den Testbetrieb geschaltet und anschließendwieder auf Normalbetrieb zurückgesetzt.

In Zeile 18 wird im Decode Register die Einstellung so gewählt, dass alle Digits der Anzeige im BCD-Code arbeiten.

Anschließend wird über das IntensityRegister die Leuchtintensität der einzelnen Anzeigen auf geringste Intensität (00) gesetzt (Zeile 19).

Das Scan Limit Register beschränkt die Ausgabe auf das erste Anzeigenelement 0 (Zeile 20) und setzt anschließend über das Shutdown Register dieAnzeige in den normalen Betrieb.

Die Endlosschleife (Zeilen 24 - 31) regelt die Ausgabe der Zahlen und Zeichen.

Die Schleife wird 16-mal durchlaufen und an die erste 7-Segment-Anzeige (0x01) werdendie Inhalte der Variablen i übergeben; das sind die Zahlen von 1 bis 16.

Nun lassen sich bekanntlich auf einer einstelligen Anzeige keine zweistelligen Zahlen, wie zum Beispiel 10, 11 oder 12 darstellen.

Ein Blick in das Datenblatt des MAX7219 Bausteins (S. 8) verrät,dass die Zeichen -, E, H, L und P statt der Zahlen 10, 11, 12, 13 und 14 ausgegeben werden.

Die Zahl 15 wird im Display als "blank", also Leerzeichen, dargestellt und bleibt für uns unsichtbar.

Jetzt kommst du!

  • Wandle das Programm DisplayTest1.c so ab, dass die Zahlen von 0 bis 7 von rechts nach links in den acht 7-Segment-Anzeigen stehen(Abb. 8).
  • Wandle das Programm DisplayTest1.c so ab, dass die Zahlen von 0 bis 7 von links nach rechts in den acht 7-Segment-Anzeigen stehen(Abb. 8).
  • Wie man auf dem 8-stelligen Display sieht, werden die alten Zeichen nicht gelöscht, wenn im weiteren Verlauf nur mit ein oder zwei Displaysweiter gearbeitet wird. Füge in das Programm eine Programmzeile ein, die bei jedem Start alle Anzeigenelemente löscht (mit einem Leerzeichen füllt).


8 - Arduino und MAX7219

Die Ansteuerung des MAX7219 über den Arduino UNO erfolgt ähnlich wie bei den Propeller Controllern, mit demUnterschied, dass beim UNO diesmal der SPI-Bus benutzt wird, der mit vier Pin vorbelegt ist.

Von dem Bus werden drei Leitungen benutzt: MOSI, SCK und SS, die im Programm über dieBibliotheksfunktionen aus dem Ordner SPI.h angesprochen werden.

Die Funktionen der Bibliothek SPI.h (ein Auszug)

 

  • spi.transfer(val)

Parameter

val  enthält den Wert, der über den Bus an den Baustein übertragen wird.

 

  • spi.setBitOrder(order)

legt fest, ob die auf den Bus gelegten Bits beginnend mit dem MSBFIRST (most significant bit) oder LSBFIRST (least significant bit)übertragen werden sollen.

Parameter

order      LSBFIRST oder MSBFIRST

 

  • spi.begin()

Initialisiert den SPI Bus, indem die I/O Pin SCK, MOSI und SS als OUTPUT gesetzt werden. SCK und MOSI werden auf LOW und SS auf HIGHgezogen.

MOSI: Master Out Slave In; die Masterverbindung, über die Daten an die Slaves übertragenwerden.

SCK: Serial Clock

SS: Slave Select - der Pin, über den der Master ein Bauteil ein- bzw. ausschalten kann. HIGH bedeutet, keinKontakt mit Master; LOW bedeutet, Kommunikation mit dem Master.

 

Auf dem Arduino UNO Board sind folgende I/O Pin als SPI Ports vorbelegt:

MOSI: Pin 11

SCK: Pin 13

SS: Pin 10

 

  • spi.end()

Beendet den SPI Bus.

Testschaltung mit MAX7219 - 8-stelliger 7-Segment-Anzeige und Arduino UNO
Aufgaben
  • Übertrage das Programm DisplayTest1_Arduino.ino in den Editor und speichere es ab.
  • Schließe die 8-stellige 7-Segment LED Anzeige nach Abb. 7, 8 an das Arduino Board an.
  • Starte das Programm und überprüfe, ob
    -  alle 8 Anzeigen eingeschaltet werden und für ca. 1 Sekunde in diesem Zustand verbleiben.

    alle 8 Anzeigen anschließend aus gehen.
    die 1. Anzeige die Zahlen von 0 bis 9 und weitere Zeichen zeigt.

Das Programm DisplayTest1_Arduino.ino





In Abschnitt 7 wurde bereits auf die verschiedenen Register und wie sie anzusprechen sind eingegangen.

Die Programme Prop-C und Arduino-C ähneln sich sehr stark, obwohl beim Arduino auf den SPI-Bus und die damit verbundenen Befehle zugegriffen wurde.

Eine erneute Besprechung für dieses Programm entfällt.

Quelle:
https://www.rahner-edu.de/mikrocontroller/themen-und-projekte/7-segment-anzeigen/



********************************************************I*
Arduino Smartmeter - Wh Meßgerät - Impulsmesser - Impulszähler
          Fa. B+G E-Tech DRT428B digitaler Drehstromzähler
Stromzähler für DIN Hutschiene - Energiemessgerät 400V 20(80) A mit S0 Schnittstelle

Hersteller:  ‎B+G E-Tech
Artikelnummer:  ‎DRT428B
400Vac / 20(80)A
S0 Schnittstelle mit 1000 Imp./kWh
LCD Display blau Hinterleuchtet
Stromzähler für Hutschiene

Am Markt gibt es sehr viele Stromzähler bzw. Subzähler die in der Lage sind, ihre Daten an ein anderes System weiterzugeben.
Dafür gibt es verschiedene Schnittstellen wie den ModBus, S0 oder auch Serial.
In diesem Artikel geht es um das mitschreiben von verbrauchten Wattstunden mittels eines Arduino Board über S0.

- Wie funktioniert S0
Das S0 System von Stromzählern ist ein einfacher Impuls, der bei jedem verbrauchten Watt erzeugt wird.
Dieses System hat absolut nichts mit der bekannten S0-Schnittstelle vom ISDN zu tun.
In dem Zähler befindet sich meistens ein Optokoppler oder Relais, das nach jedem verbrauchten Watt einen kurzen Impuls gibt, indem der angeschlossene Stromkreis geschlossen wird.
Die Impulszeit ist nicht standardisiert und je nach Hersteller unterschiedlich.
In der Regel dauert ein Impuls etwa 20 - 100 Millisekunden.
Ebenso gibt es auch keine bestimmte Größe pro Impuls.
Bei den meisten Zählern entspricht ein Impuls einem verbrauchten Watt.
Auf Wikipedia gibt es eine genaue Beschreibung von der S0-Schnittstelle.

- Anschluss an den Ardunio
Um eine S0-Schnittstelle mit dem Arduino zu verbinden, wird lediglich ein Widerstand benötigt.
Die 5V Spannungsversorgung vom Arduino wird die S0-Klemme vom Zähler durchgeschliffen und geht zu einem Interrupt-Pin (D2).
Damit der digitale Eingang vom Arduino ein genaues Signal bekommt wird hier in Serie zur Masse ein PullDown-Widerstand von etwa 10k Ohm geschaltet.
Gibt der Zähler einen Impuls, so geht der Pegel am digitalen Eingang in dieser Zeit von Low auf High.

- Wattstunden zählen und Speichern
Mittels Interrupt werden am Arduino die Wattstunden gezählt.
Der Beispielcode enthält eine Integer-Variable, die bei jedem Impuls um eine Eins erhöht wird.
Damit kann der Wattverbrauch seit dem Programmstart mitgezählt werden.
Bei einem Reset oder Stromausfall gehen jedoch am Arduino die gezählten Wattstunden verloren.
Um dies zu verhindern, kann der Zählerstand in einem bestimmten Intervall auf den internen EEPROM gespeichert werden.
Um den EEPROM jedoch zu schonen, sollte der Schreibvorgang im Dauerbetrieb nur alle paar Stunden durchgeführt werden.

- Der Beispielcode
Wenn die Software startet, wird der Zählerstand vom EEPROM eingelesen und die Integer Variable "wh_total" damit beschrieben.
Parallel dazu startet auch ein weiterer Counter, der die verbrauchten Wattstunden seit dem Reset bzw. Systemstart mitzählt. Die S0-Impulse werden als Interrupt empfangen.
Bei jedem Interrupt wird die Counter-Funktion aufgerufen und die beiden Zählerstände um den Wert "1" erhöht.
Die Speicherung des Zählerstandes in den EEPROM erfolgt nach einem definierbaren Intervall.
Achtung:
 In diesem Beispiel werden aufgrund der Einfachheit alle Zählerstände als Integer definiert.
Integer ist ein Zahlenwert-Datentyp, der bis max 32.767 bzw. 65.535 als unsigned Integer geht.
Damit ist es möglich, bis zu 65 Kilowattstunden zu zählen.
Wenn das nicht ausreicht, kann anstatt dem Datentyp Integer auch Long verwendet werden.


ARDUINO Sketch
#include <EEPROM.h>int interval = 5;  //Counter refresh and save intervalint wh_start, wh_total;int pulseCount, crontimer; void setup() {Serial.begin(9600);attachInterrupt(0, onPulse, FALLING);}void loop() {  if(millis()/1000 > crontimer+interval){    crontimer = millis()/1000;    wh_total = read_counter(0);    wh_total = wh_total+pulseCount;    save_counter(0, wh_total);    pulseCount = 0;         Serial.print("Start Wh: ");    Serial.println(wh_start);    Serial.print("Total Wh: ");    Serial.println(wh_total);    Serial.println("================");  }}int read_counter(int address){  long byte_2 = EEPROM.read(address);  long byte_1 = EEPROM.read(address + 1);  return ((byte_2 << 0) & 0xFFFFFF) + ((byte_1 << 8) & 0xFFFFFFFF);}void save_counter(int address, int value){  byte byte_2 = (value & 0xFF);  byte byte_1 = ((value >> 8) & 0xFF);  EEPROM.update(address, byte_2);  EEPROM.update(address + 1, byte_1);}void onPulse(){    pulseCount++;    wh_start++;}


Quelle:
https://www.aeq-web.com/arduino-smartmeter-s0-interface/
https://www.youtube.com/watch?v=zNBYUA3l4Oo&list=PLoMSZGQFQMtKWh3RjU8dj7HKUs7bHq4GL




********************************************************I*
   AD8232 heart rate sensor module
                     Heart Monitor

ICQUANZX EKG-Modul AD8232 EKG-Messung Puls Herzfrequenzsensor Modul Kit EKG-Überwachungssensor für Arduino mit Dupont-Kabel




AD8232 verwendet ein zweipoliges Hochpassfilter, um die Bewegungsartefakte und das Elektrodenhalbzellenpotential zu beseitigen
Der AD8232 verwendet einen Operationsverstärker, der ohne Einschränkungen ein dreipoliges Tiefpassfilter baut, wodurch zusätzliche Geräusche vermieden werden
Nenntemperaturbereich: 0 - 70 Grad
Arbeitstemperaturbereich: -40 - 85 Grad
Anwendung: Fitness- und Sportherzfrequenzüberwachung; Tragbares EKG; Remote Health Monitor

Quelle:
https://www.amazon.de/ICQUANZX-EKG-Messung-Herzfrequenzsensor-EKG-%C3%9Cberwachungssensor-Dupont-Kabel/dp/B088R8VZ74/ref=asc_df_B088R8VZ74/?




********************************************************I*
               ARDUINO UNO R3


VL53L0X TOF Laser Distanz Sensor
13.06.2021
Video
https://www.aeq-web.com/arduino-vl53l0x-time-of-flight-sensor-library-test/
Der VL53L0X ist ein Time-of-Flight Laser Distanz Sensor mit bis zu 2 Meter Reichweite. Ist dieser Sensor eine alternative zu Ultraschall?



Drehzahlmesser von Lüfter auswerten
21.02.2021
Video
DE/EN
https://www.aeq-web.com/arduino-pc-lufter-drehzahl-messen-uber-tachosignal/
Lüfter in PCs und Industrieanlagen verfügen über eine Tachosignalleitung. In diesem Artikel geht es um die Drehzahlmessung eines Lüfters mit dem Arduino



Temperatur messen mit PT1000 & Arduino
20.12.2020
Video
DE/EN
https://www.aeq-web.com/pt1000-temperature-sensor-arduino-lm358-messwandler/
PT1000 Sensoren können nicht direkt analog mit einem Mikrocontroller gemessen werden. Wie baut man einen Messwandler mit dem LM358 für den PT1000 und Arduino?



Arduino Anemometer Schaltung
29.11.2020
Video
DE/EN
https://www.aeq-web.com/arduino-anemometer-wind-sensor/
Mit einem Mikrocontroller wie dem Arduino, einer kleinen Schaltung und entsprechender Software kann die Windgeschwindigkeit über ein Anemometer gemessen werden

 


UDP Message Server Code
06.11.2020
https://www.aeq-web.com/arduino-python-udp-polling-server/
Auf dieser Seite gibt es den Python Source Code für das Projekt: Arduino Bidirektional steuern über das Internet hinter NAT



Arduino Radiosender mit RDS
09.10.2020
Video
https://www.aeq-web.com/arduino-rds-radio-text-fm-transmitter-si4713/
Das Adafruit SI4713 FM-Transmitter Board ist ein kleiner Radiosender, der neben Stereo Musik auch den Radiotext und RDS Informationen übertragen kann.



Arduino über PHP steuern
02.08.2020
https://www.aeq-web.com/arduino-led-steuern-mit-udp-und-php-ueber-internet/
In diesem Artikel geht es um die weltweite Steuerung und bidirektionale Verbindung zum Arduino über eine Webseite bzw. PHP.



Arduino weltweit steuern
26.07.2020
Video
https://www.aeq-web.com/arduino-ethernet-bidirektionale-verbindung-hinter-nat-und-firewall-weltweit-steuern/
Über das Ethernet Shield kann ein Arduino weltweit gesteuert werden. Hier geht es um den Aufbau einer bidirektionalen UDP Verbindung hinter NAT und Firewalls



Arduino UDP Controller Code
26.07.2020
https://www.aeq-web.com/arduino-bidirectional-udp-communication-code/
Auf dieser Seite gibt es die Arduino Code-Dokumentation zum Projekt: Arduino Bidirektional steuern über das Internet hinter NAT



Arduino HTTPS Request
05.06.2020
DE/EN
https://www.aeq-web.com/arduino-ethernet-shield-secure-tls-https-post-get-request/
In diesem Artikel klären wir, welche Voraussetzungen notwendig sind, um einen verschlüsselten HTTPS Request mit dem Arduino durchzuführen.



Arduino Interrupt einstellen
17.05.2020
Video
https://www.aeq-web.com/arduino-microcontroller-interrupt-function/
Interrupt ist eine geniale Funktion, die nahezu jeder Mikrocontroller kann. In diesem Artikel geht es um die praktische Anwendung von Interrupts am Arduino



Spannungsteiler für Mikrocontroller
21.03.2020
https://www.aeq-web.com/spannungsteiler-microcontroller-berechnen-und-dimensionieren/
In diesem Artikel geht es um die Dimensionierung und Berechnung von Spannungsteilern speziell für digitale und analoge Eingänge von Mikrocontrollern & Boards



Relais steuern mit Mikrocontrollern
08.03.2020
Video
https://www.aeq-web.com/relais-mit-microcontroller-ansteuern-und-die-schaltungen/
Wie werden Relais richtig über Mikrocontroller gesteuert? Was ist zu beachten? Hier gibt es die Schaltpläne und alle Infos über die galvanische Trennung



Siebensegmentanzeige mit HC595
22.02.2020
Video
https://www.aeq-web.com/siebensegment-display-74hc595-schieberegister-arduino/
In diesem Artikel geht es um die effiziente Ansteuerung einer Siebensegment-Anzeige über ein Schieberegister. Als Controller wird ein Arduino Uno verwendet.



GY906 Infrarot Temperatur Sensor
11.01.2020
Video
https://www.aeq-web.com/arduino-pyrometer-mxl90614-gy906-infrarot-temperatur-sensor/
In diesem Artikel dreht sich alles um den MXL90614/GY906 Temperatursensor in Verbindung mit einem Arduino Uno über die I2C Schnittstelle



Arduino Uno vs. WeMos D1
29.11.2019
Video
https://www.aeq-web.com/wemos-d1-r1-r2-vs-arduino-uno-shield-compatibility/
In diesem Artikel vergleichen wir das WeMos D1 mit dem Arduino Uno. Außerdem klären wir den Unterschied zwischen R1, R2 und der Arduino Shield kompatibilität



Arduino und der EEPROM
15.11.2019
Video
https://www.aeq-web.com/arduino-atmega-eeprom-read-write-details/
In diesem Artikel befassen wir uns mit den Grundlagen vom EEPROM Speicher und zeigen wie vom Arduino aus Bytes, Boolean, Int und Strings gespeichert werden



Arduino Smartmeter
01.11.2019
Video
https://www.aeq-web.com/arduino-smartmeter-s0-interface/
In diesem Artikel zeigen wir, wie aus einem einfachen Stromzähler und einem Arduino ein Smartmeter gebaut wird, das den Zählerstand im EEPROM speichern kann



Arduino 230V Dimmer
05.10.2019
Video
https://www.aeq-web.com/230v-ac-arduino-dimmer-pahsenanschnitt/
In diesem Artikel zeigen wir, wie man mit einem Arduino mittels Phasenanschnitt einen Dimmer für Lampen, Motoren und kleine Heizungen baut und Leistung regelt



Arduino Blitzdetektor Shield
04.09.2019
https://www.aeq-web.com/ramser-blitz-o-shield-arduino-blitzdetektor/
In diesem Artikel berichten wir über den neuen Blitzdetektor Bausatz (Blitz-O-Shield) für das Arduino Board von Ramser Elektrotechnik









DIN A4  ausdrucken
********************************************************I*
Impressum: Fritz Prenninger, Haidestr. 11A, A-4600 Wels, Ober-Österreich, mailto:[email protected]
ENDE