Strom- und Wasserzähler mit IR Sensor aufbauen

Hi Gregor,

habe jetzt grade mal in meiner Pause nochmal über die diversen antworten geschaut und mir auch deine Batterieladeüberwachung angesehen.

Habe den Code mal kopiert und das delay auf (100) gesetzt. Muss ich die Zeitangabe bei Millis auch abändern? Wenn ich es richtig verstanden habe dient diese Zeile

Serial.print  (millis()/1000);

dazu nur jede Sekunde im Monitor anzuzeigen, oder?

Lg
Dennis

dennis15015:
... Wenn ich es richtig verstanden habe dient diese Zeile

Serial.print  (millis()/1000);

dazu nur jede Sekunde im Monitor anzuzeigen, oder?

Die Funktion millis() gibt ja die Dauer zurück, die der Arduino eingeschaltet ist (in Millisekunden). Mit dieser Ausgabe erscheint im seriellen Monitor halt nicht die genaue Zahl, z. B. 12465, sondern nur die 12. Die 465 fallen unter den Tisch. Ich wollte halt einen „Zeitstempel“ in der Ausgabe, weil ich zum Mitschreiben ein Terminalprogramm verwende, das keine Option „Zeitstempel zeigen“ hat.

Ich hoffe, dass das noch so stimmt. Mein Geschreibsel mit der Ladekurve ist mittlerweile ja ziemlich alt.

Gruß

Gregor

PS: Kontrolliere am besten auch noch einmal die Verdrahtung. Die Werte, die Du gepostet hast, sind ja nicht so dolle. Wackle auch mal an allen Verbindungen. Kontaktprobleme sind so ziemlich das Übelste, was einem bei so einer Bastelei unterkommen kann.

gregorss:
PS: Kontrolliere am besten auch noch einmal die Verdrahtung. Die Werte, die Du gepostet hast, sind ja nicht so dolle. Wackle auch mal an allen Verbindungen. Kontaktprobleme sind so ziemlich das Übelste, was einem bei so einer Bastelei unterkommen kann.

So sah habe ich gerade gemacht. Scheint das Display zumindest schonmal wieder zu funktionieren.

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

Anbei sind auch 2 Fotos vom Test aufbau auf dem Tisch.

Hallo zusammen,

ich habe jetzt mal den Aufbau nochmal auf dem Zähler gesetzt und auch den Plotter mit laufen lassen.
Einen Screenshot vom Plotter is als Foto beigefügt.
So wie es aussieht kann man auch diese "ungenauen" Schaltzustände erkennen mit diesem Zittern beim an bzw. Absteigen des Rechteck Signals.

Versuche das nachher nochmal in so eine Plotter Grafik zu bekommen falls noch benötigt?

Was meint ihr denn zu der Grafik die ich beigefügt habe. Ist das Problem zu erkennen bzw wie man es in den Griff bekommen könnte?

lg
Dennis.

Das sieht ja ziemlich ordentlich aus. Ganz anders als die Werte, die Du zuletzt bekommen hast. Da hätte ich mir das folgende Geschreibsel eigentlich sparen können. Aber weil ich es getippt habe, musst Du es jetzt lesen:

dennis15015:
Anbei sind auch 2 Fotos vom Test aufbau auf dem Tisch.

Was ist denn das gelbe Licht am „Zähler-Adapter“? Und wo genau wird das reflektierte Licht erfasst? Kannst Du mit dem Trimmer auf dem Lese-Dingsda-Platinchen etwas Wichtiges verstellen? Was passiert, wenn Du die Erfassung testest, indem Du den Finger vor dem Sensor bewegst?

Nuja, Fragen über Fragen :slight_smile: Immerhin läuft das Display und Du hast Kontaktprobleme kennengelernt. Eigentlich könnte jetzt das WE anfangen.

Gruß

Gregor

----------------------------------weiter im Text ...

Das mit den kleinen Spitzen bekommst Du in den Griff, indem Du beim Lesen eine Hysterese berücksichtigst. D.h. ein low-high-Wechsel wird nur ausgewertet, wenn ein höherer Wert überschritten wird als bei einem high-low-Wechsel. Bei solch sauber trennbaren Leveln kann die Hysterese ziemlich groß sein.

Nochn Gruß

Gregor

Ich war mir nicht sicher ob du das mit dem Plotter schon vorhergeschrieben hattest.
Wusste nicht einmal das es sowas kann Schäm

