Filter im Code auf einmal sehr langsam

Hallo Community.

Ich sitze jetzt schon seit Tagen und Wochen an diesem Problem und komme einfach nicht weiter.
Ich habe einen riesigen Code geschrieben und dieser funktioniert auch einwandfrei, bis auf eine Funktion.
Prinzipiell geht es darum, für eine automatisierte EpoxiHarz-Mischvorrichtung vorher die Gewichts- Unter- und Obergrenze des Harzbades einzustellen in das später hinein gefördert wird, sowie die Volumenanteile der beiden Komponenten. All das wird ins EEPROM gespeichert und nachher wieder abgerufen. Nach diesen Werten werden dann die zwei Pumpen über PWM gesteuert.

Der Code funktioniert mit mehreren Stati. In jedem Status wird eine Aufgabe ausgeführt und dann über einen button der Status geändert oder er erhöht sich selber über ein "status++". Über die buttons kann man in höhere und niedrigere Stati springen. Die Werte werden über ein Poti eingestellt und dann mit den buttons bestätigt.

Es geht mir nur um eine Sache: Zum auswählen der Harzbad Unter- und Obergrenzen habe ich einen Filter eingeführt, der nur Vielfache Werte von 25 auf dem Display anzeigt, da eine höhere Genauigkeit stören würde:

int WertUG = Poti / 2;   //Einführung Rohwert UG
if (WertUG % 25 == 0) {  //UG in 25er Schrittweite (filter)
    Wert_filterUG = WertUG;
  }

Im Status 7 wird dann "Wert_filterUG" auf dem LCD angezeigt und kann mit dem Poti eingestellt werden. Ein Druck auf den button erhöht den Status, wo der letzte Wert dann ins EEPROM gespeichert wird:

  if (status == 7) {  //Harzbad UG einstellen über Poti (Wert_filterUG)
    lcd.setCursor(0, 0);
    lcd.print("Harzbad Untergr.");
    lcd.setCursor(0, 1);
    lcd.print(Wert_filterUG);
    lcd.print(" g");
    if (Wert_filterUG < 1000) {
      lcd.setCursor(5, 1);
      lcd.print(" ");
    }
    if (Wert_filterUG < 100) {
      lcd.setCursor(4, 1);
      lcd.print(" ");
    }
    if (Wert_filterUG < 10) {
      lcd.setCursor(3, 1);
      lcd.print(" ");
    }
  }

Das Problem: Wenn man am Poti dreht, hängen die Werte komplett hinterher. Es dauert mehrere Sekunden bis sich der Wert ändert und dann ist man auf einmal von 100 auf 500 gesprungen und es ist fast unmöglich einen Wunschwert einzustellen. Es macht mich einfach sehr unglücklich, da der Rest alles läuft. Ohne den Filter ändern sich die Werte flüssig.
Ich habe auch mal den oberen Code in jeden Status eingefügt und komischerweise Funktioniert der Filter total flüssig in allen Stati kleiner 3!
Es muss also irgendwo eine Stelle geben, die ab Status 3 den Arduino verlangsamt oder so.
Ich habe ab Status 3 blinkende Displays in den Code eingebaut, die funktionieren aber mit "millis()" und sollten nichts verlangsamen. Auch als ich das Blinken raus genommen habe, hat es nicht besser geklappt.
Ich habe auch schon die Baudrate in beide Richtungen angepasst, ohne Erfolg.
Wenn ich kleinere Teiler als 25 nehme, läuft es immer flüssiger.

Ich werde unten meinen Code einfügen, bis zum Status 7. Ist trotzdem eine Menge, weil das ganze Setup und die Bedingungen davor mit drin sind. Es tut mir Leid wenn euch dann der Kopf glüht. Danach geht es noch weiter bis Status 21, aber da läuft alles und da ist auch nirgends Status 3 erwähnt.

Ich bin total am Verzweifeln und möchte das Projekt einfach nicht so unperfekt abgeben... :disappointed_relieved: Vielleicht könnt ihr mir ja sagen, woran es liegt dass dieser Filter so seltsam hält. Vielen Dank euch!

#include <EEPROM.h>  //Libraries
#include <HX711_ADC.h>
#include <LiquidCrystal.h>
#include <TM1637Display.h>
#include <inttypes.h>

#define CLK1 26  //define small display pins für alle 3 Displays; small display1
#define DIO1 27
#define CLK2 22  //small display 2
#define DIO2 23
#define CLK3 24  //small display 3
#define DIO3 25

const uint8_t lo[] = {
  //Blink-Anzeige "LO", wenn Vorratsbehälter unter bestimmter Grenze
  SEG_D | SEG_E | SEG_F,                          // L
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,  // O
  0x00,
  0x00,
};

const uint8_t auff[] = {
  //Blink-Anzeige "AUFF", wenn die Pumpen arbeiten
  SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G,  // A
  SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,          // U
  SEG_A | SEG_E | SEG_F | SEG_G,                  // F
  SEG_A | SEG_E | SEG_F | SEG_G,                  // F
};

const int button1Pin = 10;  //button Pins
const int button2Pin = 9;

const int HX711_dout_1 = 39;  //Zelle1 HX711 dout pin
const int HX711_sck_1 = 38;   //Zelle1 HX711 sck pin
const int HX711_dout_2 = 37;  //Zelle2 HX711 dout pin
const int HX711_sck_2 = 36;   //Zelle2 HX711 sck pin
const int HX711_dout_3 = 35;  //Zelle3 HX711 dout pin
const int HX711_sck_3 = 34;   //Zelle3 HX711 sck pin

const int potPin = A0;                                           //Poti Pin
const int rs = 52, en = 50, d4 = 48, d5 = 46, d6 = 44, d7 = 42;  //LCD Pins

const int pump1 = 3;  //Pumpen Pins
const int pump2 = 4;

HX711_ADC LoadCell_1(HX711_dout_1, HX711_sck_1);  //HX711 1 Harzbad
HX711_ADC LoadCell_2(HX711_dout_2, HX711_sck_2);  //HX711 2 Harz
HX711_ADC LoadCell_3(HX711_dout_3, HX711_sck_3);  //HX711 3 Haerter

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);  //LCD-Display erstellen
TM1637Display display1(CLK1, DIO1);         //SmallDisplay1 erstellen
TM1637Display display2(CLK2, DIO2);         //SmallDisplay2 erstellen
TM1637Display display3(CLK3, DIO3);         //SmallDisplay3 erstellen

const int calVal_eepromAdress_1 = 0;  // EEPROM adress for calibration value load cell 1 (4 bytes); Adressen müssen mind. 4 Stellen auseinander liegen
const int calVal_eepromAdress_2 = 4;  // EEPROM adress for calibration value load cell 2 (4 bytes)
const int calVal_eepromAdress_3 = 8;  // EEPROM adress for calibration value load cell 3 (4 bytes)

unsigned long t = 0;  //Variablen
int button1 = 0;
int button2 = 0;
int status = 0;
int extra = 0;
int neu = 0;
int pumprate1 = 0;
int pumprate2 = 0;

bool Auffuellvorgang{ false };  //Auffüllvorgang ist nicht aktiviert

float WertHarz;               //vol. Anteil Harz
int WertHarz_address = 150;   //EEPROM address for WertHarz
float PumpHarz;               //Pumpenverhältnis Harz
int PumpHarz_address = 154;   //EEPROM address
float WertHaert;              //vol. Anteil Haert
int WertHaert_address = 160;  //EEPROM address for WertHaert
float PumpHaert;              //Pumpenverhältnis Haert
int PumpHaert_address = 164;  //EEPROM address

