ESP8266 + KY-024 Hallsensor Modul (49E) an Gaszähler über Tasmota

Guten Morgen zusammen,

leider bin ich mit der Suche nicht wirklich fündig geworden.
Aber eventuell kann mir jemand hier weiter helfen.

Ich habe einen ESP8266 und ein KY-024 Hallsensor (49E Modul) von AZdelivery - mit dieser Konstellation möchte ich die Impulse von meinem Gaszähler messen.

Hierzu habe ich den ESP8266 mit Tasmota geflasht und den digitalen Ausgang vom Hallsensor über GPIO13 angeschlossen und als Counter in der Software eingestellt (hab das in irgend einer Anleitung so gesehen und daher übernommen).

Nun habe ich das Problem, dass diese Kombi nun zwar zählt, aber entweder zu wenig oder zu viel.

Ich habe hier auch mit den Debounce-Werten gespielt - bei CounterDebounce 100 zum Beispiel, zählt er viel zu viel. CounterDebounce 1000 ist es zu wenig usw.

Kann man die Feinjustierung ausschließlich über diese CounterDebounce-Werte machen oder gibt es eine bessere Variante als den Counter um die Daten ins Home Assistant zu bekommen?

Am Ende sind es ja immer nur einzelne Impulse die gezählt werden. Aktuell macht er da aber leider was er will.

Beim Gaszähler handelt es sich um einen Pietro Fiorentini G4.

Hat niemand eine Idee bzw. Anregung?

Über den digitalen Ausgang kann man das nicht zählen. Der Gaszähler bleibt stehen wo er stehen bleibt. Manchmal eben auch da, wo er im Ripple vom LM939 (Komparator) liegt. Beibt er im Kippbereich stehen, wird auch ein delay nicht helfen, da der Zähler ja Stunden in dieser Stellung verbleiben kann. Und dann zählt er in jedem Schleifenumlauf einen Impuls weiter oder auch mal nicht.

Die einzige Möglichkeit das sauber zu zählen, bin hier langsam in der finalen Testphase, den Analogwert abzufragen. Da dieser aber genauso flackert muss man die Näherungsflanke sowie die Magnetverlassenflanke überwachen und dann auf der Verlassenflanke zählen, da der Zähler ja für Stunden auf dem Magnet stehen bleiben kann.

## Funktionsweise

| Zustand | Aktion |
|----|----|
| A0 < 490 | Magnet erkannt (fallende Flanke möglich) |
| A0 > 520 | Magnet weg (steigende Flanke → **Zählung!**) |
| 490–520 | keine Änderung, Rauschunterdrückung aktiv |
| Bei Start | aktueller Zustand (Magnet da oder nicht) wird erkannt |  |  |  |  |

Diese Werte habe ich bei einem Arduino Nano mit 5V Versorgung des KY024. Wenn man den mit 3,3V über den ESP8266 versorgt, dann sind die Werte kleiner, müssen angepasst ermittelt werden.

Das Programm für den Arduino Nano mit MiniDisplay sieht folgendermaßen aus:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define SENSOR_DO 2
#define SENSOR_AO A0

unsigned long impulseCount = 0;
float faktor = 0.1; // 1 Impuls = 0,1 m³

int analogValue = 0;
int minVal = 1023;
int maxVal = 0;
int d0State = 0;

// — Hysterese-Parameter —
const int BASELINE = 505;       // typischer Mittelwert ohne Magnet
const int DELTA = 15;           // Rauschbereich / Totzone
const int LOW_THRESHOLD = BASELINE - DELTA;   // z. B. 490
const int HIGH_THRESHOLD = BASELINE + DELTA;  // z. B. 520

bool magnetDetected = false;    // Zustand: Magnet aktuell erkannt
bool lastMagnetDetected = false; // Zustand im letzten Durchlauf

#define GRAPH_WIDTH 128
#define GRAPH_HEIGHT 12
int graphData\[GRAPH_WIDTH\];
int graphIndex = 0;

void setup() {
pinMode(SENSOR_DO, INPUT);
pinMode(SENSOR_AO, INPUT);
Serial.begin(9600);

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F(“Displayfehler!”));
for(;;);
}

impulseCount = 0;