gregorss:
Was ist denn das gelbe Licht am „Zähler-Adapter“? Und wo genau wird das reflektierte Licht erfasst? Kannst Du mit dem Trimmer auf dem Lese-Dingsda-Platinchen etwas Wichtiges verstellen? Was passiert, wenn Du die Erfassung testest, indem Du den Finger vor dem Sensor bewegst?

Also auf dem Bild sieht man das neben der gelben led auch die Foto Diode ist, die das Licht detektiert.
Den Trimmer kann man verstellen, den habe ich aber schon soweit einestellt das er auf der Schwelle ist wo das Licht noch erkannt wird. Wenn ich ihn hier am Tisch im Dunkeln teste dann flackern die Werte nicht so extrem aber dennochs chon wenn man mit dem finger sehr langsam vorbei fährt.
Sobald ich die Platte auf den Zähler setze wird das licht ja direkt von unten reflektiert (Weiße Oberfläche). Sprich dann arbeitet der Sensor andersherum. Er empfängt Licht und unterbricht das Signal sobald der Zeiger vorbei fährt... Zumindest sollte er das dann tun :smiley:

gregorss:
Nuja, Fragen über Fragen :slight_smile: Immerhin läuft das Display und Du hast Kontaktprobleme kennengelernt. Eigentlich könnte jetzt das WE anfangen.

Zum Display habe ich aber manchmal nachdem neu Hochladen des sketches komische Zeichen im Display. Anbei ein Foto was ich meine. Eine Idee woher das kommt, oder was das sein kann?

gregorss:
Das mit den kleinen Spitzen bekommst Du in den Griff, indem Du beim Lesen eine Hysterese berücksichtigst. D.h. ein low-high-Wechsel wird nur ausgewertet, wenn ein höherer Wert überschritten wird als bei einem high-low-Wechsel. Bei solch sauber trennbaren Leveln kann die Hysterese ziemlich groß sein.

Alles klar dannn habe ich ja wieder etwas Lesestoff :slight_smile:

Danke Dir für den Link.

Lg
Dennis.

dennis15015:
[Serieller Plotter] Wusste nicht einmal das es sowas kann Schäm

Ja, so isses. Erfahrungen machen einen älter, ätsch.

dennis15015:
Zum Display habe ich aber manchmal nachdem neu Hochladen des sketches komische Zeichen im Display. Anbei ein Foto was ich meine. Eine Idee woher das kommt, oder was das sein kann?

So etwas bekomme ich in meinem Display nie zu sehen, weil ich die Hintergrundbeleuchtung erst nach der Initialisierung mit ...begin() einschalte. Wenn es immer erscheint, wenn es auch nur an die Betriebsspannung angelegt wird, ist das Müll vom Display-Controller. Solange es funktioniert und du drumherum-arbeiten kannst, musst Du Dir wohl keine Sorgen machen.

Gruß

Gregor

Nabend zusammen,

vorab schonmal vielen Dank für alle zahlreichen Tipps die ich von jedem bekommen habe.
Ich habe einige Tipps kombinieren können und was soll ich sagen.
Der Sensor läuft jetzt soweit ich es kurz testen konnte GUT. Sowohl bei schneller als langsamer Wasserentnahme.

@Gregor:

gregorss:
JSo etwas bekomme ich in meinem Display nie zu sehen, weil ich die Hintergrundbeleuchtung erst nach der Initialisierung mit ...begin() einschalte. Wenn es immer erscheint, wenn es auch nur an die Betriebsspannung angelegt wird, ist das Müll vom Display-Controller. Solange es funktioniert und du drumherum-arbeiten kannst, musst Du Dir wohl keine Sorgen machen.

Ok alles klar. Das blöde ist nur das ich jedesmal nach stromzufuhr dann den reset Knop drücken muss damit die Werte wieder weg sind.

Hier ist auch nochmal der Code für das jetzt schonmal funktionierende Zählerchen. Ich habe mir noch die Mühe gemacht step für step ein paar Erklärungen dabei zu schreiben, falls jemand irgendwann mal auch nach so etwas suchen sollte :slight_smile:

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

int relais = 13;
int sensor_state = LOW;
int sensor = 0;
int pulsschritte = 1;
int zaehlerstand = 0;
int counter = 0;
int state = LOW;
int laststate = HIGH;
unsigned long relais_time;
int relais_state = LOW;
int hysterese = 100;


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

pinMode(relais, OUTPUT); //Es wird angegeben das relais ein Output ist.
pinMode(sensor, INPUT);  // Es wird angegeben das sensor ein Input ist.
lcd.begin(16,2); // LCD wird gestartet.

