Wägezelle HX711; Änderung bei Rückgabewert verstehen

Hallo zusammen,

ich benötige nochmal Ideen zur Fehlersuche. Mit einem Arduino Pro Mini lese ich eine Wägezelle HX711 aus und gebe den Wert seriell aus. Nichts besonderes, nur dass ich kein Tara verwende, um auch nach einem Neustart des Pro Mini weiter messen zu können. Das hat seit langem funktioniert. Jetzt habe ich den Code erweitert, um die analogen Messwerte von Pin A6 und A7 mit auszuwerten. Der Code für die Messzelle ist nicht betroffen. Zum Programmieren habe ich den Pro Mini auch von der Wägezelle getrennt. Seit dem Wiederanschließen liefert er jedoch andere Werte. Konkret scheint das Minuszeichen zu fehlen.

vorher: -884.3
nachher: 881.6

Bisherige Lösungsversuche:
Kabel an der Wägezelle wurden nicht verändert.
Am Pro Mini ist ein Vertauschen der Kabel ausgeschlossen, da die Übertragung grundsätzlich klappt.
Da ich am Code keine Ursache erkennen konnte, habe ich den alten Code wieder eingespielt. Das Ergebnis bleibt aber ein positiver Messwert, d.h. das Minuszeichen fehlt weiter.

Es wäre kein Problem, die Auswertelogik an die neuen Werte anzupassen, aber ich würde gerne den Grund der Änderung verstehen.
Was habe ich übersehen, oder wo einen falschen Schluss gezogen?

Viele Grüße
Frank

#include <HX711.h>                                    // Wägezelle
#include <avr/wdt.h>                                  // für Watchdog

#define One_Wire_Pin 5                                // OneWireBus
const byte OElPin = 12;                               // für Ölalarm Tankraumüberwachung
const byte WasserPinTR = 14;                          // =A0 für Wasseralarm Tankraumüberwachung
const int LOADCELL_DOUT_PIN = A1;
const int LOADCELL_SCK_PIN = A2;
HX711 scale;
const byte WasserPinK = 17;                            // =A3 für Wasseralarm Küche

// Kommunikation
// =============
int sGID;                                             // Serial übertragenene GeräteID
char sKB;                                             // Serial übertragenenr Kennbuchstabe
float sPara;                                          // Serial übertragenenr Parameterwert
String str;                                           // Serial Input-Buffer String
unsigned long lextWatchdogStreicheln = 0;             // letztes Streicheln des externen Watchdogs

// Neustart nach Verbindungsabbruch
// ================================
unsigned long lWatchdogEingang = 0;                   // letzte Nachricht von außen

// Wasseralarm / Ölalarm
// =====================
// Wassersensor ohne Kontakt Werte um 0; bei Wasser analog Werte um 780 könnte damit auch an einem digitalen Eingang hängen
const unsigned long MessintervallWasser = 300000;      // Millisekunden Zeit zwischen den Messungen, wenn das letzte Messen negativ war 300000 -> alle 5 Min
unsigned long lWassermessung = 0;                    // letzte Messung
unsigned int WasseralarmCountTR;                     // Zähler Wasseralarm Tankraum
unsigned int WasseralarmCountK;                      // Zähler Wasseralarm Küche
unsigned int OElalarmCount;                          // Zähler OElalarm
unsigned int refCount;                               // ReferenzZähler Wasseralarm
bool boolZusWasser = false;                          // Zusätzliche Auswertung

// Tankfüllhöhe
// ============
unsigned long MessintervallOElStand = 21600000;   // Millisekunden Zeit zwischen den Messungen 21600000 -> alle 6 Stunden
unsigned long lOElStandmessung = 0;                     // letzte Messung
bool boolZusTank = false;                               // Zusätzliche Auswertung

// Setup
// =====
void setup()
{
  wdt_disable();

  // Aktiviere Watchdog mit 8s Zeitkonstante
  // =======================================
  wdt_enable(WDTO_8S);

  pinMode(LED_BUILTIN, OUTPUT);

  Serial.begin(9600); 

  pinMode(OElPin, INPUT);
  pinMode(WasserPinTR, INPUT);
  pinMode(WasserPinK, INPUT);

  // Tankfüllhöhe
  // ============
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  Serial.print(F("Scale: "));
  Serial.println(scale.get_scale());
  scale.set_scale(2106.75982f);
  Serial.println(scale.get_scale());
  scale.power_down();                       
}

