Bier-Durchflusszähler

Nachdem mir #noiasca den entscheidenden Tipp gab, das Problem I2C und Button zu lösen, darf ich euch hier am positiven Ergebnis teilhaben lassen.
Geändert hat sich das checken und filtern von Fehlimpulsen dei in den Durchflusszähler durch Lichtschalter oder Bierkühler eingespeist werden
Vielleicht kann jemand mit meinem Durchflusszähler etwas anfangen.

Durchflusszähler von Biotech Art-Nr.: 126063 Typ1
Arduino Uno
SunFounder IIC I2C TWI 1602 Serial LCD Module bei Amazon

Leider habe ich die meisten Kommentare entfernen müssen, damit ich den Code hochladen konnte.

enjoy it :slight_smile:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <math.h>
#include <OneButton.h>

const int tasterPin = 4;   
const uint8_t heartbeatPin = 13;

LiquidCrystal_I2C lcd(0x27, 16, 2);

OneButton Taster1 = OneButton(tasterPin, true);
int DEBUG = 0;
volatile long impulse, impulse_vorher, zapfimpulse;          //messen der impulse
long summe_der_impulse;
int sensorPin = 2;             

const long pulse_pro_liter = 8327;      
const long fassinhalt      = 30.0;       
long volles_fass ;               
const int leuchtdauer = 12000;         
boolean licht, zapfvorgang, menge_einstellen;
static uint32_t Heartbeat;

unsigned long licht_timer;             // timer für die Beleuchtung des LCD-Displays
unsigned long zapf_timer;    
unsigned long zapf_ende_timer;
unsigned long timer_menge;      //timer während Menge reduzieren
unsigned long tast_timer;       //timer wenn taster kurz gedrückt wurde
unsigned long fehlpuls_timer;       //timer bei fehlimpulsen


float liter;                     
float seiterl;                   
float gezapft;                   
short check_fehler;
byte customChar[] = {
  B01010,  B00000,  B01110,  B00001,  B01111,  B10001,  B01111,  B00000
};

//________________________________________________________________________________________

void rpm ()     
{
  impulse++;  
}

//________________________________________________________________________________________

void setup()
{
  Wire.begin();
  Wire.setClock(10000);
  pinMode(sensorPin, INPUT_PULLUP); 
  attachInterrupt(digitalPinToInterrupt(sensorPin), rpm, FALLING);;
  pinMode (tasterPin, INPUT_PULLUP);
  pinMode(heartbeatPin, OUTPUT);
  Taster1.attachClick(licht_an);
  Taster1.attachDuringLongPress(Menge_reduzieren);

  delay (150);

  if (DEBUG) {
    Serial.begin(115200);   
  }

  lcd.createChar(0, customChar);
  licht_timer = 0;
  volles_fass = pulse_pro_liter * fassinhalt ;

  lcd.begin();
  lcd.backlight();
  lcd.noCursor();
  lcd.clear();
 
  lcd.setCursor(0, 0);
  lcd.print(F("Bierz"));
  lcd.write(0);
  lcd.print(F("hler = OK      "));
  lcd.setCursor(0, 1);
  lcd.print(F("     PROST!     "));

  for (int i = 0; i < 3; i++) {
    lcd.backlight();
    delay(150);
    lcd.noBacklight();
    delay(150);
  }
  lcd.backlight();
  delay (3000);     

  licht_timer = millis();
  zapf_timer = millis() ;               
  zapf_ende_timer = millis();
  Heartbeat = millis();
  fehlpuls_timer = millis();

  Berechnung();          
  LCD_Anzeige_Standard();
  impulse = 0;
  check_fehler = 0;
  zapfvorgang = false;
  menge_einstellen = false;
  licht = true;
}

//________________________________________________________________________________________