// — Initialzustand erfassen —
int startValue = analogRead(SENSOR_AO);
if (startValue < LOW_THRESHOLD) {
magnetDetected = true;
} else {
magnetDetected = false;
}
lastMagnetDetected = magnetDetected;

display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(“Gaszaehler Init…”);
display.display();
delay(1000);
}

void loop() {
analogValue = analogRead(SENSOR_AO);
d0State = digitalRead(SENSOR_DO);

// Min/Max verfolgen
if (analogValue < minVal) minVal = analogValue;
if (analogValue > maxVal) maxVal = analogValue;

// — Hysterese mit Rauschunterdrückung —
if (analogValue < LOW_THRESHOLD) {
magnetDetected = true;
}
else if (analogValue > HIGH_THRESHOLD) {
magnetDetected = false;
}
// Zwischenbereich: Zustand bleibt unverändert

// — Flankenerkennung —
if (lastMagnetDetected == false && magnetDetected == true) {
// Magnet kommt (fallende Flanke)
Serial.println(“FALLENDE Flanke erkannt”);
}
else if (lastMagnetDetected == true && magnetDetected == false) {
// Magnet verlässt Sensor (steigende Flanke)
impulseCount++;
Serial.print("Impuls erkannt! Gesamt: ");
Serial.println(impulseCount);
}

lastMagnetDetected = magnetDetected;

// Graph-Daten
graphData\[graphIndex\] = analogValue;
graphIndex = (graphIndex + 1) % GRAPH_WIDTH;

float volumen_m3 = impulseCount \* faktor;

// — Anzeige —
display.clearDisplay();
display.setTextSize(1);

display.setCursor(0, 0);
display.print(“Imp:”);
display.print(impulseCount);
display.print("  ");
display.print(volumen_m3, 1);
display.print(“m3”);

display.setCursor(0, 10);
display.print(“A0:”);
display.print(analogValue);
display.print(" Min:“);
display.print(minVal);
display.print(” Max:");
display.print(maxVal);

display.setCursor(0, 20);
display.print(“D0:”);
display.print(d0State == HIGH ? “HIGH” : “LOW “);
display.print(” M:”);
display.print(magnetDetected ? “Y” : “N”);

// Graph zeichnen
for (int x = 0; x < GRAPH_WIDTH; x++) {
int idx = (graphIndex + x) % GRAPH_WIDTH;
int y = map(graphData\[idx\], 0, 1023, SCREEN_HEIGHT - 1, SCREEN_HEIGHT - GRAPH_HEIGHT);
display.drawPixel(x, y, SSD1306_WHITE);
}

display.display();

delay(100);
}

---

\- - - Ende Arduino Code - - - 

Für den ESP8266 ist es für die Testphase ist es hilfreich einen Webserver zu installlieren, und die Min und Maxwerte auf der Webseite auszugeben und dann die Triggerwerte entsprechend anzupassen.

:crayon:by HarryP: Code-/Logzeilen formatiert (bitte immer in </> einbinden)
s.a.: (Neues Update & Features - Hier in der Community 🫶)

Hi, danke für die Rückmeldung - zwischenzeitlich bin ich vom ESP8266 weg und habe eine ESPCam mit AI on the Edge laufen, welche ausgezeichnet funktioniert. Hatte nur hier nicht mehr an den Thread gedacht :face_with_peeking_eye:

Jetzt habe ich es ausreichend mit dem Arduino getestet über längere Zeit und er zählt jetzt richtig.

Jetzt werde ich es umsetzten mit dem ESP8266. Hier lasse ich mir die Daten erst mal auf der Webseite ausgeben. Dann habe ich noch ein Editfenster wo ich den aktuellen Stand des Zählers eingeben kann, der dann durch die Impulse aufgezählt wird.

Ein Kameraprojekt hatte ChatGPT mir als alternative vorgeschlagen. Habe ich aber nicht weiter verfolgt.

Wäre nett wenn du mir mal genauer mitteilst was für eine Kamera du verwendest und wie du die Daten erfasst. Arbeitet die KI lokal oder mit Auswertung über Internet?

Ich weiß nicht ob ich hier verlinken kann:

Es ist eine DIY More ESP 32 Cam.

Ausgewertet wird mit GitHub - jomjol/AI-on-the-edge-device: Easy to use device for connecting "old" measuring units (water, power, gas, ...) to the digital world

Läuft lokal und meldet via MQTT an Home Assistant