// Loop
// ====
void loop()
{
  // internen Watchdog Streicheln
  wdt_reset();

  // externen Watchdog Streicheln
  if ((millis() - lextWatchdogStreicheln) > 30000) {
    lextWatchdogStreicheln = millis();
    Serial.println(F("<wdt>.</wdt>"));
  }

  // Neustart nach Verbindungsabbruch
  // ================================
  if ((millis() - lWatchdogEingang) > 900000) {
    // 15 keine Kommunikation mehr -> Neustarten
    Serial.println(F("Neustart nach Verbindungsabbruch"));
    // nach 8S beisst der Watchdog zu
    delay(9000);
  }


  // Wasseralarm / Ölalarm
  // =====================
  if (((millis() - lWassermessung) > MessintervallWasser) or (OElalarmCount > 0) or (WasseralarmCountTR > 0) or (WasseralarmCountK > 0) or boolZusWasser)               // Zeit für neue Messung, oder eine der letzten Messungen positiv
  {
    lWassermessung = millis();
    if (digitalRead(OElPin) == HIGH)
    {
      OElalarmCount ++;
    }

    if (digitalRead(WasserPinTR) == HIGH)
    {
      WasseralarmCountTR ++;
    }
    if (digitalRead(WasserPinK) == HIGH)
    {
      WasseralarmCountK ++;
    }

    refCount ++;


    if (refCount > 30)                                    // Auswertung nach x Messungen
    {
      if (OElalarmCount > 15)                             // mindestens 15 von 30 Messungen positiv
      {
        if (WasseralarmCountTR > 15)                        // mindestens 15 von 30 Messungen positiv
        {
          Serial.println(F("<Wasseralarm>Tankraum</Wasseralarm>"));
        }
        else
        {
          Serial.println(F("<OElalarm>Tankraum</OElalarm>"));
        }
        Serial.print(F("OElalarmCount: "));
        Serial.print(OElalarmCount);
        Serial.print(F("   WasseralarmCountTR: "));
        Serial.println(WasseralarmCountTR);
      }
      else
      {
        if (WasseralarmCountTR > 15)                          // mindestens 15 von 30 Messungen positiv
        {
          Serial.println(F("<Wasseralarm>TankraumNurWassersensor</Wasseralarm>"));
          Serial.print(F("OElalarmCount: "));
          Serial.print(OElalarmCount);
          Serial.print(F("   WasseralarmCountTR: "));
          Serial.println(WasseralarmCountTR);

        }
      }

      if (WasseralarmCountK > 15)                          // mindestens 15 von 30 Messungen positiv
      {
        Serial.println(F("<Wasseralarm>Kueche</Wasseralarm>"));
        Serial.print(F("WasseralarmCountK: "));
        Serial.println(WasseralarmCountK);
      }

      if (boolZusWasser)
      {
        Serial.print(F("OElalarmCount: "));
        Serial.print(OElalarmCount);
        Serial.print(F("   WasseralarmCountTR: "));
        Serial.println(WasseralarmCountTR);
        Serial.print(F("   WasseralarmCountK: "));
        Serial.println(WasseralarmCountK);
      }

      OElalarmCount = 0;                                     // Zähler zurücksetzen
      WasseralarmCountTR = 0;
      WasseralarmCountK = 0;
      refCount = 0;
      boolZusWasser = false;
    }
  }

  // Tankfüllhöhe
  // ============
  if (((millis() - lOElStandmessung) > MessintervallOElStand) or boolZusTank)                // Zeit für neue Messung
  {
    lOElStandmessung = millis();
    scale.power_up();                              // Wecken
    if (scale.wait_ready_timeout(1000)) {
      Serial.print(F("<OElstand>"));
      Serial.print(scale.get_units(30), 1);         // aus 30 Messungen mitteln
      Serial.println(F("</OElstand>"));
    } else {
      Serial.println("HX711 not found.");
    }
    scale.power_down();                           // Stromsparen
    boolZusTank = false;
  }

}

An welcher Stelle im Programm werden diese Werte erzeugt?
An welcher Stelle im Programm werden diese Werte ausgegeben?