void Menge_reduzieren() {
  menge_einstellen = true;
  timer_menge = millis();
  lcd.backlight();
  licht = true;
  lcd.setCursor(0, 0);
  lcd.print(F("alt  "));
  lcd.print(liter, 1);
  lcd.print(F(" Liter    "));

  summe_der_impulse = summe_der_impulse + (pulse_pro_liter / 2);
  Berechnung();

  lcd.setCursor(0, 1);
  lcd.print(F("neu  "));
  lcd.print(liter, 1);
  lcd.print(F(" Liter    "));
  delay (500); // Pause, damit man den Taster wieder rechtzeitig auslassen kann
}

//________________________________________________________________________________________

void Berechnung() { 
  liter = float(volles_fass - summe_der_impulse - zapfimpulse) / pulse_pro_liter;
  seiterl = float(liter * 3.0);

  gezapft = (float(zapfimpulse) / pulse_pro_liter ) * 1000 ;
}

//________________________________________________________________________________________

void LCD_Anzeige_Standard() {
  lcd.setCursor(0, 0);
  lcd.print(F("Noch "));
  lcd.print(liter, 1);
  lcd.print(F( " Liter    "));
  lcd.setCursor(0, 1);
  lcd.print(seiterl, 0);
  lcd.print(F(" Seiterl        "));
}

//________________________________________________________________________________________

void LCD_Anzeige_Zapfen()
{
  lcd.setCursor(0, 0);
  lcd.print(F("Noch "));
  lcd.print(liter, 2);
  lcd.print(F(" Liter    "));
  lcd.setCursor(0, 1);
  lcd.print(F("gezapft "));
  lcd.print(gezapft, 0);
  lcd.print(F(" ml    "));
}

//________________________________________________________________________________________

void LCD_Anzeige_info()
{
  lcd.setCursor(0, 0);
  lcd.print(F("Noch "));
  lcd.print(liter, 2);
  lcd.print(F( " Liter    "));
  lcd.setCursor(0, 1);
  lcd.print(seiterl, 1);
  lcd.print(F(" Seiterl        "));
}

//________________________________________________________________________________________

void licht_an() {
  licht_timer = millis();
  tast_timer = millis();
  lcd.backlight();
  licht = true;
  LCD_Anzeige_info();
}

//________________________________________________________________________________________

void Fehlimpuls_check() {
  if (millis() - fehlpuls_timer > 300) {
    if (impulse != 0) {           
      impulse_vorher = impulse_vorher + impulse;
      check_fehler ++;
      impulse = 0;
    } else {
      impulse_vorher = 0;
      check_fehler = 0;
    }
    if ((check_fehler > 3) && (impulse_vorher > 0)) {  
      impulse = impulse_vorher;
      zapfvorgang = true;
      licht = true;
      lcd.backlight();
      check_fehler = 0;
      zapf_timer = millis() - 150;  
    }
    fehlpuls_timer = millis();
  }
}

//________________________________________________________________________________________

void Bier_zapfen() {
  if (impulse != 0) {                
    zapfimpulse = zapfimpulse + impulse;
    impulse = 0;
    Berechnung();                    
    licht = true;
    lcd.backlight();
    if ( millis() - zapf_timer >= 100) {
      LCD_Anzeige_Zapfen();          
      zapf_timer = millis();         
    }
    zapf_ende_timer = millis();      
    licht_timer = millis();          
  }

 
  if ( millis() - zapf_ende_timer >= 7000) {
    zapfvorgang = false;
    summe_der_impulse =  summe_der_impulse + zapfimpulse;
    zapfimpulse = 0;
    impulse_vorher = 0;
    LCD_Anzeige_Standard();          
    tast_timer = millis();           
    fehlpuls_timer = millis();       
  }
}

//________________________________________________________________________________________

