Strom- und Wasserzähler mit IR Sensor aufbauen

Guten Morgen Liebe Forums Mitglieder,

Ich habe die bekannte Suchmaschine schon rauf und runter gesucht und Beiträge gefunden, aber leider nichts was mein Problem darstellt oder ähnelt.
da ich hier neu bin, wollte ich euch mal um einen Rat bitten.
Vor gut 1-2 Wochen bin ich auf die Idee gekommen meinen Stromzähler (Digital mit IR LED impulsen) und einen Analogen Nassläufer Wasserzähler auszulesen.
Da ich ein KNX basiertes Smarthome habe ist es relativ schwer günstige Sensoren oder ähnliches dafür zu bekommen. Ca. 90€ pro Zähler.

Ich habe die bekannte Suchmaschine schon rauf und runter gesucht und Beiträge gefunden, aber leider nichts was mein Problem darstellt oder ähnelt.

Jetzt habe ich mich in die Welt des Arduino vertieft und ich denke bzw. hoffe das ich die Grundlagen soweit verstanden habe. Ich habe bereits auch einige Sketche versucht zu schreiben. Beim Testen schien dieser erstmal auch zu funktionieren, jedoch habe ich das Problem, dass der Sensor oder die Logik anscheinend kein sauberes High-Low detektiert und mir quasi bei einem Zähldurchgang direkt mehrere "Zählungen" detektiert.

Zum Aufbau: Ich habe für beide Messungen den selben Typen Sensor verwendet den TCRT5000.

Um die Stromzähler IR-LED impulse zu "messen" habe ich auf dem sensor die IR-LED entfernt, sodass nur noch die Fotodiode/transistor drauf ist. Diese detektiert dann auch das Signal.

Beim Wasserzähler musste ich etwas umändern damit das Licht den roten Pfeil für die Umdrehung erkennt. Angepasst habe ich diesen Sensor so als wie in diesem Beitrag beschrieben:
Wasserzähler Sesnor Umbau

Zum testen habe ich das Arduino MEGA 2560 Board angeschlossen an ein Breadboard mit einem LCD Display (16,2) und einem Poti für den Kontrast. Selbstverständlich auch den Sensor.

Der Funktionsablauf sollte wie folgt sein (im test sketch Wasserzähler):

Der Sensor soll bei einer Umdrehung des 1L zähler einen Impuls detektieren.
Dieser soll von Arduino ausgewertet werden und einen Counter hochzählen welcher auch im Display Aktuell angezeigt wird. Außerdem soll bei jedem 5 Impuls ein Relais geschaltet werden für ca 200-500 mS. In meinem Test sketch habe ich dazu die interne LED (Out 13) verwendet.
Wie oben schon erwähnt funktioniert das Prinzip auch, der Zähler zählt und das Relais schaltet. Nur bekomme ich eben keinen klaren 1 impuls sondern direkt eine Vielzahl.

Da ich momentan auf der Arbeit bin, kann ich den aktuellen Sketch leider nicht posten. Beigefügt sind 2 Bilder von meinem Sketch Entwurf bei dem ich angefangen habe bevor ich die Einzelheiten angepasst habe auf die Ports vom MEGA2560 Board.

Außerdem habe ich in dem jetzigen Code stehen: bei Void Impulscheck die zeile geändert:
impuls = impuls + pulsschritte

und darunter noch eine Zeile eingefügt:
Counter = Counter + 1

Ich hoffe das man etwas erkennen kann. Sobald ich Zuhause bin nachher werde ich den Sketch Code als Code hier posten.
Gegebenenfalls hat aber jemand von euch ja schon eine Idee woran es liegen könnte oder was ich machen kann damit ich das Problem beheben kann?

Über eine Rückmeldung wäre ich Dankbar.
Vielen Dank schonmal.

Liebe Grüße
Dennis.

Und hier ist noch das Bild vom 2en Teil des Sketches.

dennis15015:
Und hier ist noch das Bild vom 2en Teil des Sketches.

Hihi, klasse. Stelle den Sketch doch in Quelltext-Form direkt hier ins Forum. Wenn Du Code-Tags benutzt, ist er auch gut für Leute mit Tablet zu lesen.

Gruß