Hast du eine Kopie der Binärdatei die die Minuswerte liefert?
Gibt es mehrere ältere Versionen die du auch ausprobieren könntest?
Hast du mit den verschiedenen Source-code-Versionen Inhaltsvergleiche von einem Programm machen lassen?
Also eine Software (genau nicht menschliche Augen)
die Buchstabe für Buchstabe vergleichen?

Hast du eine zweite Wägezelle, einen zweiten HX711 mit dem man Über kreuz testen kann?

vgs
Wenn du dir sicher bist, dass es keine Hardware-Ursache hat dann muss es ja eine Software-Ursache haben.

das heißt dann aber auch dass sowohl dein alter Code und dein neuer Code das gleiche ausgeben. Daher gehe ich davon aus dass du

  • wenn auch unwissentlich - etwas an deiner Hardware geändert hast
  • oder etwas an deiner eingebundenen .h

wegen zweiteres schreibt man sich hinter einem include am besten immer die genaue Version die man verwendet hat um so auf eine Stand zurückgehen zu können der mal funktioniert hat.

Hallo StefanL38,

An welcher Stelle im Programm werden diese Werte erzeugt?
An welcher Stelle im Programm werden diese Werte ausgegeben?

in einer Zeile:

Serial.print(scale.get_units(30), 1); // aus 30 Messungen mitteln

Hast du eine Kopie der Binärdatei die die Minuswerte liefert?

Dazu müsste ich mal herausfinden, wo die IDE die Dateien zwischenspeichert, und ob die da noch liegen. Ich habe bisher immer direkt aus der IDE hochgeladen und die Binärdateien nicht händisch gesichert. Habe nur auf den Code geachtet.

Gibt es mehrere ältere Versionen die du auch ausprobieren könntest?

Ich könnte ein noch älteres Backup heraussuchen, aber ich kann anhand der Datumsangaben nachvollziehen, dass der alte Code sicher alt genug ist, um der zu sein, der in der alten Fassung verwendet wurde. Habe das auch schon mit zwei Backupständen gemacht.

Hast du mit den verschiedenen Source-code-Versionen Inhaltsvergleiche von einem Programm machen lassen?
Also eine Software (genau nicht menschliche Augen)
die Buchstabe für Buchstabe vergleichen?

Nein, aber der Code aus dem Backup liefert jetzt auch die Werte ohne Minuszeichen, deshalb fehlt mir eine Version, die jetzt noch die Rückmeldung mit dem Minuszeichen ausgibt.

Hast du eine zweite Wägezelle, einen zweiten HX711 mit dem man Über kreuz testen kann?

Das kann ich noch versuchen. Hatte ich bisher nicht gemacht, da er Werte liefert, die im normalen Bereich liegen und die Verkabelung sich hier nicht geändert haben kann. Dazu müsste man in den Tankraum klettern.

Wenn du dir sicher bist, dass es keine Hardware-Ursache hat dann muss es ja eine Software-Ursache haben.

Ich kam ja zum Ergebnis, beides auszuschließen, deshalb setze ich noch viele Hoffnungen auf noiasca's Ansatz oder dass es noch weitere Möglichkeiten gibt, die ich übersehen habe.

Vielen Dank für deine Anregungen.

Hallo noiasca.

das heißt dann aber auch dass sowohl dein alter Code und dein neuer Code das gleiche ausgeben.

Korrekt.

Daher gehe ich davon aus dass du
wenn auch unwissentlich - etwas an deiner Hardware geändert hast
oder etwas an deiner eingebundenen .h

Unwissentliche Änderung der Hardware, ja, aber ich wüsste nicht, wie es gehen soll. Stromversorgung falsch würde keine Messung ermöglichen. Bleiben noch Daten und Taktsignal. Vertauschung oder an anderem Pin würde keine Werte liefern. Deshalb fällt mir nicht ein, was falsch sein kann. Ich würde verstehen, wenn die Kabel der Wägezelle zum HX711 verdreht wurden, aber die sind in einem separaten Tankraum und damit ist die Änderung ausgeschlossen.

wegen zweiteres schreibt man sich hinter einem include am besten immer die genaue Version die man verwendet hat um so auf eine Stand zurückgehen zu können der mal funktioniert hat.

Guter Tipp, versuche ich ab jetzt zu beachten.

Dann bleibt mir wohl nur, die Ausgabelogik an die neue Situation anzupassen, und bin bei einer neuen Änderung besser gerüstet.

Vielen Dank für die Anregungen.