void loop() {
  Taster1.tick();

  if (not zapfvorgang) {
    Fehlimpuls_check();
  }
  if (zapfvorgang) { // keine else Funktion, da während des Fehlerchecks der Zapfvorgang geändert werden kann
    Bier_zapfen();
  }

  if (not menge_einstellen && not zapfvorgang) {
    if ( millis() - tast_timer >= 5000) {
      LCD_Anzeige_Standard();
      tast_timer = millis();
    }
  }

  if (menge_einstellen) {              
    licht = true;
    lcd.backlight();
    licht_timer = millis();
    if ( millis() - timer_menge >= 5000) {
      menge_einstellen = false;
      LCD_Anzeige_Standard();
      timer_menge = millis();
    }
  }

  if (licht) {
    if (millis() - licht_timer >= leuchtdauer) {
      lcd.noBacklight();
      licht = false ;
      licht_timer = millis();
    }
  }

  if (millis() - Heartbeat > 1000)
  { digitalWrite(heartbeatPin, !digitalRead(heartbeatPin));
    Heartbeat = millis();
  }
}

Warum machst Du das sinnloserweise in einem neuen Thread losgelöst von der alten Diskussion?

@Mod: Bitte mit dem Ursprungsthread zusammenführen

Gruß Tommy

Tommy, ich vermute du hast den falschen Link gepostet.

Edit:
Ok, wurde geändert.

Nö, im letzten Posting dort teilt der hiesige TO mit, dass er es gelöst hat.

Gruß Tommy

Tommy56:
Nö, im letzten Posting dort teilt der hiesige TO mit, dass er es gelöst hat.

Gruß Tommy

Ich teile mit, dass ich es ANDERS gelöst habe. Mein Ursprungsthread war
hier
Nur dort ist das Thema etwas ganz anderes gewesen!

Ich habe den Ursprungsthread angepasst.

Gruß Tommy

TO: brauchst noch Feedback auf deinen Sketch oder willst es so lassen?

:slight_smile: jederzeit gerne :slight_smile:

nur als Anregung

//8892/548 dein Original
//8144/373 nun auf meiner Kiste

const uint8_t tasterPin = 4;  // datentyp geändert
const uint8_t heartbeatPin = 13;

LiquidCrystal_I2C lcd(0x27, 16, 2);

OneButton Taster1 = OneButton(tasterPin, true);
const byte DEBUG = 0; // datentyp geändert, const: das hat massive Auswirkung auf Ram
volatile uint32_t impulse, impulse_vorher, zapfimpulse;          //messen der impulse            // das braucht kein signed zu sein
uint32_t summe_der_impulse;                                         // das braucht kein signed zu sein
const byte  sensorPin = 2; // datentyp geändert, const

const uint16_t pulse_pro_liter = 8327;     // datentyp geändert (alt long)
const uint8_t fassinhalt = 30;             // datentyp geändert (alt long), Zuweisung geändert (alt 30.0)
uint16_t volles_fass;                      // braucht kein signed zu sein
const uint32_t leuchtdauer = 12000;        // datentyp geändert
boolean licht, zapfvorgang, menge_einstellen;
static uint32_t Heartbeat;

unsigned long licht_timer;                 // timer für die Beleuchtung des LCD-Displays
unsigned long zapf_timer;
unsigned long zapf_ende_timer;
unsigned long timer_menge;                 // timer während Menge reduzieren
unsigned long tast_timer;                  // timer wenn taster kurz gedrückt wurde
unsigned long fehlpuls_timer;              // timer bei fehlimpulsen

float liter;
float seiterl;
float gezapft;
uint16_t check_fehler;                    // datentyp geändert (alt short)
const byte customChar[] = 
{  B01010,  B00000,  B01110,  B00001,  B01111,  B10001,  B01111,  B00000};       // const gemacht

habs nicht mit Hardware getestet, aber einiges sollte nun besser sein.
Auf alle Fälle braucht das nun weniger Flash und Ram.

Was du noch generell machen sollst:
Vieleicht kannst sogar noch einige Zähler von 32bit auf 16 bit reduzieren. Das musst du dir überlegen.

leg dir fest wie du Variablen, Funktionen, Konstanten benennen willst,
was beginnt mit Kleinbuchstaben,
nimmst Underscores oder Camelcase zum Trennen,
wann schreibst in Versalien, etc.
Aktuell ist das bunt gemischt.

Und die Delays ... ja die sollst eigentlich auch loswerden.