int Wert_filterUG;  //UG in 25er Schrittweite
float UG;
int UG_address = 120;  // EEPROM adress for UG

int Wert_filterOG;  //OG in 25er Schrittweite
float OG;
int OG_address = 124;  //EEPROM address for OG

unsigned long previousMillisHB = 0;  //Harzbad Zeiten für Blink-Anzeige
const long intervalHB = 2340;
const long intervalHB2 = 11700;
unsigned long previousMillisBlink = 0;  //Harz und Härter Zeiten für Blink-Anzeige
const long intervalBlink = 3900;
const long intervalBlink2 = 7800;
unsigned long previousMillisTare = 0;  //Tare Zeiten für Tare ohne delay
const long intervalTare = 23400;
const long intervalTare2 = 39000;
const long intervalTare3 = 39780;
bool istGesetzt = false;   //bool Variable für Tare
bool istGesetzt2 = false;  //bool Variable für Tare2


void setup() {
  TCCR2B = TCCR2B & 0b11111000 | 0x02; Timer2 (pin 9&10) von 490 auf 3900Hz ändern
  pinMode(button1Pin, INPUT);  //Pin Modes
  pinMode(button2Pin, INPUT);
  pinMode(pump1, OUTPUT);
  pinMode(pump2, OUTPUT);
  Serial.begin(57600);
  Serial.print("status: ");
  Serial.println(status);

  float calibrationValue_1;                               // calibration value load cell 1
  float calibrationValue_2;                               // calibration value load cell 2
  float calibrationValue_3;                               // calibration value load cell 3
  EEPROM.get(calVal_eepromAdress_1, calibrationValue_1);  //calibration values aus EEPROM holen (vorher generiert)
  EEPROM.get(calVal_eepromAdress_2, calibrationValue_2);
  EEPROM.get(calVal_eepromAdress_3, calibrationValue_3);
  LoadCell_1.begin();  //Wägezellen starten
  LoadCell_2.begin();
  LoadCell_3.begin();
  unsigned long stabilizingtime = 15600;  // higher time = higher tare preciscion
  boolean _tare = true;                  //false = no tare in next step
  byte loadcell_1_rdy = 0;
  byte loadcell_2_rdy = 0;
  byte loadcell_3_rdy = 0;

  while ((loadcell_1_rdy + loadcell_2_rdy + loadcell_3_rdy) < 3) {  //run startup, stabilization and tare, all modules simultaniously
    if (!loadcell_1_rdy) loadcell_1_rdy = LoadCell_1.startMultiple(stabilizingtime, _tare);
    if (!loadcell_2_rdy) loadcell_2_rdy = LoadCell_2.startMultiple(stabilizingtime, _tare);
    if (!loadcell_3_rdy) loadcell_3_rdy = LoadCell_3.startMultiple(stabilizingtime, _tare);
  }

  LoadCell_1.setCalFactor(calibrationValue_1);  // user set calibration value (float)
  LoadCell_2.setCalFactor(calibrationValue_2);  // user set calibration value (float)
  LoadCell_3.setCalFactor(calibrationValue_3);  // user set calibration value (float)

  Serial.println("Startup is complete");

  lcd.begin(16, 2);
  lcd.print("Startup complete");
  lcd.setCursor(0, 1);
  lcd.print("press button1");
  display1.clear();
  display2.clear();
  display3.clear();
}