Gregor

Hallo Gregor,

danke für deine Antwort.
Wie ich bereits in meinem Start post erwähnt habe, ist der Code auf meinem Laptop welcher Zuhause liegt ;). Sobald ich nachher Zuhause bin werde ich selbstverständlich den Code hier wie es sich gehört einfügen :). Hatte den Post nur schon mal geschrieben, das man sich schon mal Gedanken machen kann. Evtl. hat ja jemand schonmal von dem Problem gehört oder es selbst gehabt. Mir ist aber auch klar das man den Code benötigt um genauer zu schauen was die Ursache sein kann.

Lg
Dennis.

Hallo dennis,
ich denke du brauchst für den Fankenwechsel keinen Interput:
So könnte es innerhalb der Loop aussehen mann muss sich den aktuellen Status einlesen und den letzten merken gibt es einen Änderung von LOW nach HIGH muss du zählen + 1 und nur dann.
Damit sollte es soweit klappen
#Hier der Pseudocode

void loop(){
 state = digitalRead (inputPin);
 
 //Flankenwechsel erkennen
 if(laststate == LOW && state == HIGH) {
    //zähler erhöhen
    count++;
 }
//letzten zustand merken 
 laststate = state; 
}

Gruß
DerDani

dennis15015:
Wie ich bereits in meinem Start post erwähnt habe, ...

Uh, das habe ich überlesen, sorry.

Was Du beschreibst, klingt nach „prellen“, aber das kann's ja eigentlich nicht sein.

Ich würde zunächst die Ablesung nicht per Interrupt erledigen, sondern das in loop() unterbringen. So schnell wird sich der Zeiger ja nicht drehen. Dann könntest Du mal aufzeichnen, was konkret am Eingang ankommt - Serial.print(), ein Terminal-Programm und gnuplot sind Deine Freunde (s. hier, da habe ich mal einen Akku-Ladevorgang verfolgt).

Gruß

Gregor

Hallo Dani,

danke für deine Antwort. Ich werde das nachher direkt mal ausprobieren mit deinem Vorschlag.
Ich hatte den selben test auch versucht zu übernehmen in einem "taster" sketch.
Mit dem last state etc. Hatte auch funktioniert von der Funktion aber auch da genau das selbe das ich mit einer Sensor erfassung direkt mehrere Erfassugen auf dem Counter hatte.

Würde das dann auch noch funktionieren wenn ich das auch für den Stromzähler benutzen würde?
Dieser gibt ja shcnell IR impulse 10.000 Imp/KWh sprich bei ca 7kw/h sind es dann schon

70.000 Imp = 1166 IMP/min = ~20 Imp/Sek

würde das dann dennoch funktionieren von der Geschwindigkeit? Ich hatte mehrfach geelsen das am Arduino bis 50Hz wohl kein Problem wäre und Interrupt hier wohl am sinnvolsten wäre.

Der Wasserzähler läuft ja nicht soschnell (zum Glück ;D )

@Gregor
ja ich hatte da auch schon dran gedacht das es evtl. irgendeine Form von "prellen" ist, deshalb habe ich es auch schon umegschrieben zu einem Sketch der normal bei Tastern verwendet wird. Mit dem selben Ergebnis.

Lg
Dennis.

dennis15015:
ja ich hatte da auch schon dran gedacht das es evtl. irgendeine Form von "prellen" ist, deshalb habe ich es auch schon umegschrieben zu einem Sketch der normal bei Tastern verwendet wird. Mit dem selben Ergebnis.

Mit einem mechanischen Kontakt handelst Du Dir auf jeden Fall ein Prell-Problem ein. Probiere wie gesagt erst einmal aus, das konkret erfasste Signal aufzuzeichnen.

Was die Geschwindigkeit angeht: Eines meiner Gebastel durchläuft loop() knapp 19.000 mal pro Sekunde, ein anderes Gebastel zeigt eine 7x7-Matrix von LEDs rund 70 mal pro Sekunde. 50 Hz sind ein Klacks.

Gruß

Gregor

gregorss:
Mit einem mechanischen Kontakt handelst Du Dir auf jeden Fall ein Prell-Problem ein. Probiere wie gesagt erst einmal aus, das konkret erfasste Signal aufzuzeichnen.