lcd.setCursor(0,0);      //Cursor wird an 1. Stelle in der 1. Zeile gesetzt.
lcd.print("Wasserstand"); // Wasserstand wird ins Display geschrieben.
  lcd.setCursor (14,1);   //Cursor wird an 15. Stelle in der 2. Zeile gesetzt.
  lcd.print("M3");        //M3 wird in das Display geschrieben.
}

void loop(){
  
  lcd.setCursor(0,1);   //Cursor wird an 1. Stelle in der 2. Zeile gesetzt.
  lcd.print (zaehlerstand); // Der Wert aus Variable "zaehlerstand" wird in das Display geschrieben.

  lcd.setCursor(8,1);  //Cursor wird an 9. Stelle in der 2. Zeile gesetzt.
  lcd.print (counter);  // Der Wert aus Variable "Counter" wird in das Display geschrieben.

if(analogRead(sensor) > 800 + hysterese) // Wert des (Licht)sensors wird Analog eingelesen und verglichen ob dieser größer ist als der Hysteresen Schwellwert Einschalten.
    {
      sensor_state = HIGH; // Wenn der (Licht) sensor Wert größer als der Hysteresen Schwellwert ist, dann wird die Variable "sensor_state" auf HIGH gesetzt.
    }
else if(analogRead(sensor) < 200 - hysterese) // Ist der Wert nicht größer als der Wert für den hysteresen einschaltschwellwert, 
                                              // wird verglichen ob dieser Wert kleiner ist als der Hysteresen Auschhalt Schwellwert.

    {

     sensor_state = LOW;  // Ist der sensor Wert kleiner als der Hysteresen Ausschaltschwellwert, so wird die Variable "sensor_state" auf LOW gesetzt. 
      
    }
  
 state = sensor_state; // Der Wert der Variable "sensor_state" wird in die Variable "state" übernommen.
 
 //Flankenwechsel erkennen
 
 if(laststate == LOW && state == HIGH) // Hier wird der Flankenwechsel ausgewertet. Wenn die Variable "laststate" = LOW ist & die Variable "state" = HIGH, dann 
 
 { 
    zaehlerstand++;  //Zähler erhöhen &
    counter = counter + pulsschritte; // die variable "counter" übernimmt den Wert aus der Variable "counter" + "pulssschritte" &
    if (counter == 0 || counter == 5) // Hier wird gechecked ob die variable "counter" = 0 oder 5 ist.
{
relais_time = millis();  //Ist die Bedingung wahr, so schreibe die aktuelle vergangene Zeit seit Systemstart (in Millisekunden) in die Variable "relais_time" &
digitalWrite(relais,HIGH); // setze das Ausgangs Relais auf HIGH &
relais_state = HIGH; // setze die Variable "relais_state" auf HIGH %
pulsschritte = -pulsschritte; // übernehme in die Variable "pulsschritte" den Wert -"pulsschritte" (Dies sorgt dafür das der Counter addiert bzw. subtrahiert wird)

}
 }
if (relais_state == HIGH) // Wenn die Variable "relais_state" = HIGH ist, dann:
{if (millis()-relais_time > 500) // Wenn die aktuelle vergangene Zeit seit Systemstart (in Millisekunden) - der angegebenen Zeit in der Variable "relais_time" 
                                 // größer als 500 Millisekunden ist, dann:

{ digitalWrite(relais, LOW); // Setze das Ausgangs relais auf LOW &
relais_state = LOW;  // Setze die Variable "relais_state" auf LOW

}
}

 
//letzten zustand merken 
 laststate = state;  // übernehme den Wert aus der Variable "state" in die Variable "laststate".
 

}

Wie schon erwähnt führte hier zur Lösung das delay zu ersetzen durch Millis, den Flankenwechsel zu erkennen und auch zuletzt noch die Hysterese einzubauen um werte Schwankungen auszugleichen.
Ich vermute der eine oder andere bekommt diesen Code auch noch besser/kürzer hin.
Für mich auf jedenfall ist er so schon sehr gut und bin froh das ihr mir hier geholfen habt, bei meinem Ersten Projekt :slight_smile:

Da es aber noch weiter geht, wollte ich Fragen wie sieht es aus mit Werte speichern? Habe schon gelesen das EEprom unvorteilhaft ist, da er nicht so oft beschrieben werden kann.
Wäre SD Karte eine alternative von der Geschwindigkeit her?
Ich würde nämlich gerne alle 10 L oder so den Wert abspeichern und bei jeder kWh für eventuelle Strom ausfälle. Für das vorhaben über KNX ist das an sich nicht so wichtig, aber da ich ja nu auch schon ein LCD habe würde ich auch die Werte gerne dort anzeigen lassen.