void loop() {
  static boolean newDataReady = 0;
  const int serialPrintInterval = 3900;

  if (LoadCell_1.update()) newDataReady = true;  //check for new data Waegezellen
  LoadCell_2.update();
  LoadCell_3.update();

  display1.setBrightness(4);  //SmallDisplays anschalten
  display2.setBrightness(4);
  display3.setBrightness(4);

  //  Fuellstandsanzeige Harzbad Normalzustand
  int HB;
  if (status >= 3) {
    HB = LoadCell_1.getData();
    if (LoadCell_1.getData() < 0) {
      HB = 0;
    }
  }
  //  Fuellstandsanzeige Harzbad Auffüllvorgang mit Blink
  if ((status == 20 || status == 21) && (pumprate1 > 0 || pumprate2 > 0)) {  //Blink wenn mindestens eine der beiden Pumpen arbeitet und auffüllt
    unsigned long currentMillisHB = millis();
    if (LoadCell_1.getData() < 0) {
      HB = 0;
    }
    if (currentMillisHB - previousMillisHB < intervalHB) {  //Zeige den Vektor "auff" an
      display1.setSegments(auff);
    }
    if (currentMillisHB - previousMillisHB >= intervalHB) {  //Zeige den Wert "Wägezelle" HB an
      display1.showNumberDec(HB, false, 4, 0);
    }
    if (currentMillisHB - previousMillisHB >= intervalHB2) {  //Reset den Wert von Millis
      previousMillisHB = currentMillisHB;
    }
  } else if (status >= 3) {  //Außerhalb von Status 20/21 nur HB anzeigen
    display1.showNumberDec(HB, false, 4, 0);
  }

  //  Fuellstandsanzeige Harz mit Blink
  int HARZ = LoadCell_2.getData();
  if (status >= 3) {
    unsigned long currentMillisBlink = millis();
    if (LoadCell_2.getData() < 0) {
      HARZ = 0;
    }
    if (LoadCell_2.getData() >= 100) {  //Wenn HARZ > 100g, nur HARZ anzeigen
      display2.showNumberDec(HARZ, false, 4, 0);
    }
    if (LoadCell_2.getData() < 100) {  //Wenn HARZ < 100g, Anzeige mit Blink
      if (currentMillisBlink - previousMillisBlink < intervalBlink) {
        display2.setSegments(lo);
      }
      if (currentMillisBlink - previousMillisBlink >= intervalBlink) {
        display2.showNumberDec(HARZ, false, 4, 0);
      }
      if (currentMillisBlink - previousMillisBlink >= intervalBlink2) {
        previousMillisBlink = currentMillisBlink;
      }
    }
  }
  //  Fuellstandsanzeige Haerter mit Blink
  int HAERT = LoadCell_3.getData();
  if (status >= 3) {
    unsigned long currentMillisBlink = millis();
    if (LoadCell_3.getData() < 0) {
      HAERT = 0;
    }
    if (LoadCell_3.getData() >= 100) {  //Wenn HAERT > 100g, nur HAERT anzeigen
      display3.showNumberDec(HAERT, false, 4, 0);
    }
    if (LoadCell_3.getData() < 100) {  //Wenn HAERT < 100g, Anzeige mit Blink
      if (currentMillisBlink - previousMillisBlink < intervalBlink) {
        display3.setSegments(lo);
      }
      if (currentMillisBlink - previousMillisBlink >= intervalBlink) {
        display3.showNumberDec(HAERT, false, 4, 0);
      }
      if (currentMillisBlink - previousMillisBlink >= intervalBlink2) {
        previousMillisBlink = currentMillisBlink;
      }
    }
  }

  ///////////////////////////////////////////////////////////////////// Funktion der Buttons
  button1 = digitalRead(button1Pin);  //Einführung Buttons
  button2 = digitalRead(button2Pin);


  if (button1 == HIGH && extra == 0) {
    delay(3900);
    status++;
    Serial.print("status: ");
    Serial.println(status);
    lcd.clear();
  } else if (button2 == HIGH) {
    delay(3900);

    switch (status) {
      case 9:
      case 8:
        status = 7;
        break;
      case 10:
      case 11:
        status = 9;
        break;
      case 12:
      case 13:
      case 14:
        status = 11;
        break;
      case 15:
      case 16:
      case 17:
      case 18:
      case 19:
        status = 14;
        break;
      case 20:
        extra++;
        Serial.print("extra: ");
        Serial.println(extra);
        break;
      case 21:
        pumprate1 = PumpHarz * 2.55;
        pumprate2 = PumpHaert * 2.55;
        analogWrite(pump1, pumprate1);
        analogWrite(pump2, pumprate2);
        status = 20;
        extra = 0;
        neu = 0;
        break;
    }

    Serial.print("status: ");
    Serial.println(status);
    lcd.clear();
  }

  if (button1 == HIGH && status == 20 && extra > 0 && extra <= 3) {
    delay(3900);
    neu++;
    Serial.print("neu: ");
    Serial.println(neu);
    lcd.clear();
  }

  if (button2 == HIGH && status == 20 && neu > 0) {
    delay(3900);
    neu = 0;
    extra--;
    Serial.print("neu: ");
    Serial.println(neu);
    lcd.clear();
  }
  /////////////////////////////////////////////////////////////////////////////////////////

  int Poti = analogRead(potPin);  //Einführung Poti
  int FoerderHarz = Poti / 17;    //Einführung Fördergeschwindigkeit Harz beim Aufbauen
  int FoerderHaert = Poti / 17;   //Einführung Fördergeschwindigkeit Harz beim Aufbauen
  int AntHarz = Poti / 6.82;      //Einführung Anteil Harz, mit Poti festlegen (0-150 Volumenanteile)
  if (AntHarz > 150) {
    AntHarz = 150;
  }
  int AntHaert = Poti / 6.82;  //Einführung Anteil Haert, mit Poti festlegen (0-150 Volumenanteile)
  if (AntHaert > 150) {
    AntHaert = 150;
  }

  int WertUG = Poti / 2;   //Einführung Rohwert UG
  if (WertUG % 25 == 0) {  //UG in 25er Schrittweite (filter)
    Wert_filterUG = WertUG;
  }

  int WertOG = Poti / 2 + 400;  //Einführung Rohwert OG
  if (WertOG % 25 == 0) {       //OG in 25er Schrittweite (filter)
    Wert_filterOG = WertOG;
  }


  ///////////////////////////////////////////////////////////////////////////////// Beginn Programm

  if (status == 1) {  //System aufbauen
    lcd.setCursor(0, 0);
    lcd.print("System");
    lcd.setCursor(0, 1);
    lcd.print("aufbauen");
  }
  if (status == 2) {  //Tare alle Wägezellen
    unsigned long currentMillisTare = millis();
    lcd.setCursor(0, 0);
    lcd.print("System tare...");
    if (currentMillisTare - previousMillisTare < intervalTare) {
      LoadCell_1.tareNoDelay();
      LoadCell_2.tareNoDelay();
      LoadCell_3.tareNoDelay();
    }
    if (currentMillisTare - previousMillisTare >= intervalTare && currentMillisTare - previousMillisTare < intervalTare2) {
      lcd.setCursor(0, 1);
      lcd.print("done");
    }
    if (currentMillisTare - previousMillisTare >= intervalTare2 && currentMillisTare - previousMillisTare < intervalTare3) {
      lcd.clear();
      status++;  //AUTOWECHSEL
    }
    if (currentMillisTare >= intervalTare3 && istGesetzt == false) {  //Millis-Wert einmalig speichern, danach wird "istGesetzt" nurnoch =true bleiben
      previousMillisTare = millis();
      istGesetzt = true;
    }
  }
  if (status == 3) {  //Harz und Haerter auffüllen
    lcd.setCursor(0, 0);
    lcd.print("Harz&Haert auff.");
    lcd.setCursor(0, 1);
    lcd.print("...");
    if (LoadCell_1.getData() >= 100 && LoadCell_2.getData() >= 100) {
      lcd.setCursor(0, 3);
      lcd.print("done");
      delay(23400);
      lcd.clear();
      status++;
    }
  }
  if (status == 4) {  //Harz vorfoerdern
    lcd.setCursor(0, 0);
    lcd.print("Harz vorfoerdern");
    lcd.setCursor(0, 1);
    lcd.print("adjust then b1");
    analogWrite(pump1, FoerderHarz);
  }
  if (status == 5) {  //Haerter vorfoerdern
    analogWrite(pump1, 0);
    lcd.setCursor(0, 0);
    lcd.print("Haerter vorfoerd");
    lcd.setCursor(0, 1);
    lcd.print("adjust then b1");
    analogWrite(pump2, FoerderHaert);
  }
  if (status == 6) {  //Tare alle Zellen
    analogWrite(pump1, 0);
    analogWrite(pump2, 0);
    unsigned long currentMillisTare = millis();
    lcd.setCursor(0, 0);
    lcd.print("System tare...");
    if (currentMillisTare - previousMillisTare < intervalTare) {
      LoadCell_1.tareNoDelay();
      LoadCell_2.tareNoDelay();
      LoadCell_3.tareNoDelay();
    }
    if (currentMillisTare - previousMillisTare >= intervalTare && currentMillisTare - previousMillisTare < intervalTare2) {
      lcd.setCursor(0, 1);
      lcd.print("done");
    }
    if (currentMillisTare - previousMillisTare >= intervalTare2 && currentMillisTare - previousMillisTare < intervalTare3) {
      lcd.clear();
      status++;  //AUTOWECHSEL
    }
    if (currentMillisTare >= intervalTare3 && istGesetzt2 == false) {  //Millis-Wert einmalig speichern, danach wird "istGesetzt2" nurnoch =true bleiben
      previousMillisTare = millis();
      istGesetzt2 = true;
    }
  }
  if (status == 7) {  //Harzbad UG einstellen über Poti (Wert_filterUG)
    lcd.setCursor(0, 0);
    lcd.print("Harzbad Untergr.");
    lcd.setCursor(0, 1);
    lcd.print(Wert_filterUG);
    lcd.print(" g");
    if (Wert_filterUG < 1000) {
      lcd.setCursor(5, 1);
      lcd.print(" ");
    }
    if (Wert_filterUG < 100) {
      lcd.setCursor(4, 1);
      lcd.print(" ");
    }
    if (Wert_filterUG < 10) {
      lcd.setCursor(3, 1);
      lcd.print(" ");
    }
  }

Danke dass du bis hierher gelesen hast :slight_smile:

? das sind 23,4 Sekunden bis du auf status 4 kommst, ist das so gewollt?

Ich sehe ganz viele delay().

und ich sehe unstrukturierten und unkommentierten Spaghetticode mit magischen Nummern.

Ich sehe viele uneffektive und vor allem unübersichtliche if, wo ein else angebracht wäre. Wenn es nicht < ist, ist es >=.

Gruß Tommy

Ich musste den Timer ändern, da ich für meine Anwendung über 490 Hz PWM Frequenz brauche :). Damit musste ich alle Zeitwerte mit 7,8 multiplizieren

Ja, ganz ohne ging es leider nicht. Delay spielt aber nur eine Rolle, wenn ein button gedrückt wird, oder in einem bestimmten Status, wenn etwas ausgeführt werden soll. Also auf jeden Fall keine sich permanent wiederholende delays. Meinst Du, dass es trotzdem eine Auswirkung auf das Problem hat?

Das werde ich ändern, danke. Aber auch ganz ohne die blinkenden Anzeigen hat es leider noch gehangen.

Sorry.. ich weiß, es ist kein Augenschmaus

Pins 5 und 6 haben 980 Hz, ok du brauchst über 3KHz.

ja leider