Ja werde mich heute Abend auf jedenfall mal dran versuchen. Deinen Vorschlag umzusetzen und auch den von Dani.

Lg Dennis.

Ich denke bei IR Sensor sollte es keine prellen geben und dem Sinne auch keine falschen Impulse. Was aber oberste Prämisse ist kein einizges delay() im ganzen Code!.
Immer schön bei "blink without delay" bleiben. Oder hier im Forum nach der Nachtwächter Erklärung arbeiten.

Gruß
DerDani

volvodani:
Ich denke bei IR Sensor sollte es keine prellen geben und dem Sinne auch keine falschen Impulse. Was aber oberste Prämisse ist kein einizges delay() im ganzen Code!.
Immer schön bei "blink without delay" bleiben. Oder hier im Forum nach der Nachtwächter Erklärung arbeiten.

Ja sollte es nicht. Ich weiß auch nicht warum genau das Signal so schlecht kommt bzw so oft zählt.
Ich vermute ja das dieses Signal nicht richtig auf 0 geht oder eben pulsiert während es erkannt wird?
Vom Zeitpunkt das der Zeiger erkant wird bis hin das, dass Signal durch die led auf dem board 0 anzeigt vergeht schon eine Sekunde und man sieht auch das die led ein wenig "flackert" oder "pulsiert" während dessen es ein "HIGH" sendet oder sonst etwas.

Evtl schaffe ich es auch heute Abend mal ein Video davon zu machen.

Das mit dem Delay hatte ich auch schon gelesen. Werde es später auch entfernen. Hatte das nur eingebaut um sicher zu stellen das der Ausgang Lange genung geschaltet ist für den Bus-Ankoppler der später am relais Ausgang angeschlossen werden soll.

Lg
Dennis.

Hi

Zur Not sollte auch analogRead gehen, hier die Minima und Maxima mithalten und Impuls nur generieren, wenn wir 'das erste Mal durch Null' gehen - diesen Merker resetten, wenn wir 80% von Minimum/Maximum erreicht haben.

Andere Frage: Wie bekommst Du diese Werte dem KNX beigebracht?

MfG

Guten Abend zusammen,

wie versprochen hier mein Ursprünglich getesteter Quell Code :wink:

#include <LiquidCrystal.h> 
LiquidCrystal lcd(22, 23, 24, 25, 26, 27);

const int relais = 13;
const int IRsensor = 20;
volatile int pulsschritte = 1;
volatile int impuls = 0;
volatile int Counter = 0;
volatile int sensorstatus = 0;

void setup() {
  // put your setup code here, to run once:

pinMode(relais, OUTPUT);
pinMode(IRsensor, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(IRsensor),Impulscheck, RISING);
lcd.begin(16, 2);

}

void loop() {
  // put your main code here, to run repeatedly:
lcd.setCursor(7,1);
lcd.print(impuls);

if(Counter == 0 || Counter == 5)
{
 digitalWrite(relais,HIGH);
 delay(200);
 digitalWrite(relais,LOW); 
}

}


void Impulscheck() {

sensorstatus = digitalRead(IRsensor);
impuls = impuls + 1;
Counter = Counter + pulsschritte;
if (Counter == 0 || Counter == 5)
{
pulsschritte = -pulsschritte;
}

  
}

Ich versuche mich gleich auf jedenfall mal an die Zahlreichen Hilfestellungen die, ihr mir gegeben habt.
In der Hoffnung das ich das hinbekomme :slight_smile:

postmaster-ino:
Hi

Zur Not sollte auch analogRead gehen, hier die Minima und Maxima mithalten und Impuls nur generieren, wenn wir 'das erste Mal durch Null' gehen - diesen Merker resetten, wenn wir 80% von Minimum/Maximum erreicht haben.

Wie stelle ich das denn am geschicktesten an? Ich bin schon froh das ich nach den paar tagen in denen ich die Beispiele aus dem Forum in mich aufgesaugt habe, dass ich das schon hinbekommen habe.
Denke das was Gregor und Dani vorgeschlagen haben so noch hinbekommen werde.
Werde gleich mal versuchen wie weit ich komme. :wink:

postmaster-ino:
Andere Frage: Wie bekommst Du diese Werte dem KNX beigebracht?

Dafür soll das Relais am Ausgang sein, welches beim Wasserzähler zu jeder Umdrehung (1L) ein Impuls an das Relais sendet welches dann an ein Binär KNX eingang angeschlossen ist. Ebenfalls beim Stromzähler soll dann quasi bei jedem 10.000 Impuls (1kWh) an ein anderes Relais gesendet werden, welches auch wieder auf ein KNX eingang geht. Von dort aus will ich das dann über meine Visu verwalten.

Lg
Dennis.

Hi

Binär-Eingang - wenn's 'Spielstrom' ist, könnte dort auch ein schnöder Opto-Koppler reichen, Den der Arduino ansteuert.
Wenn Du mit den Binär-Eingängen auch 'Mehr' machen kannst - der Arduino kann Dir davon auch Mehrere bespielen - mit unterschiedlichsten Informationen .

Damit wir Ausreißer wieder weg bekommen, könnte man Minimum/Maximum als Mittelwert erfassen - je nachdem, ob wir über/unter 50% sind.
Somit hätten wir auch direkt eine schöne 'weiche' Schwelle, ab Denen wir uns merken, daß wir 'oben' oder 'unten' waren.
Beim Nulldurchgang counter++; und den Merker 'oben' und 'unten' wieder löschen.
Jetzt müssen die Messwerte erst wieder über die weiche Schwelle drüber/drunter, damit wir den Merker wieder setzen.

Da uns so aber auch die Grenze verschwimmt (also auf den aktuellen Messwert angleicht), müssten wir noch nachsehen, ob sich am Messwert 'genug' geändert hat, um die Mittelwerte zu füttern.

Rein theoretisch, hatte was Ähnliches Mal für eine glaub Lichtschranke zusammen gepfuscht - zugegeben, mit mäßigem Erfolg (wenn Das auch das Einzige ist, woran ich mich sicher erinnere).

MfG

Also das was Dani vorgeschlagen hat,
war schon etwas besser, aber trotzdem noch sehr viel "geflacker". Ich vermute das wir das tatsächlich irgendwie über Analog machen müssen, da ich vermute das es genau um die schaltschwelle geht.

Diesen Code habe ich jetzt ausprobiert gehabt:

#include <LiquidCrystal.h>
LiquidCrystal lcd(22,23,24,25,26,27);

int relais = 13;
int sensor = 20;
int pulsschritte = 1;
int zaehlerstand = 0;
int counter = 0;
int state = 0;
int laststate =1;


void setup() {
  // put your setup code here, to run once:

pinMode(relais, OUTPUT);
pinMode(sensor, INPUT);
lcd.begin(16,2);

lcd.setCursor(0,0);
lcd.print("Wasserstand");
  lcd.setCursor (14,1);
  lcd.print("M3");
}

void loop(){
  
  lcd.setCursor(0,1);
  lcd.print (zaehlerstand);

  lcd.setCursor(8,1);
  lcd.print (counter);
  
 state = digitalRead (sensor);
 
 //Flankenwechsel erkennen
 if(laststate == LOW && state == HIGH) {
    //zähler erhöhen
    zaehlerstand++;
    counter = counter + pulsschritte;
    if (counter == 0 || counter == 5)
{
digitalWrite(relais,HIGH);
delay(200);
digitalWrite(relais,LOW);
pulsschritte = -pulsschritte;
}
 }
//letzten zustand merken 
 laststate = state; 

 
}

Das Delay war hier auch nur um zu schauen ob das Relais schaltet. Sollte der Rest drum herum so funktionieren wie gedacht, dann würde ich das auch ersetzen wollen :wink:

Morgen werde ich mal schauen ob ich es hinbekomme ober den Serial Print ein paar analog werte aufzu zeichnen.
Aus irgeneinem Grund scheint mein LCD oder Board einen Wackler auf der Verdrahtung zum LCD zu haben, oder wisst ihr ggf. warum das LCD Display mal normal funktioniert und mal entweder komische zeichen anzeigt oder eben nur die Hintergrundsbeleuchtung?

postmaster-ino:
Hi