Für den Stromzähler, kann ich hier den Code übernehmen (abändern der Variablen) und einfach unter den anderen setzen, bzw darüber? Da die Stromimpulse eig. kontinuierlich gezählt werden müssen.

Langer Text Fragen über Fragen :slight_smile: Entschuldigt das der so kang geworden ist und sich evtl. zieht zum lesen :wink:

Lg
Dennis.

Nur schnell hierzu:

dennis15015:
... Habe schon gelesen das EEprom unvorteilhaft ist, da er nicht so oft beschrieben werden kann.

Das EEPROM ist lt. Hersteller für 100.000 Schreibzyklen spezifiziert. Bei einem Schreibvorgang pro Stunde reicht das für > 10 Jahre.

Gruß

Gregor

gregorss:
Nur schnell hierzu:

Das EEPROM ist lt. Hersteller für 100.000 Schreibzyklen spezifiziert. Bei einem Schreibvorgang pro Stunde reicht das für > 10 Jahre.

Gruß

Gregor

Danke für die Zügige Rückmeldung. Alles Klar. Ich mache mich diesbezüglich nochmal schlau.
Ich würde schon gerne grade bei den Stromwerten je kWh speichern und dann auch automatisch bei einem Neustart (bsp. Stromausfall oder aus anderem Grund) wieder Automatisch aufrufen. Beim Wasserzähler wird eh nach m³ abgelesen. da wäre es mir relativ egal wenn da mal der eine oder andere (10/100) Liter nicht gezählt wird durch einen Stromausfall.

Ich weiß ja nicht, wie oft bei Dir der Strom ausfällt. Hier Freiburg-Stadt in den letzten zwei Jahren kein einziges Mal.

Solche Ablesereien mache ich übrigens nur zu Fuß (ganz wörtlich zum Stromablesen 2 Geschosse in den Keller) und „logge“ das per Textdatei. Meinen Wasserverbrauch überwache ich nicht. Da ich letztes Jahr gut 600 € NK-Rückzahlung bekommen habe, kann ich aber nicht so verschwenderisch sein. Wenn bei Dir ab und zu der Strom ausfällt und das nur für kurze Zeit, dann genügt vielleicht einfach ein großer Elko in der Stromversorgung. Sehr kurze Stromausfälle hatte ich zuletzt vor knapp 10 Jahren, als ich noch außerhalb FRs gewohnt habe.

Logge einfach nicht stündlich, sondern nur alle zwei Stunden ins EEPROM. Das verdoppelt die Lebensdauer :-)))

Gruß

Gregor

Ansonsten könnte man auch über einen FRAM nachdenken.

Gruß Tommy

gregorss:
Ich weiß ja nicht, wie oft bei Dir der Strom ausfällt. Hier Freiburg-Stadt in den letzten zwei Jahren kein einziges Mal.

Solche Ablesereien mache ich übrigens nur zu Fuß (ganz wörtlich zum Stromablesen 2 Geschosse in den Keller) und „logge“ das per Textdatei. Meinen Wasserverbrauch überwache ich nicht. Da ich letztes Jahr gut 600 € NK-Rückzahlung bekommen habe, kann ich aber nicht so verschwenderisch sein. Wenn bei Dir ab und zu der Strom ausfällt und das nur für kurze Zeit, dann genügt vielleicht einfach ein großer Elko in der Stromversorgung. Sehr kurze Stromausfälle hatte ich zuletzt vor knapp 10 Jahren, als ich noch außerhalb FRs gewohnt habe.

An sich fällt der Strom nicht so oft aus. Da ich aber noch dabei bin den Keller zu renovieren und die Garage, komme ich nicht drum herum in nah gelegener Zeit des Öfteren den Strom abzuschalten :wink:
Natürlich hast du recht. Um meinen STrom-/Wasser verbrauch zu berechnen (monatlicher) Verbrauch gehe ich auch immer in den Keller und lese die Werte ab. Auch für den Gas verbrauch. Das würde ich halt gerne einfach sichgestellt loggen, damit ich dafür eben nicht immer in den Keller muss, sondern einfach auf meine Visu später schauen kann und direkt sehe wie der verbrauch ist bzw war. :slight_smile:

Zur jährlichen Ablesung laufe ich dann eh in den Keller. Ich bin mir auch noch nicht sicher ob ich ggf. später noch nen nano extra in den Stromkasten hänge der mir die werte des Stromzählers über Funk übermittelt zum Haupt Arduino board welches am Wasserzähler ist und den Gaszähler auch direkt dort anschließe oder ob cih alles draht gebunden an einen Arduino packe, dann muss ich mal schauen wie gut das Signal über ein paar meter kommt :wink:

Tommy56:
Ansonsten könnte man auch über einen FRAM nachdenken.
Gruß Tommy

Hi Tommy,

ja hatte ich eben auch schon irgendwo gelesen und wühle mich durch das Forum und Google um ein paar info's diesbezüglich zu bekommen :slight_smile:
Der hat aufjedenfall genug speicherzyclen :smiley:

Lg
Dennis.

Schau mal hier bis zum Ende.

Gruß Tommy

dennis15015:
An sich fällt der Strom nicht so oft aus. Da ich aber noch dabei bin den Keller zu renovieren und die Garage, komme ich nicht drum herum in nah gelegener Zeit des Öfteren den Strom abzuschalten :wink:

Lösung: Mach Keller und Garage zuerst fertig.

Macht halt vermutlich nicht so viel Spaß wie das Basteln mit Arduino.

Das Leben ist gemein und das ganze Universum sowieso kaputt.

Gruß

Gregor

Tommy56:
Schau mal hier bis zum Ende.

Gruß Tommy

Den beitrag hatte ich auch schon gefunden und gelesen. Aber beim ersten drüber lesen nicht so ganz verstanden. Schaue morgen nochmal genauer ggf. werde ich dann etwas schlauer draus.

gregorss:
Lösung: Mach Keller und Garage zuerst fertig.

Macht halt vermutlich nicht so viel Spaß wie das Basteln mit Arduino.

Das Leben ist gemein und das ganze Universum sowieso kaputt.

ja da hast du Recht :smiley: ist ja auch alles eine Kosten Frage :wink:
An sich bin ich ja wie gesagt schon zufrieden, dass der Zähler funktioniert habe auch eben mal das IR board für den stromzähler dran gehangen und der war jetzt auch deutlich präziser ohne Störungen.

Also ich denke das mir so schon sehr gut weitergeholfen ist so. Alles jetzt nur noch kombinieren und weiter experimentieren, denn das ist das was ja Spaß macht und fit hällt :wink:

Euch noch eine gute Nacht =)

Lg
Dennis.

Hi Tommy,

ich habe deinen Beitrag jetzt nochmal genau gelsen.

Tommy56:
Schau mal hier bis zum Ende.

Gruß Tommy

Jedoch verstehe ich nicht so 100_% wie ich letzendlich die Werte in einen Fram schreibe. Zeitgleich habe ich mich auch nochmal mit dem EEprom beschäftigt und gelesen.

Folgendes habe ichzum eeprom heruasgefunden:

Eeprom hat 0-255 Speicherstellen (Addressen) die beschrieben/ausgelesen werden können.
Um meinen Wert "zaehlerstand" in den EEprom zu schreiben gibt es 2 Möglichkeiten

float zaehlerstand  = 1500

float alter_zaehlerstand = 0



EEPROM.put(0,zaehlerstand); //aktueller zaehlerstand wird auf Addresse 0 in den EEprom geschrieben oder mit

EEPROM[ 0 ] = zaehlerstand 


zum auslesen kann man dann verwenden: 

EEPROM.get(0,alter_zaehlerstand); // Der Wert der im EEprom unter Addresse 0 gespeichert ist wird ausgelsen und in der variable "alter_zaehlerstand" übernommen oder mit
zaehlerstand = EEPROM [0];

Habe ich das so richtig verstanden?
Wie sieht es denn aus bei einem FRAM?
Ist das in etwa dort genauso "Easy"?

Aus deinem Beitrag konnte ich entnehmen das man wenn ein I²C Fram benötigt wird, zusätzlich diese Addresse noch angegeben werden muss.

Aber am sonsten habe ich nicht ganz durch deinen Code hindurch geblickt, ob das nun der code der lib gewesen ist doer schon der normale Sketch code für die Funktion.

Kannst du mir da ggf. ein wenig auf die Sprünge helfen :slight_smile:

Lg
Dennis.

Wenn Du konkrete Fragen hast, ja.

Gruß Tommy

Tommy56:
Wenn Du konkrete Fragen hast, ja.

Gruß Tommy

Alles klar. Wenn ich nachher zuHause bin schaue ich nochmal.
Hatte cih das denn bzgl. EEprom richtig verstanden?

Lg
Dennis

Float ist auf AVR 4 Bytes groß. Es wäre damit besser zu formulieren:
Ab Adresse 0 (bis 3) steht die Variable.

Gruß Tommy