Ich finde es sehr unübersichtlich an sehr vielen Stellen im Sketch Variablen zu definieren.
Außerdem wegen der lokalen Variablen kann es DIr leicht passieren daß irgendwo die Variable nicht existiert oder einen anderen Wert hat als Du Dir erwartest.
Grüße Uwe

Verstehe. Und meinst Du, dass das eine Auswirkung auf den Filter haben könnte?

Die Art(Kunst), wie du dein Programm geschrieben hast, hält mich davon ab, da durch zu blicken.
Mir ist das zuviel if
Zuviel in loop() (pi mal Daumen sind bis zu 20 Zeilen ok)

Ich wünsche mir Modularität!
Dann könnte man die Komponenten viel besser einzeln testen.

Hallo,
ich wurde mal an die Stelle wo der analog Wert eingelesen wird ein Serial.print einbauen nur um mal festzustellen ob das Einlesen schon hängt. Dann an einer anderen Stellen mit Serial.print herausfinden wo sich der Übeltäter versteckt. Letztlich wirst Du um ein systematisches Debuggen nicht herumkommen.

Die Beiden Taster hast Du mit pulldown Widerständen versehen ?

schau dir mal enum an dann kannst Du die magischen Nummern vergessen und den "Schritten" vernünftige Namen geben. Wenn Du dann noch swich.. case anstelle der if... verwendest wird es schon ein Wenig überschaubarer und Du findest Dich auch noch in einem Jahr zurecht.

Hallo,
Danke für die Ideen. Ich habe mit dem Serial.print nachgeschaut und tatsächlich hängt schon das Einlesen...
Ja, die Taster haben pulldown Widerstände.

Die anderen Anregungen sind mir schon mehrmals über den Weg gelaufen, mit viel Zeit würde ich das auch nochmal neu aufrollen.

Ich krieg Ddeinen Code schon nicht kompiliert.

exit status 1
stray '\303' in program

Nachdem ich die letzte KLammer schon eingefügt habe.
Was für ein Controller?
UNd woher stammen die libs?

Hey.
Ja, das wundert mich nicht.. Vielleicht habe ich nicht gesagt, dass das nur der Teil des Codes bis zum Problem ist, sorry. Danach kommen noch weitere Stati und auch Teile, die ich aus den Libs habe. Da kommt dann auch die letzte Klammer.
Ich dachte, dass erfahrene Augen vielleicht da schon sehen, wo das Problem vielleicht liegen könnte. Naiv.

Die Libs habe ich alle aus dem Library Manager der IDE. Ich habe einen Arduino Mega 2560.
Ich habe das Projekt vorhin abgegeben. Den Filter habe ich jetzt auf %5 gesetzt, das ist zwar eigentlich zu klein aber läuft annähernd flüssig. Wissen wo das Problem liegt, würde ich natürlich trotzdem gern..

Ich lade hier jetzt einfach den gesamten Code hoch:

#include <EEPROM.h>  //Libraries
#include <HX711_ADC.h>
#include <LiquidCrystal.h>
#include <TM1637Display.h>
#include <inttypes.h>

#define CLK1 26  //define small display pins für alle 3 Displays; small display1
#define DIO1 27
#define CLK2 22  //small display 2
#define DIO2 23
#define CLK3 24  //small display 3
#define DIO3 25

const uint8_t lo[] = {
  //Blink-Anzeige "LO", wenn Vorratsbehälter unter bestimmter Grenze
  SEG_D | SEG_E | SEG_F,                          // L
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,  // O
  0x00,
  0x00,
};

const uint8_t auff[] = {
  //Blink-Anzeige "AUFF", wenn die Pumpen arbeiten
  SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G,  // A
  SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,          // U
  SEG_A | SEG_E | SEG_F | SEG_G,                  // F
  SEG_A | SEG_E | SEG_F | SEG_G,                  // F
};

const int button1Pin = 10;  //button Pins
const int button2Pin = 9;

const int HX711_dout_1 = 39;  //Zelle1 HX711 dout pin
const int HX711_sck_1 = 38;   //Zelle1 HX711 sck pin
const int HX711_dout_2 = 37;  //Zelle2 HX711 dout pin
const int HX711_sck_2 = 36;   //Zelle2 HX711 sck pin
const int HX711_dout_3 = 35;  //Zelle3 HX711 dout pin
const int HX711_sck_3 = 34;   //Zelle3 HX711 sck pin

const int potPin = A0;                                           //Poti Pin
const int rs = 52, en = 50, d4 = 48, d5 = 46, d6 = 44, d7 = 42;  //LCD Pins

const int pump1 = 3;  //Pumpen Pins
const int pump2 = 4;

HX711_ADC LoadCell_1(HX711_dout_1, HX711_sck_1);  //HX711 1 Harzbad
HX711_ADC LoadCell_2(HX711_dout_2, HX711_sck_2);  //HX711 2 Harz
HX711_ADC LoadCell_3(HX711_dout_3, HX711_sck_3);  //HX711 3 Haerter

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);  //LCD-Display erstellen
TM1637Display display1(CLK1, DIO1);         //SmallDisplay1 erstellen
TM1637Display display2(CLK2, DIO2);         //SmallDisplay2 erstellen
TM1637Display display3(CLK3, DIO3);         //SmallDisplay3 erstellen

const int calVal_eepromAdress_1 = 0;  // EEPROM adress for calibration value load cell 1 (4 bytes); Adressen müssen mind. 4 Stellen auseinander liegen
const int calVal_eepromAdress_2 = 4;  // EEPROM adress for calibration value load cell 2 (4 bytes)
const int calVal_eepromAdress_3 = 8;  // EEPROM adress for calibration value load cell 3 (4 bytes)

unsigned long t = 0;  //Variablen
int button1 = 0;
int button2 = 0;
int status = 0; //Stati für Aufgaben
int extra = 0;  //extra-Menü als Unterprogramm
int neu = 0;  //neu-Menü als weiteres Unterprogramm
int pumprate1 = 0;
int pumprate2 = 0;

bool Auffuellvorgang{ false };  //Auffüllvorgang ist nicht aktiv

float WertHarz;               //vol. Anteil Harz
int WertHarz_address = 150;   //EEPROM address for WertHarz
float PumpHarz;               //Pumpenverhältnis Harz
int PumpHarz_address = 154;   //EEPROM address
float WertHaert;              //vol. Anteil Haert
int WertHaert_address = 160;  //EEPROM address for WertHaert
float PumpHaert;              //Pumpenverhältnis Haert
int PumpHaert_address = 164;  //EEPROM address

int Wert_filterUG;  //UG in 25er Schrittweite
float UG;
int UG_address = 120;  // EEPROM adress for UG

int Wert_filterOG;  //OG in 25er Schrittweite
float OG;
int OG_address = 124;  //EEPROM address for OG

unsigned long previousMillisHB = 0;  //Harzbad Zeiten für Blink-Anzeige
const long intervalHB = 300;
const long intervalHB2 = 1500;
unsigned long previousMillisBlink = 0;  //Harz und Härter Zeiten für Blink-Anzeige
const long intervalBlink = 500;
const long intervalBlink2 = 1000;
unsigned long previousMillisTare = 0;  //Tare Zeiten für Tare ohne delay
const long intervalTare = 3000;
const long intervalTare2 = 5000;
const long intervalTare3 = 5100;
bool istGesetzt = false;   //bool Variable für Tare
bool istGesetzt2 = false;  //bool Variable für Tare2