Binär-Eingang - wenn's 'Spielstrom' ist, könnte dort auch ein schnöder Opto-Koppler reichen, Den der Arduino ansteuert.
Wenn Du mit den Binär-Eingängen auch 'Mehr' machen kannst - der Arduino kann Dir davon auch Mehrere bespielen - mit unterschiedlichsten Informationen .

´

Ja müsste ich mal schauen was ich ggf. noch mehr machen könnte.
Glaube der schaltstrom ist 3,3VDC und max. 10mA.
Bezüglich der Schwelle schaue ich morgen mal wenn ich es schaffe ein paar daten auszulesen und abzuspeichern, damit auch ein Anhaltspunkt da ist.

Hi

KEIN delay() ... So können wir uns den Kram auch schenken.

Wobei ich eigentlich denke, daß Dir LED oder ESL Flackern in die Suppe spuckt - wenn ein Oszi zur Hand wäre?
Alternativ den Kram völlig abdunkeln.

MfG

dennis15015:
...war schon etwas besser, aber trotzdem noch sehr viel "geflacker". ...

Deshalb meinte ich das mit dem Aufzeichnen.

Schließe den „Empfänger“ an einen analogen Eingang an und zeichne auf, was da ankommt, wenn der Zeiger läuft. Daraus kann man dann ableiten, wie „gelesen“ werden soll. Ungefähr das habe ich gemacht, als ich die „elektronische Achse“ für mein Fahr-herum-Gebastel gebastelt hab.
Was ich damals aufgezeichnet habe, kannst Du hier bewundern: kodierscheibentest.pdf

Das Bild dazu:

Gruß

Gregor

Hi Gregor,

also ich habe dem ganzen schon ein Gehäuse verpasst das ich quasi auf den Zähler drauf setze sodass kein Umgebungslicht dran kommt außer eben das von der LED.
Habe auch eben mal den Serial monitor angeworfen und ich denke das was man drauf sieht erklärt auch warum die werte nur so rein donnern es unterscheidet sich quasi kaum von einander.
Anbei habe ich eine Datei angehangen mit allen Werten die mir der Monitor ausgespuckt hat. Eig. Unterscheiden die sich kaum am Zähler. Habe es mal hier am tisch im Dunklen probiert da waren die abstände etwas größer.
Ich versuche morgen nochmal ob ich den sensor noch was justieren kann mithilfe des Serial Monitors. Ggf. ist wie du sagst die LED auf dem Sensor ein **eck Wert :wink:

Jetzt geht's für mich aber auch langsam ins Bett. Sobald ich morgen also wieder Zeit habe. Werde ich noch etwas weiter basteln.
Ich denke aber das man an sich mit den beigefügten Werten nicht wirklich was anfangen kann...

PDF hat etwas über 600 Seiten... :smiley:

Monitor Werte.pdf (1.5 MB)

dennis15015:
...
Ich denke aber das man an sich mit den beigefügten Werten nicht wirklich was anfangen kann...

Das stimmt. Die gemessenen Werte sind sich sehr ähnlich. Zum Spielen mit solchen Zeitreihen ist der serielle Plotter der IDE echt praktisch. Nimm mal den Sketch von meinem Akkulade-Beispiel und ändere die Zeit auf vielleicht eine Zehntelsekunde je loop()-Durchlauf - oder Fünfzigstel oder wie's halt passt.

Mache/poste auch mal einen Schaltplan oder ein brauchbares Foto vom Aufbau.

Gruß

Gregor

gregorss:
Das stimmt. Die gemessenen Werte sind sich sehr ähnlich. Zum Spielen mit solchen Zeitreihen ist der serielle Plotter der IDE echt praktisch. Nimm mal den Sketch von meinem Akkulade-Beispiel und ändere die Zeit auf vielleicht eine Zehntelsekunde je loop()-Durchlauf - oder Fünfzigstel oder wie's halt passt.

Mache/poste auch mal einen Schaltplan oder ein brauchbares Foto vom Aufbau.

Alles klar werde es nachher mal versuchen um zu basteln und heute Abend auch mal ein Foto nach zu reichen vom Test Aufbau.

Auf jedenfall Danke für die Tipps :slight_smile:

Lg
Dennis.