Ich habe von Herrn Jürgen Horter (www.Horter-Shop.de) das neue I2C Impuls Counter Modul zum Testen erhalten. Die zwei PCF8583 Bausteine können Impulse zählen und die Werte über den I2C Bus bereitstellen. Somit ist es ohne Probleme möglich, Durchflussmesser mit mehreren hundert Impulsen pro Minute oder einen Stromzähler mit S0-Schnittstelle auszuwerten.
An das I2C Impuls Counter Modul kann direkt ein Sensor mit 5V Betriebsspannung angeschlossen und ausgewertet werden. Ich habe mit einem YF-S201 Durchflussmesser und dem TLE 4905L Hallsensor getestet.
Um Impulse mit einer Spannung von 12V oder 24V über das Modul zu zählen, ist für jeden Eingang ein Optokoppler verbaut. Dieser kann wie die Pull-Up Widerstände über einen Jumper aktiviert werden. Es wird je nach Spannung noch ein Widerstand auf der Platine benötigt, dieser wird aber mitgeliefert.
Anschlussplan – 5V Durchflussmesser mit Hall- Sensor
Anschlussplan – Stromzähler mit S0 Ausgang und 24V Spannung
Wichtig! Taster oder andere “prellende” Sensoren sind nicht für die Zählung geeignet oder müssen entsprechend entprellt werden. Bei einem einfachen Taster können sonst schnell zweistellige Werte pro Tastendruck entstehen.
Sketch
Ich habe ein Beispiel vorbereitet, das den ersten PCF8583 Baustein in den Modus Impulszähler versetzt und dann kontinuierlich alle 60 Sekunden ausliest. Es werden die Summe der Impulse inkl. der Umrechnung in Liter und der Durchschnitt pro Sekunde ausgegeben. So sieht die Ausgabe im Serial Monitor aus.
Ich werde bei Gelegenheit oder wenn die Nachfrage besteht, auch noch das I2C WLAN Gateway Projekt entsprechend erweitern.
Für den Sketch wird aktuell noch die PCF8583 Library (Bitbucket Repository) von Xose Pérez benötigt.
#include "PCF8583.h"
PCF8583 sensor1(0xA0); // YF-S201 Water flow hall sensor
// PCF8583 sensor2(0xA2);
unsigned long previousMillis = 0;
long interval = 60000;
void setup() {
// configure serial link to debug
Serial.begin(9600);
// configure PCF8583 to event counter mode and reset counts
sensor1.setMode(MODE_EVENT_COUNTER);
sensor1.setCount(0);
}
void loop() {
unsigned long currentMillis = millis();
// report the events every second
// Serial.println(counter.getCount());
if (currentMillis - previousMillis > interval)
{
previousMillis = millis();
float count = sensor1.getCount();
sensor1.setCount(0);
Serial.print("SUM: ");
Serial.print(count ,0);
Serial.print(" = ");
Serial.print((count / 450) ,1);
Serial.println(" liter");
Serial.print("AVG: ");
Serial.print((count / 60), 1);
Serial.println(" impulse per second");
}
}
ToDo
Leider funktioniert der Interrupt noch nicht. Dieser fehlt leider in der Library und mir fehlen noch die richtigen Werte, die gesendet werden müssen, damit der Interrupt nach x Impulsen aktiviert wird. Vielleicht hat jemand noch eine Idee?
Hallo,
ich habe soetwas ähnliches gemacht.
Ich bin ohne die 12V ausgekommen.
Aber nicht ohne Interrupt. Die nötige Entprellung des S0 (brummen) habe ich durch Ignoranz von Pulsen < 200 ms in der Interruptroutine realisiert.
Der Code ist für esp8266/esp32.
So geht es gleich mit Wep-Interface, Mqtt, … weiter.
Im moment brüte ich auf einem KNX-Gateway.
Hier der Code und einen schönen Tag aus Toppenstedt.
(Fragen zu HW Layout etc. unter meiner e-mail)
#include "user_interface.h"
#include "SSD1306Wire.h" // legacy: #include "SSD1306.h"
#define SDA 5 //I2C Bus
#define SCL 4 //I2C Bus
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL – SDA and SCL
#include
#include
#include
unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
// All for Output
int LED_intern = 2;int TH1 = 14;int TH2 = 12;
// All for Input
int Left = 15;int Mid = 2;int Right = 0;int Key_val =0;
// All for Temperature ntc to gnd and resistor to vcc
float V_cc;float ADCvalue;float U_Th;float I_Rv;float R_Th;float Tempetature;
#define V_cc 3.300
#define Rv 100000
#define NOMINAL_RESISTANCE 10000
#define NOMINAL_TEMPERATURE 25
#define BCOEFFICIENT 3950
// All for Oilcount
//int eeAddress = 16;unsigned int t = 0;float pulse_vol = 0.005 ;float liter = 0.000 ;unsigned long oldmillis = millis();unsigned long pulsetime;
//float hour = 3600000;float liter_hour = 0;float kwh_liter = 10.84;
// All for Powermeter
int eeAddress = 16;
unsigned int t = 0;
float kwh_per_pulse = 0.0025 ; // 400 pulses per kwh
float kwh = 0.000 ;
float kw = 0.000 ;
unsigned long oldmillis = millis();
unsigned long pulsetime;
float h = 3600000;
//******************************************************************************
void setup() {
WiFi.forceSleepBegin();
Serial.begin(74880);
display.init();
Serial.println(“Turning WiFi Off”);
pinMode(LED_intern, OUTPUT);
digitalWrite(LED_intern, LOW);
delay(1000);
digitalWrite(LED_intern, HIGH);
pinMode(TH1,OUTPUT);
pinMode(TH2,OUTPUT);
pinMode(Left,INPUT);
pinMode(Mid,INPUT);
pinMode(Right,INPUT);
pinMode(13,INPUT);
EEPROM.begin(512);
EEPROM.get( eeAddress, kwh);
//Level-triggered (CHANGE) or Edge-triggered (RISING, FALLING interrupt)
attachInterrupt(digitalPinToInterrupt(13), handleInterrupt, RISING);
//*******************************************************************************
}
void loop() {
get_Key_val();
get_Temerature();
put_Oled();
put_eeprom();
delay (100);
//*******************************************************************************
}
void test_output(){
delay(10);
digitalWrite(TH1, HIGH);
delay(10);
digitalWrite(TH1, LOW);
delay(10);
digitalWrite(TH2, HIGH);
delay(10);
digitalWrite(TH2, LOW);
delay(10);
}
void get_Key_val(){
Key_val = 0;
if (digitalRead(Left)==HIGH)
{Key_val += 1;}
if (digitalRead(Mid)==LOW)
{Key_val += 2;}
if (digitalRead(Right)==LOW)
{Key_val += 4;}
if (Key_val > 0) {
print_serial(); }
//******************************************************************************
}
void get_Temerature(){
ADCvalue = 0;
for(int i = 0; i = 36000) {
EEPROM.put(eeAddress, kwh);
EEPROM.commit();
t = 0;
print_serial();}
}
void print_serial() {
Serial.print(“SUMME: =”);Serial.print(kwh); Serial.print(” KW/h “);
Serial.print(“POWER: =”);Serial.print(kw); Serial.print(” KW “);
Serial.print(“Keyval =”);Serial.println(Key_val);
//*******************************************************************************
}
ICACHE_RAM_ATTR void handleInterrupt(){
pulsetime = millis() – oldmillis;
oldmillis = millis();
if (pulsetime >= 200) {
kw = h/ pulsetime * kwh_per_pulse;
kwh = kwh + kwh_per_pulse;
print_serial(); }
//******************************************************************************
}
Hi,
wie viele Impulse können insgesamt gezählt werden bzw. wie groß ist das Register?
Bleiben die gezählten Impulse auch nach Spannungsausfall erhalten (z.B. Batteriewechsel)?
Hallo Malkem,
das I2C Impuls Counter Modul puffert nur die Impulse, diese sollten aber regelmäßig ausgelesen und z. B. über ein I2C WLAN Modul mit Wemos D1 mini gespeichert werden.
Viele Grüße
Stefan