void setup() {
  //TCCR2B = TCCR2B & 0b11111000 | 0x02; //Timer2 (pin 9&10) von 490 auf 3900Hz ändern (FUNKTIONIERT NICHT RICHTIG)
  pinMode(button1Pin, INPUT);  //Pin Modes
  pinMode(button2Pin, INPUT);
  pinMode(pump1, OUTPUT);
  pinMode(pump2, OUTPUT);
  Serial.begin(57600);
  Serial.print("status: ");
  Serial.println(status);

  float calibrationValue_1;                               // calibration value load cell 1
  float calibrationValue_2;                               // calibration value load cell 2
  float calibrationValue_3;                               // calibration value load cell 3
  EEPROM.get(calVal_eepromAdress_1, calibrationValue_1);  //calibration values aus EEPROM holen (vorher generiert)
  EEPROM.get(calVal_eepromAdress_2, calibrationValue_2);
  EEPROM.get(calVal_eepromAdress_3, calibrationValue_3);
  LoadCell_1.begin();  //Wägezellen starten
  LoadCell_2.begin();
  LoadCell_3.begin();
  unsigned long stabilizingtime = 2000;  // higher time = higher tare preciscion
  boolean _tare = true;                  //false = no tare in next step
  byte loadcell_1_rdy = 0;
  byte loadcell_2_rdy = 0;
  byte loadcell_3_rdy = 0;

  while ((loadcell_1_rdy + loadcell_2_rdy + loadcell_3_rdy) < 3) {  //run startup, stabilization and tare, all modules simultaniously
    if (!loadcell_1_rdy) loadcell_1_rdy = LoadCell_1.startMultiple(stabilizingtime, _tare);
    if (!loadcell_2_rdy) loadcell_2_rdy = LoadCell_2.startMultiple(stabilizingtime, _tare);
    if (!loadcell_3_rdy) loadcell_3_rdy = LoadCell_3.startMultiple(stabilizingtime, _tare);
  }

  LoadCell_1.setCalFactor(calibrationValue_1);  // user set calibration value (float)
  LoadCell_2.setCalFactor(calibrationValue_2);  // user set calibration value (float)
  LoadCell_3.setCalFactor(calibrationValue_3);  // user set calibration value (float)

  Serial.println("Startup is complete");

  lcd.begin(16, 2);
  lcd.print("Startup complete");
  lcd.setCursor(0, 1);
  lcd.print("press button1");
  display1.clear();
  display2.clear();
  display3.clear();
}

void loop() {
  unsigned long currentMillis = millis(); //millis() zählt die vergangene Zeit seit Beginn, damit wird später gearbeitet
  static boolean newDataReady = 0;
  const int serialPrintInterval = 500;
  int Poti = analogRead(potPin);  //Einführung Poti (Kann Werte von 0 bis 1023 generieren, kann umgerechnet werden)
  int GewichtHB = LoadCell_1.getData(); //Wägezelle1 für Gewicht Harzbad
  int GewichtHARZ = LoadCell_2.getData(); //Wägezelle2 für Gewicht Harz Vorrat
  int GewichtHAERT = LoadCell_3.getData();  //Wägezelle3 für Gewicht Härter Vorrat
  // Begrenze GewichtHB, GewichtHARZ und GewichtHAERT auf nicht-negativ
  GewichtHB = max(GewichtHB, 0);
  GewichtHARZ = max(GewichtHARZ, 0);
  GewichtHAERT = max(GewichtHAERT, 0);


  if (LoadCell_1.update()) newDataReady = true;  //check for new data Waegezellen
  LoadCell_2.update();
  LoadCell_3.update();

  display1.setBrightness(4);  //SmallDisplays anschalten
  display2.setBrightness(4);
  display3.setBrightness(4);

  //  Fuellstandsanzeige Harzbad Auffüllvorgang mit Blink
  if ((status == 20 || status == 21) && (pumprate1 > 0 || pumprate2 > 0)) {  //Blink wenn mindestens eine der beiden Pumpen arbeitet und auffüllt
    if (currentMillis - previousMillisHB < intervalHB) {                     //Zeige den Vektor "auff" an
      display1.setSegments(auff);
    }
    if (currentMillis - previousMillisHB >= intervalHB) {  //Zeige den Wert "Wägezelle" GewichtHB an
      display1.showNumberDec(GewichtHB, false, 4, 0);
    }
    if (currentMillis - previousMillisHB >= intervalHB2) {  //Reset den Wert von Millis
      previousMillisHB = currentMillis;
    }
    //  Fuellstandsanzeige Harzbad Normalzustand
  } else if (status >= 3) {  //Außerhalb von Status 20/21 nur GewichtHB anzeigen ohne Blink
    display1.showNumberDec(GewichtHB, false, 4, 0);
  }

  // Anzeige GewichtHARZ und GewichtHAERT mit Blink
  if (status >= 3) {
    // Anzeige mit Blink für GewichtHARZ
    if (GewichtHARZ < 100) {
      if (currentMillis - previousMillisBlink < intervalBlink) {
        display2.setSegments(lo);
      } else if (currentMillis - previousMillisBlink >= intervalBlink2) {
        previousMillisBlink = currentMillis;
      } else {
        display2.showNumberDec(GewichtHARZ, false, 4, 0);
      }
    } else {
      display2.showNumberDec(GewichtHARZ, false, 4, 0); //über 100g Anzeige ohne Blink
    }

    // Anzeige mit Blink für GewichtHAERT
    if (GewichtHAERT < 100) {
      if (currentMillis - previousMillisBlink < intervalBlink) {
        display3.setSegments(lo);
      } else if (currentMillis - previousMillisBlink >= intervalBlink2) {
        previousMillisBlink = currentMillis;
      } else {
        display3.showNumberDec(GewichtHAERT, false, 4, 0);
      }
    } else {
      display3.showNumberDec(GewichtHAERT, false, 4, 0); //über 100g Anzeige ohne Blink
    }
  }

  ///////////////////////////////////////////////////////////////////// Funktion der Buttons
  button1 = digitalRead(button1Pin);  //Einführung Buttons
  button2 = digitalRead(button2Pin);


  if (button1 == HIGH && extra == 0) {
    delay(500);
    status++;
    Serial.print("status: ");
    Serial.println(status);
    lcd.clear();
  } else if (button2 == HIGH) { //switch case zum Zurückspringen im Status wenn button2 gedrückt
    delay(500);

    switch (status) {
      case 9:
      case 8:
        status = 7;
        break;
      case 10:
      case 11:
        status = 9;
        break;
      case 12:
      case 13:
      case 14:
        status = 11;
        break;
      case 15:
      case 16:
      case 17:
      case 18:
      case 19:
        status = 14;
        break;
      case 20:
        extra++;
        Serial.print("extra: ");
        Serial.println(extra);
        break;
      case 21:
        pumprate1 = PumpHarz * 2.55;
        pumprate2 = PumpHaert * 2.55;
        analogWrite(pump1, pumprate1);
        analogWrite(pump2, pumprate2);
        status = 20;
        extra = 0;
        neu = 0;
        break;
    }

    Serial.print("status: ");
    Serial.println(status);
    lcd.clear();
  }

  if (button1 == HIGH && status == 20 && extra > 0 && extra <= 3) {
    delay(500);
    neu++;
    Serial.print("neu: ");
    Serial.println(neu);
    lcd.clear();
  }

  if (button2 == HIGH && status == 20 && neu > 0) {
    delay(500);
    neu = 0;
    extra--;
    Serial.print("neu: ");
    Serial.println(neu);
    lcd.clear();
  }
  ///////////////////////////////////////////////////////////////// Funktionen Potentiometer

  int FoerderHarz = Poti / 17;   //Einführung Fördergeschwindigkeit Harz beim Aufbauen
  int FoerderHaert = Poti / 17;  //Einführung Fördergeschwindigkeit Harz beim Aufbauen
  int AntHarz = Poti / 6.82;     //Einführung Anteil Harz, mit Poti festlegen (0-150 Volumenanteile)
  if (AntHarz > 150) {
    AntHarz = 150;
  }
  int AntHaert = Poti / 6.82;  //Einführung Anteil Haert, mit Poti festlegen (0-150 Volumenanteile)
  if (AntHaert > 150) {
    AntHaert = 150;
  }

  int WertUG = Poti / 2;  //Einführung Rohwert UG
  if (WertUG % 5 == 0) {  //UG in 5er Schrittweite (filter)
    Wert_filterUG = WertUG;
  }

  int WertOG = Poti / 2 + 400;  //Einführung Rohwert OG
  if (WertOG % 5 == 0) {        //OG in 5er Schrittweite (filter)
    Wert_filterOG = WertOG;
  }


  ///////////////////////////////////////////////////////////////////////////////// Beginn Programm

  if (status == 1) {  //System aufbauen
    lcd.setCursor(0, 0);
    lcd.print("System");
    lcd.setCursor(0, 1);
    lcd.print("aufbauen");
  }
  if (status == 2) {  //Tare alle Wägezellen
    lcd.setCursor(0, 0);
    lcd.print("System tare...");
    if (currentMillis - previousMillisTare < intervalTare) {
      LoadCell_1.tareNoDelay();
      LoadCell_2.tareNoDelay();
      LoadCell_3.tareNoDelay();
    }
    if (currentMillis - previousMillisTare >= intervalTare && currentMillis - previousMillisTare < intervalTare2) {
      lcd.setCursor(0, 1);
      lcd.print("done");
    }
    if (currentMillis - previousMillisTare >= intervalTare2 && currentMillis - previousMillisTare < intervalTare3) {
      lcd.clear();
      status++;  //AUTOWECHSEL
    }
    if (currentMillis >= intervalTare3 && istGesetzt == false) {  //Millis-Wert einmalig speichern, danach wird "istGesetzt" nurnoch =true bleiben
      previousMillisTare = millis();
      istGesetzt = true;
    }
  }
  if (status == 3) {  //Harz und Haerter auffüllen und messen
    lcd.setCursor(0, 0);
    lcd.print("Harz&Haert auff.");
    lcd.setCursor(0, 1);
    lcd.print("...");
    if (GewichtHB >= 100 && GewichtHARZ >= 100) {
      lcd.setCursor(0, 3);
      lcd.print("done");
      delay(3000);
      lcd.clear();
      status++;
    }
  }
  if (status == 4) {  //Harz vorfoerdern manuell
    lcd.setCursor(0, 0);
    lcd.print("Harz vorfoerdern");
    lcd.setCursor(0, 1);
    lcd.print("adjust then b1");
    analogWrite(pump1, FoerderHarz);
  }
  if (status == 5) {  //Haerter vorfoerdern manuell
    analogWrite(pump1, 0);
    lcd.setCursor(0, 0);
    lcd.print("Haerter vorfoerd");
    lcd.setCursor(0, 1);
    lcd.print("adjust then b1");
    analogWrite(pump2, FoerderHaert);
  }
  if (status == 6) {  //Tare alle Zellen
    analogWrite(pump1, 0);
    analogWrite(pump2, 0);
    lcd.setCursor(0, 0);
    lcd.print("System tare...");
    if (currentMillis - previousMillisTare < intervalTare) {
      LoadCell_1.tareNoDelay();
      LoadCell_2.tareNoDelay();
      LoadCell_3.tareNoDelay();
    }
    if (currentMillis - previousMillisTare >= intervalTare && currentMillis - previousMillisTare < intervalTare2) {
      lcd.setCursor(0, 1);
      lcd.print("done");
    }
    if (currentMillis - previousMillisTare >= intervalTare2 && currentMillis - previousMillisTare < intervalTare3) {
      lcd.clear();
      status++;  //AUTOWECHSEL
    }
    if (currentMillis >= intervalTare3 && istGesetzt2 == false) {  //Millis-Wert einmalig speichern, danach wird "istGesetzt2" nurnoch =true bleiben
      previousMillisTare = millis();
      istGesetzt2 = true;
    }
  }
  if (status == 7) {  //Harzbad UG einstellen über Poti (Wert_filterUG)
    lcd.setCursor(0, 0);
    lcd.print("Harzbad Untergr.");
    lcd.setCursor(0, 1);
    lcd.print(Wert_filterUG);
    lcd.print(" g");
    Serial.println(Wert_filterUG);
    if (Wert_filterUG < 1000) {
      lcd.setCursor(5, 1);
      lcd.print(" ");
    }
    if (Wert_filterUG < 100) {
      lcd.setCursor(4, 1);
      lcd.print(" ");
    }
    if (Wert_filterUG < 10) {
      lcd.setCursor(3, 1);
      lcd.print(" ");
    }
  }
  if (status == 8) {  //Harzbad UG speichern
    float UG = Wert_filterUG;
    EEPROM.put(UG_address, UG);  //UG auf UG-address ins EEPROM speichern
    delay(1000);
    Serial.print("UG saved");
    lcd.print("Untergr. saved");
    lcd.setCursor(0, 1);
    lcd.print("set to: ");
    lcd.print(UG, 0);
    lcd.print(" g");
    delay(3000);
    lcd.clear();
    status++;  //AUTOWECHSEL
  }
  if (status == 9) {  //Harzbad OG einstellen über Poti (Wert_filterOG)
    lcd.setCursor(0, 0);
    lcd.print("Harzbad Obergr.");
    lcd.setCursor(0, 1);
    lcd.print(Wert_filterOG);
    lcd.print(" g");
    if (Wert_filterOG < 1000) {
      lcd.setCursor(5, 1);
      lcd.print(" ");
    }
    if (Wert_filterOG < 100) {
      lcd.setCursor(4, 1);
      lcd.print(" ");
    }
  }
  if (status == 10) {  //Harzbad OG speichern
    float OG = Wert_filterOG;
    EEPROM.put(OG_address, OG);  //OG auf OG-address ins EEPROM speichern
    delay(1000);
    Serial.print("OG saved");
    lcd.print("Obergr. saved");
    lcd.setCursor(0, 1);
    lcd.print("set to: ");
    lcd.print(OG, 0);
    lcd.print(" g");
    delay(3000);
    lcd.clear();
    status++;  //AUTOWECHSEL
  }
  if (status == 11) {  //Anteil Harz einstellen über Poti (AntHarz)
    lcd.setCursor(0, 0);
    lcd.print("Ant. Harz(vol):");
    lcd.setCursor(0, 1);
    lcd.print(AntHarz);
    if (AntHarz < 100) {
      lcd.setCursor(2, 1);
      lcd.write(" ");
    }
    if (AntHarz < 10) {
      lcd.setCursor(1, 1);
      lcd.write(" ");
    }
    delay(200);
  }
  if (status == 12) {  //Anteil Harz in EEPROM speichern
    float WertHarz = AntHarz;
    EEPROM.put(WertHarz_address, WertHarz);
    Serial.print("EEPROM changed");
    status++;
  }
  if (status == 13) {                                   //gesp. Anteil Harz anzeigen
    WertHarz = EEPROM.get(WertHarz_address, WertHarz);  //aus EEPROM holen
    lcd.print("Ant. Harz saved");
    lcd.setCursor(0, 1);
    lcd.print("= ");
    lcd.print(WertHarz, 0);
    lcd.print(" (vol.)");
    delay(4000);
    lcd.clear();
    status++;  //AUTOWECHSEL
  }
  if (status == 14) {  //Anteil Haert einstellen über Poti (AntHaert)
    lcd.setCursor(0, 0);
    lcd.print("Ant. Haert(vol):");
    lcd.setCursor(0, 1);
    lcd.print(AntHaert);
    if (AntHaert < 100) {
      lcd.setCursor(2, 1);
      lcd.write(" ");
    }
    if (AntHaert < 10) {
      lcd.setCursor(1, 1);
      lcd.write(" ");
    }
    delay(200);
  }
  if (status == 15) {  //Anteil Haert im EEPROM speichern
    float WertHaert = AntHaert;
    EEPROM.put(WertHaert_address, WertHaert);
    Serial.print("EEPROM changed");
    status++;  //AUTOWECHSEL
  }
  if (status == 16) {  //gesp. Anteil Haert anzeigen
    WertHaert = EEPROM.get(WertHaert_address, WertHaert);
    lcd.print("Ant. Haert saved");  //aus EEPROM holen
    lcd.setCursor(0, 1);
    lcd.print("= ");
    lcd.print(WertHaert, 0);
    lcd.print(" (vol.)");
    delay(4000);
    lcd.clear();
    status++;  //AUTOWECHSEL
  }
  if (status == 17) {  //gesp. Harz-Haert Verhältnis anzeigen
    lcd.setCursor(0, 0);
    lcd.print("gesp Harz-Haert:");
    lcd.setCursor(0, 1);
    lcd.print(WertHarz, 0);
    lcd.print(" : ");
    lcd.print(WertHaert, 0);
    lcd.print(" (vol.)");
    delay(4000);
    lcd.clear();
    status++;  //AUTOWECHSEL
  }
  if (status == 18) {                                      //Berechnung der Pumpenverhältnisse; 3 mögliche Varianten
    WertHarz = EEPROM.get(WertHarz_address, WertHarz);     //aus EEPROM holen
    WertHaert = EEPROM.get(WertHaert_address, WertHaert);  //""
    if (WertHarz > WertHaert) {                            //Harz/Haert auf 100/x herunterrechnen; später werden in diesem Verhältnis die Pumpen angesteuert
      PumpHarz = 100;
      PumpHaert = (100 * WertHaert) / WertHarz;
      EEPROM.put(PumpHarz_address, PumpHarz);  //in EEPROM speichern
      EEPROM.put(PumpHaert_address, PumpHaert);
      status++;  //AUTOWECHSEL
    }
    if (WertHarz < WertHaert) {  //Haert/Harz auf 100/x herunterrechnen; später werden in diesem Verhältnis die Pumpen angesteuert
      PumpHarz = (100 * WertHarz) / WertHaert;
      PumpHaert = 100;
      EEPROM.put(PumpHarz_address, PumpHarz);  //in EEPROM speichern
      EEPROM.put(PumpHaert_address, PumpHaert);
      status++;  //AUTOWECHSEL
    }
    if (WertHarz == WertHaert) {
      PumpHarz = 100;  //beides auf 100% festgelegt; später werden in diesem Verhältnis die Pumpen angesteuert
      PumpHaert = 100;
      EEPROM.put(PumpHarz_address, PumpHarz);  //in EEPROM speichern
      EEPROM.put(PumpHaert_address, PumpHaert);
      status++;  //AUTOWECHSEL
    }
  }
  if (status == 19) {  //start process
    lcd.setCursor(0, 0);
    lcd.print("start process:");
    lcd.setCursor(0, 1);
    lcd.print("press button1");
  }

  if (status == 20 || status == 21) {  //Auffüllungsprozess beginnt, dauerhafte Überwachung des Harzbadfüllstandes und Nachförderung wenn gebraucht
    UG = EEPROM.get(UG_address, UG);   //Werte aus EEPROM holen
    OG = EEPROM.get(OG_address, OG);
    PumpHarz = EEPROM.get(PumpHarz_address, PumpHarz);
    PumpHaert = EEPROM.get(PumpHaert_address, PumpHaert);
    //Zustand 1 Untergrenze
    if (GewichtHB < UG && GewichtHB < OG && Auffuellvorgang == false) {  //Füllstand unterhalb Untergrenze; Pumpen fördern
      pumprate1 = PumpHarz * 2.55;
      pumprate2 = PumpHaert * 2.55;
      analogWrite(pump1, pumprate1);
      analogWrite(pump2, pumprate2);
      Auffuellvorgang = true;
    }
    //Zustand 2 Auffüllen
    if (GewichtHB >= UG && GewichtHB < OG && Auffuellvorgang == true) {  //Füllstand zwischen UG und OG; Pumpen fördern
      pumprate1 = PumpHarz * 2.55;
      pumprate2 = PumpHaert * 2.55;
      analogWrite(pump1, pumprate1);
      analogWrite(pump2, pumprate2);
      Auffuellvorgang = false;
    }
    //Zustand 3 Obergrenze
    if (GewichtHB > UG && GewichtHB >= OG && Auffuellvorgang == false) {  //Füllstand bei OG; Pumpen hören auf zu fördern; Füllstand sinkt wieder
      pumprate1 = 0;
      pumprate2 = 0;
      analogWrite(pump1, pumprate1);
      analogWrite(pump2, pumprate2);
      Auffuellvorgang = false;
    }
  }

  //////////////////////////////////////////////////////////////// Beginn extra-Programm

  if (extra == 1 && neu == 0) {  //Wechsel mit Button2; UG ändern
    lcd.setCursor(0, 0);
    lcd.print("UG neu?");
    lcd.setCursor(0, 1);
    lcd.print("press button1");
  }
  if (extra == 1 && neu == 1) {  //Harzbad UG neu einstellen
    lcd.setCursor(0, 0);
    lcd.print("Harzbad Untergr.");
    lcd.setCursor(0, 1);
    lcd.print(Wert_filterUG);
    lcd.print(" g");
    if (Wert_filterUG < 1000) {
      lcd.setCursor(5, 1);
      lcd.print(" ");
    }
    if (Wert_filterUG < 100) {
      lcd.setCursor(4, 1);
      lcd.print(" ");
    }
    if (Wert_filterUG < 10) {
      lcd.setCursor(3, 1);
      lcd.print(" ");
    }
  }
  if (extra == 1 && neu == 2) {  //Harzbad UG neu speichern
    float UG = Wert_filterUG;
    EEPROM.put(UG_address, UG);
    delay(1000);
    Serial.print("UG saved");
    lcd.print("Untergr. saved");
    lcd.setCursor(0, 1);
    lcd.print("set to: ");
    lcd.print(UG, 0);
    lcd.print(" g");
    delay(3000);
    lcd.clear();
    neu = 0;  //AUTOWECHSEL
  }

  if (extra == 2 && neu == 0) {  //OG ändern
    lcd.setCursor(0, 0);
    lcd.print("OG neu?");
    lcd.setCursor(0, 1);
    lcd.print("press button1");
  }
  if (extra == 2 && neu == 1) {  //Harzbad OG neu einstellen
    lcd.setCursor(0, 0);
    lcd.print("Harzbad Obergr.");
    lcd.setCursor(0, 1);
    lcd.print(Wert_filterOG);
    lcd.print(" g");
    if (Wert_filterOG < 1000) {
      lcd.setCursor(5, 1);
      lcd.print(" ");
    }
    if (Wert_filterOG < 100) {
      lcd.setCursor(4, 1);
      lcd.print(" ");
    }
  }
  if (extra == 2 && neu == 2) {  //Harzbad OG neu speichern
    float OG = Wert_filterOG;
    EEPROM.put(OG_address, OG);
    delay(1000);
    Serial.print("OG saved");
    lcd.print("Obergr. saved");
    lcd.setCursor(0, 1);
    lcd.print("set to: ");
    lcd.print(OG, 0);
    lcd.print(" g");
    delay(3000);
    lcd.clear();
    neu = 0;  //AUTOWECHSEL
  }

  if (extra == 3 && neu == 0) {  //Mischverh ändern
    lcd.setCursor(0, 0);
    lcd.print("Mischverh neu?");
    lcd.setCursor(0, 1);
    lcd.print("press button1");
  }
  if (extra == 3 && neu == 1) {  //Anteil Harz einstellen neu
    lcd.setCursor(0, 0);
    lcd.print("Ant. Harz(vol):");
    lcd.setCursor(0, 1);
    lcd.print(AntHarz);
    if (AntHarz < 100) {
      lcd.setCursor(2, 1);
      lcd.write(" ");
    }
    if (AntHarz < 10) {
      lcd.setCursor(1, 1);
      lcd.write(" ");
    }
    delay(200);
  }
  if (extra == 3 && neu == 2) {  //Anteil Harz in EEPROM speichern  neu
    float WertHarz = AntHarz;
    EEPROM.put(WertHarz_address, WertHarz);
    Serial.print("EEPROM changed");
    neu++;
  }
  if (extra == 3 && neu == 3) {  //gesp. Anteil Harz anzeigen neu
    WertHarz = EEPROM.get(WertHarz_address, WertHarz);
    lcd.print("Ant. Harz saved");
    lcd.setCursor(0, 1);
    lcd.print("= ");
    lcd.print(WertHarz, 0);
    lcd.print(" (vol.)");
    delay(4000);
    lcd.clear();
    neu++;  //AUTOWECHSEL
  }
  if (extra == 3 && neu == 4) {  //Anteil Haert einstellen  neu
    lcd.setCursor(0, 0);
    lcd.print("Ant. Haert(vol):");
    lcd.setCursor(0, 1);
    lcd.print(AntHaert);
    if (AntHaert < 100) {
      lcd.setCursor(2, 1);
      lcd.write(" ");
    }
    if (AntHaert < 10) {
      lcd.setCursor(1, 1);
      lcd.write(" ");
    }
    delay(200);
  }
  if (extra == 3 && neu == 5) {  //Anteil Haert im EEPROM speichern neu
    float WertHaert = AntHaert;
    EEPROM.put(WertHaert_address, WertHaert);
    Serial.print("EEPROM changed");
    neu++;  //AUTOWECHSEL
  }
  if (extra == 3 && neu == 6) {  //gesp. Anteil Haert anzeigen  neu
    WertHaert = EEPROM.get(WertHaert_address, WertHaert);
    lcd.print("Ant. Haert saved");
    lcd.setCursor(0, 1);
    lcd.print("= ");
    lcd.print(WertHaert, 0);
    lcd.print(" (vol.)");
    delay(4000);
    lcd.clear();
    neu++;  //AUTOWECHSEL
  }
  if (extra == 3 && neu == 7) {  //gesp. Harz-Haert Verhältnis anzeigen neu
    lcd.setCursor(0, 0);
    lcd.print("gesp Harz-Haert:");
    lcd.setCursor(0, 1);
    lcd.print(WertHarz, 0);
    lcd.print(" : ");
    lcd.print(WertHaert, 0);
    lcd.print(" (vol.)");
    delay(4000);
    lcd.clear();
    neu++;  //AUTOWECHSEL
  }
  if (extra == 3 && neu == 8) {  //Berechnung der Pumpenverhältnisse neu
    WertHarz = EEPROM.get(WertHarz_address, WertHarz);
    WertHaert = EEPROM.get(WertHaert_address, WertHaert);
    if (WertHarz > WertHaert) {
      PumpHarz = 100;
      PumpHaert = (100 * WertHaert) / WertHarz;
      EEPROM.put(PumpHarz_address, PumpHarz);
      EEPROM.put(PumpHaert_address, PumpHaert);
      neu = 0;  //AUTOWECHSEL
    }
    if (WertHarz < WertHaert) {
      PumpHarz = (100 * WertHarz) / WertHaert;
      PumpHaert = 100;
      EEPROM.put(PumpHarz_address, PumpHarz);
      EEPROM.put(PumpHaert_address, PumpHaert);
      neu = 0;  //AUTOWECHSEL
    }
    if (WertHarz == WertHaert) {
      PumpHarz = 100;
      PumpHaert = 100;
      EEPROM.put(PumpHarz_address, PumpHarz);
      EEPROM.put(PumpHaert_address, PumpHaert);
      neu = 0;  //AUTOWECHSEL
    }
  }
  if (extra == 4 && neu == 0) {  //Back to process, verlassen von extra-Modus
    lcd.setCursor(0, 0);
    lcd.print("back to process?");
    lcd.setCursor(0, 1);
    lcd.print("press button2");
  }
  if (extra == 5) {
    extra = 0;
  }

  if (status == 21) {  //Nachfrage vor Ausschalten, ob wirklich beendet werden soll
    pumprate1 = 0;
    pumprate2 = 0;
    analogWrite(pump1, pumprate1);
    analogWrite(pump2, pumprate2);
    lcd.print("PAUSE");
    lcd.setCursor(0, 1);
    lcd.print("back =2, off =1");
  }

  if (status == 22) {  //finish process, Ende Prozess; Pumpen werden ausgeschaltet
    pumprate1 = 0;
    pumprate2 = 0;
    analogWrite(pump1, pumprate1);
    analogWrite(pump2, pumprate2);
    lcd.setCursor(0, 0);
    lcd.print("process finished");
    lcd.setCursor(0, 1);
    lcd.print("disconnect power");
  }


  //get smoothed value from data set; Werte der Wägezellen in den Serial Monitor schreiben
  if ((newDataReady)) {
    if (millis() > t + serialPrintInterval) {
      float a = GewichtHB;
      float b = GewichtHARZ;
      float c = GewichtHAERT;
      Serial.print("Load_cell_1: ");
      Serial.print(a);
      Serial.print("    Load_cell_2: ");
      Serial.print(b);
      Serial.print("    Load_cell_3: ");
      Serial.println(c);
      newDataReady = 0;
      t = millis();
    }
  }

  if (LoadCell_1.getTareStatus() == true) {  //nach ergolgreichem Tare, Bestätigung im Serial Monitor
    Serial.println("Tare load cell 1 complete");
  }
  if (LoadCell_2.getTareStatus() == true) {
    Serial.println("Tare load cell 2 complete");
  }
  if (LoadCell_3.getTareStatus() == true) {
    Serial.println("Tare load cell 3 complete");
  }
}

LG

Schade.
Ich schau nachher aber mal drauf.

Alter Falter.... Ich hab ja schon einiges an Code zerlegt, aber der ist wirklich harter Tobak.
Das muss ich auf einem großen Monitor machen; da geht nix auf dem Netbook unterwegs. Das kürz ich erstmal runter, damit man die Abhängigkeiten sieht.
Ich denke, dann geht auch die Auflösung, wo er rechnen muss.
Was in jedem Fall weg muss, ist das neuInit der Variablen im loop bei jedem Umlauf und das beschreiben des Display bei jedem Umlauf, wenn sich der Wert nicht geändert hat.

Mal sehen, was mir dazu einfällt...