HX711 basierte Waage

Über den Beitrag

Mit einem HX711 Modul und einer Wägezelle ist es kinderleicht, eine erstaunlich exakte Waage zu bauen. In diesem Beitrag möchte ich zeigen wie das prinzipiell funktioniert.  

Mein Ziel war es, die gleiche Funktionalität wie die meiner digitalen Küchenwaage zu erreichen: 

  • Ausgabe des Gewichtes auf einem Display
  • Nur ein Knopf zum Anschalten und für Tara
  • Automatisches Ausschalten nach einer bestimmten Zeit

Der Beitrag ist folgendermaßen gegliedert:

Was ihr braucht

Typisches Set aus Wägezelle und HX711 Modul
Typisches Set aus Wägezelle und HX711 Modul

Zum Bau der Waage benötigt ihr eine Wägezelle und ein HX711 Modul. Beides könnt ihr im Set kaufen. Wenn ihr z.B. bei Amazon oder eBay nach „HX711 Wägezelle“ sucht, bekommt ihr Dutzende von Angeboten für wenige Euro. Wählt eine Wägezelle mit dem für euch passenden Gewichtsbereich. Ich habe mir eine 2 kg Zelle besorgt. 

Was ihr sonst benötigt, kann ich euch nicht in einer konkreten Einkaufsliste vorgeben, da es zu sehr davon abhängt, wie ihr eure Waage gestalten wollt. Lest am besten erstmal weiter und entscheidet dann selbst.

Das Messprinzip

Die Wägezelle wird durch das Gewicht der zu wiegenden Last leicht gebogen. Unter dem weißen Kleber sitzen vier als Wheatstone Brücke angeordnete Dehnungsmessstreifen, deren Widerstand sich mit dem Dehnungsgrad, also mit dem Gewicht, ändert. Der Widerstand wird über den Spannungsabfall bestimmt und der wiederum mit einem A/D-Wandler ausgewertet. Wie das genau funktioniert, steht in meinem Beitrag über Dehnungsmessstreifen.

Die Änderung des Spannungsabfalls mit steigendem Gewicht ist recht gering. Ich habe wenige Millivolt pro Kilogramm gemessen. Der A/D-Wandler eines Arduino UNO bzw. eines ATmega328P ist dafür nicht geeignet. Der HX711 hingegen besitzt eine beeindruckende Auflösung von 24 Bit (= 16.777.216 Stufen).

Der HX711 selbst ist dabei eigentlich nur der sechzehnbeinige Chip auf dem Modul. Da er noch ein paar Elemente zur Beschaltung benötigt, bietet es sich an, zum Modul zu greifen. Wenn ihr euch trotzdem auch für die technischen Details des HX711 interessiert, dann findet ihr hier ein Datenblatt.

Verbauen der Wägezelle

Um ein bisschen Heimwerkern kommt ihr nicht herum. Die Wägezelle muss so eingebaut werden, dass sie sich unter Gewicht auch biegen kann. Ich habe dazu einfach ein Brett genommen und zwei gleich große Stücke abgesägt. Zwischen die Bretter kam die Wägezelle mit Abstandshaltern.

Die Wägezelle mit Abstandhaltern zwischen zwei Brettstücken
Die Wägezelle mit Abstandhaltern zwischen zwei Brettstücken

Durch das untere Brett habe ich zwei Löcher gebohrt und die Wägezelle mit zwei M5 Schrauben fixiert. Damit die Waage nicht direkt mit dem Brett aufliegt, habe ich ihr noch ein paar Füße spendiert: 

Unterseite der HX711 Waage
Unterseite der Waage

Für die andere Seite sind eigentlich M4 Schrauben vorgesehen. Um eine glatte Auflagefläche für das Wägegut zu behalten, wollte ich das obere Brett aber nicht durchbohren. Deswegen habe ich einfach ein paar Holzschrauben genommen.  

Von mir gewählte Schrauben
Von mir gewählte Schrauben

Die Kabel der Wägezelle werden folgendermaßen mit dem Modul verbunden:

  • Rot an E+
  • Schwarz an E-
  • Weiß an A-
  • Grün an A+
Anschluss der Wägezelle an das HX711 Modul
Anschluss der Wägezelle an das HX711 Modul

So sieht dann der Zwischenstand aus:

Die HX711 basierte Waage im Rohzustand
Die Waage im Rohzustand

Verwendung der HX711 ADC Bibliothek

Zur Ansteuerung des Moduls habe ich die HX711 ADC Bibliothek von Olav Kallhovd verwendet. Ihr könnt sie hier direkt von Github herunterladen oder ihr installiert sie über die Bibliotheksverwaltung der Arduino IDE. 

HX711 Grundschaltung

Minimumbeschaltung des HX711 am Arduino UNO
Minimumbeschaltung des HX711 am Arduino UNO

Das Modul kann mit Spannungen zwischen 2.6 und 5.5 Volt betrieben werden. Das Modul ist mit < 1.5 mA Stromverbrauch recht sparsam. Der DT-Pin wird mit dem Arduino Pin 4 verbunden, SCK kommt an Pin 5. Die Pins können auch geändert werden. 

Kalibrierung der Waage

Zur Kalibrierung braucht ihr einen Gegenstand mit bekanntem Gewicht. Das Gewicht sollte auf das Gramm genau bekannt und nicht zu klein sein. Am besten nehmt ihr eine zweite Waage zur Hilfe. 

Das Schöne an der hier verwendeten Bibliothek ist, dass sie euch das Leben – oder zumindest die Waagenkalibrierung – sehr einfach macht. Wählt aus den Beispielen der Bibliothek den Sketch „Calibration.ino“. Ich habe ihn hier unverändert abgedruckt:

/*
   -------------------------------------------------------------------------------------
   HX711_ADC
   Arduino library for HX711 24-Bit Analog-to-Digital Converter for Weight Scales
   Olav Kallhovd sept2017
   -------------------------------------------------------------------------------------
*/

/*
   This example file shows how to calibrate the load cell and optionally store the calibration
   value in EEPROM, and also how to change the value manually.
   The result value can then later be included in your project sketch or fetched from EEPROM.

   To implement calibration in your project sketch the simplified procedure is as follow:
       LoadCell.tare();
       //place known mass
       LoadCell.refreshDataSet();
       float newCalibrationValue = LoadCell.getNewCalibration(known_mass);
*/

#include <HX711_ADC.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif

//pins:
const int HX711_dout = 4; //mcu > HX711 dout pin
const int HX711_sck = 5; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);

const int calVal_eepromAdress = 0;
unsigned long t = 0;

void setup() {
  Serial.begin(57600); delay(10);
  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  //LoadCell.setReverseOutput(); //uncomment to turn a negative output value to positive
  unsigned long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = true; //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag() || LoadCell.getSignalTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    LoadCell.setCalFactor(1.0); // user set calibration value (float), initial value 1.0 may be used for this sketch
    Serial.println("Startup is complete");
  }
  while (!LoadCell.update());
  calibrate(); //start calibration procedure
}

void loop() {
  static boolean newDataReady = 0;
  const int serialPrintInterval = 0; //increase value to slow down serial print activity

  // check for new data/start next conversion:
  if (LoadCell.update()) newDataReady = true;

  // get smoothed value from the dataset:
  if (newDataReady) {
    if (millis() > t + serialPrintInterval) {
      float i = LoadCell.getData();
      Serial.print("Load_cell output val: ");
      Serial.println(i);
      newDataReady = 0;
      t = millis();
    }
  }

  // receive command from serial terminal
  if (Serial.available() > 0) {
    char inByte = Serial.read();
    if (inByte == 't') LoadCell.tareNoDelay(); //tare
    else if (inByte == 'r') calibrate(); //calibrate
    else if (inByte == 'c') changeSavedCalFactor(); //edit calibration value manually
  }

  // check if last tare operation is complete
  if (LoadCell.getTareStatus() == true) {
    Serial.println("Tare complete");
  }

}

void calibrate() {
  Serial.println("***");
  Serial.println("Start calibration:");
  Serial.println("Place the load cell an a level stable surface.");
  Serial.println("Remove any load applied to the load cell.");
  Serial.println("Send 't' from serial monitor to set the tare offset.");

  boolean _resume = false;
  while (_resume == false) {
    LoadCell.update();
    if (Serial.available() > 0) {
      if (Serial.available() > 0) {
        char inByte = Serial.read();
        if (inByte == 't') LoadCell.tareNoDelay();
      }
    }
    if (LoadCell.getTareStatus() == true) {
      Serial.println("Tare complete");
      _resume = true;
    }
  }

  Serial.println("Now, place your known mass on the loadcell.");
  Serial.println("Then send the weight of this mass (i.e. 100.0) from serial monitor.");

  float known_mass = 0;
  _resume = false;
  while (_resume == false) {
    LoadCell.update();
    if (Serial.available() > 0) {
      known_mass = Serial.parseFloat();
      if (known_mass != 0) {
        Serial.print("Known mass is: ");
        Serial.println(known_mass);
        _resume = true;
      }
    }
  }

  LoadCell.refreshDataSet(); //refresh the dataset to be sure that the known mass is measured correct
  float newCalibrationValue = LoadCell.getNewCalibration(known_mass); //get the new calibration value

  Serial.print("New calibration value has been set to: ");
  Serial.print(newCalibrationValue);
  Serial.println(", use this as calibration value (calFactor) in your project sketch.");
  Serial.print("Save this value to EEPROM adress ");
  Serial.print(calVal_eepromAdress);
  Serial.println("? y/n");

  _resume = false;
  while (_resume == false) {
    if (Serial.available() > 0) {
      char inByte = Serial.read();
      if (inByte == 'y') {
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.begin(512);
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.commit();
#endif
        EEPROM.get(calVal_eepromAdress, newCalibrationValue);
        Serial.print("Value ");
        Serial.print(newCalibrationValue);
        Serial.print(" saved to EEPROM address: ");
        Serial.println(calVal_eepromAdress);
        _resume = true;

      }
      else if (inByte == 'n') {
        Serial.println("Value not saved to EEPROM");
        _resume = true;
      }
    }
  }

  Serial.println("End calibration");
  Serial.println("***");
  Serial.println("To re-calibrate, send 'r' from serial monitor.");
  Serial.println("For manual edit of the calibration value, send 'c' from serial monitor.");
  Serial.println("***");
}

void changeSavedCalFactor() {
  float oldCalibrationValue = LoadCell.getCalFactor();
  boolean _resume = false;
  Serial.println("***");
  Serial.print("Current value is: ");
  Serial.println(oldCalibrationValue);
  Serial.println("Now, send the new value from serial monitor, i.e. 696.0");
  float newCalibrationValue;
  while (_resume == false) {
    if (Serial.available() > 0) {
      newCalibrationValue = Serial.parseFloat();
      if (newCalibrationValue != 0) {
        Serial.print("New calibration value is: ");
        Serial.println(newCalibrationValue);
        LoadCell.setCalFactor(newCalibrationValue);
        _resume = true;
      }
    }
  }
  _resume = false;
  Serial.print("Save this value to EEPROM adress ");
  Serial.print(calVal_eepromAdress);
  Serial.println("? y/n");
  while (_resume == false) {
    if (Serial.available() > 0) {
      char inByte = Serial.read();
      if (inByte == 'y') {
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.begin(512);
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.commit();
#endif
        EEPROM.get(calVal_eepromAdress, newCalibrationValue);
        Serial.print("Value ");
        Serial.print(newCalibrationValue);
        Serial.print(" saved to EEPROM address: ");
        Serial.println(calVal_eepromAdress);
        _resume = true;
      }
      else if (inByte == 'n') {
        Serial.println("Value not saved to EEPROM");
        _resume = true;
      }
    }
  }
  Serial.println("End change calibration value");
  Serial.println("***");
}

 

Startet den Sketch und öffnet den seriellen Monitor. Wartet bis folgende Meldung kommt:

Wagenkalibrierung am seriellen Monitor
Wagenkalibrierung am seriellen Monitor, Eingabe des bekannten Gewichtes

Dann nehmt euer Gewicht, legt es auf die Waage, gebt das Gewicht in Gramm ein und drückt Enter oder auf Senden. Notiert euch den „calibration value“ oder lasst ihn ins EEPROM des Arduino UNO schreiben. Dann wird munter das Gewicht ausgespuckt:

Ergebnis der Waagenkalibrierung
Ergebnis der Waagenkalibrierung

Wenn das Gewicht ein wenig driftet, dann wiederholt die Kalibrierung und versucht mal eine längere „stabilisingtime“ (Zeile 145).  

Regelbetrieb am PC
Mein „Eichmaß“

Regelbetrieb der HX711 Waage

Nachdem ihr die Waage kalibriert habt, könnt ihr nun in den Regelbetrieb gehen. Dafür bietet sich der Sketch „Read_1x_load_cell.ino“ an, zumindest als Grundlage. Ihr müsst lediglich in Zeile 44 euren Kalibrierfaktor eintragen oder – falls ihr ihn im EEPROM habt – Zeile 48 entkommentieren. Ansonsten funktioniert der Sketch „out of the box“. Wenn ihr einen ESP8266 verwendet, müsst ihr zusätzlich noch Zeile 46 entkommentieren.

Für die Tara gebt ihr ein „t“ im seriellen Monitor ein.

/*
   -------------------------------------------------------------------------------------
   HX711_ADC
   Arduino library for HX711 24-Bit Analog-to-Digital Converter for Weight Scales
   Olav Kallhovd sept2017
   -------------------------------------------------------------------------------------
*/

/*
   Settling time (number of samples) and data filtering can be adjusted in the config.h file
   For calibration and storing the calibration value in eeprom, see example file "Calibration.ino"

   The update() function checks for new data and starts the next conversion. In order to acheive maximum effective
   sample rate, update() should be called at least as often as the HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS.
   If you have other time consuming code running (i.e. a graphical LCD), consider calling update() from an interrupt routine,
   see example file "Read_1x_load_cell_interrupt_driven.ino".

   This is an example sketch on how to use this library
*/

#include <HX711_ADC.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif

//pins:
const int HX711_dout = 4; //mcu > HX711 dout pin
const int HX711_sck = 5; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);

const int calVal_eepromAdress = 0;
unsigned long t = 0;

void setup() {
  Serial.begin(57600); delay(10);
  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  //LoadCell.setReverseOutput(); //uncomment to turn a negative output value to positive
  float calibrationValue; // calibration value (see example file "Calibration.ino")
  calibrationValue = 887.24; // uncomment this if you want to set the calibration value in the sketch
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
  //EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom

  unsigned long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = true; //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    Serial.println("Startup is complete");
  }
}

void loop() {
  static boolean newDataReady = 0;
  const int serialPrintInterval = 0; //increase value to slow down serial print activity

  // check for new data/start next conversion:
  if (LoadCell.update()) newDataReady = true;

  // get smoothed value from the dataset:
  if (newDataReady) {
    if (millis() > t + serialPrintInterval) {
      float i = LoadCell.getData();
      Serial.print("Load_cell output val: ");
      Serial.println(i);
      newDataReady = 0;
      t = millis();
    }
  }

  // receive command from serial terminal, send 't' to initiate tare operation:
  if (Serial.available() > 0) {
    char inByte = Serial.read();
    if (inByte == 't') LoadCell.tareNoDelay();
  }

  // check if last tare operation is complete:
  if (LoadCell.getTareStatus() == true) {
    Serial.println("Tare complete");
  }
}

 

Vielleicht wollt ihr beim Einschalten nicht tarieren? Dann ändert in Zeile 48 den Wert für _tare auf false. Ihr bekommt dann einen „Fantasiewert“ als Messergebnis. Schreibt euch diesen Wert auf und zieht ihn von zukünftigen Messergebnissen ab. Damit habt ihr die Tara sozusagen eingefroren. 

Ich habe die HX711 basierte Waage dann gegen meine Küchenwaage getestet… 

Es treten an: meine Küchenwaage...
Es treten an: meine Küchenwaage…
... gegen den HX711 Eigenbau.
… gegen den HX711 Eigenbau.

… und die Ergebnisse stimmten aufs Gramm!

Ausgabe über ein OLED-Display

Um die Waage vom PC unabhängig zu machen, braucht ihr ein Ausgabemedium. Ich habe dazu ein kleines OLED-Display ausgewählt, das nur wenige Milliampere Strom benötigt. Es wird über I2C mit Hilfe der Bibliotheken Adafruit GFX und Adafruit SSD1306 angesteuert. Falls ihr das auch tun wollt könnt ihr die Bibliotheken von Github über die Links herunterladen oder über die Bibliotheksverwaltung installieren. Auf die Details gehe ich hier nicht ein, denn das würde den Rahmen sprengen. Außerdem wollt ihr ja vielleicht auch ganz andere Displays einsetzen oder Sieben-Segmentanzeigen.

Ausgabe über ein TFT-Display
Ausgabe über ein TFT-Display

Nun noch paar Anmerkungen zum folgenden Sketch. Um das Gewicht anzuzeigen, kommt die Funktion dtostrf(in, min_width, digits_after_decimal, out) zum Einsatz. Sie erlaubt es, aus Float- oder Integer-Werten (in) in eine Zeichenkette (out) zu erzeugen. Der Parameter min_width ist die Mindestbreite und digits_after_decimal gibt die Stellen nach dem Komma an. Eigentlich würde dtostrf() die Variable weight auch direkt verarbeiten. Mein Umweg über die Umformung in einen Integer verhindert aber, dass nach einer Tara die Anzeige ständig zwischen „0“ und „-0“ hin- und herschwankt.

Taramessungen werden über Interrupts an Pin 2 angefordert. Ausgelöst wird der Interrupt über einen Taster. Auf Tasterdruck wird die Variable taraRequest true und dadurch in der loop Schleife eine Taramessung initiiert. Während der Taramessung gibt die Waage ein „Wait“ auf dem Display aus. 

Der Rest des Sketches sollte halbwegs selbsterklärend sein (das behauptet natürlich jeder…). Wenn ihr fragen habt, fragt!

#include <Wire.h>
#include <HX711_ADC.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET -1 // we don't have a reset, but the constructor expects it
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
HX711_ADC LoadCell(4, 5);

byte interruptPin=2;
volatile bool taraRequest = false;

void setup()   {                
  pinMode(interruptPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin), taraEvent, RISING);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x64)
  display.clearDisplay();
  display.setTextSize(4);
  display.setTextColor(WHITE);
  display.setCursor(10,4);
  display.println("Wait");
  display.display();
  LoadCell.begin();
  LoadCell.start(2000); 
  LoadCell.setCalFactor(883.24); 
}


void loop() {
  float weightAsFloat = 0.0;
  static unsigned long t = 0;
  
  LoadCell.update();
  
  if (millis() > t + 250) {
    weightAsFloat = LoadCell.getData();
    displayWeight(weightAsFloat);
    t = millis();  
  }
  if(taraRequest){
    doTara();
    taraRequest = false;
  }
}

void displayWeight(float weight){
  int weightAsInt = int(weight+0.5);
  char weightAsString[6] = {0}; // sign (-) + 4 digits + Null character = 6
  dtostrf(weightAsInt,5,0,weightAsString);
  display.clearDisplay();
  display.setCursor(0,4);
  display.println(weightAsString);
  display.display();
}

void doTara(){
  LoadCell.tareNoDelay();
  display.clearDisplay();
  display.setCursor(10,4);
  display.println("Wait");
  display.display();
  while(LoadCell.getTareStatus()== false){
    LoadCell.update();
    delay(50);
  }
}

// IRAM_ATTR void taraEvent(){ for ESP32 / ESP8266
void taraEvent(){
  taraRequest = true;
}

 

Und so sieht es dann aus:

HX711 Waage OLED Display und Tara - Taster
OLED Display und Tara – Taster

Der nächste Evolutionsschritt: Die Waage geht schlafen

Dann wollte ich, dass die Waage bzw. ihre Komponenten in einen Standby Modus gehen, wenn über einige Zeit weder eine Gewichtsänderung stattfindet, noch eine neue Taramessung angefordert wird. Da der Arduino UNO im Schlafmodus immer noch viel Strom verbraucht (siehe mein vorletzter Beitrag über Sleep Modes), habe ich hier den „nackten“ ATmega328P verwendet. Wie man mit den ATmega328P mit der Arduino IDE programmiert, habe ich hier beschrieben. Die Schaltung dazu sieht folgendermaßen aus: 

Vollständige Schaltung für die Waage mit Display und Taraknopf
Vollständige Schaltung für die Waage mit Display und Taraknopf

Im Sketch zu dieser Variante habe ich die Variable lastWeightAsFloat eingeführt, die den Wert der jeweils letzten Messung speichert. Dieser Wert wird mit dem aktuellen Messwert verglichen. Solange sich das letzte und das aktuelle Gewicht unterscheiden (Differenz < 1 g), ist die Waage offensichtlich in Benutzung. Und so lange wird die Variable tLastChange immer wieder auf millis aktualisiert. Das gleiche passiert bei einer Taramessung. Einmal pro Hauptschleife wird tLastChange mit millis verglichen. Überschreitet die Differenz 120.000 (= 2 min), wird die Waage in den Schlaf geschickt. Zunächst wird dazu das Display ausgeschaltet, dann das HX711 Modul und schließlich wird der ATmega328P in den Tiefschlafmodus versetzt.

Ein Interrupt weckt den ATmega328P wieder. Da der Taster für die Taramessung einen Interrupt auslöst, übernimmt er auch die Weckfunktion.

#include <Wire.h>
#include <HX711_ADC.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <avr/sleep.h>

#define OLED_RESET -1 // we don't have a reset, but the constructor expects it 
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
HX711_ADC LoadCell(4, 5);

int interruptPin = 2;   // tara and wake-up pin 
int powerOnPin = 6;
volatile bool taraRequest = false;
float weightAsFloat = 0.0; // current weight (as float)
float lastWeightAsFloat = 9999.0;  // former weight
unsigned long t = 0;    // system time of last weight measurement 
unsigned long tLastChange = 0;  // system time of last change of weight

void setup()   {  
  pinMode(interruptPin, INPUT);
  pinMode(powerOnPin, OUTPUT);
  digitalWrite(powerOnPin, HIGH);
  initBalance();
  attachInterrupt(digitalPinToInterrupt(interruptPin), taraEvent, RISING);
}

void loop() {
  LoadCell.update();
  /* In one loop a) measurement is done or b) a tara or c) the balance will be send to sleep
  or d) nothing happens */
  if (millis() > (t + 250)) {
    weightAsFloat = LoadCell.getData();
    displayWeight(weightAsFloat);
    if(abs(weightAsFloat-lastWeightAsFloat) >=1){
      tLastChange = millis();
      lastWeightAsFloat = weightAsFloat;  
    }
    t = millis();
  }
  
  if(taraRequest){
    doTara();
    taraRequest = false;
  }
  
  if(millis() > (tLastChange + 120000)){ // after 2 min of no weight change or tara the balance shall fall asleep
    sleepAndWakeUp();
  }
}

void initBalance(){
  taraRequest = false;
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x64)
  display.clearDisplay();
  display.setTextSize(4);
  display.setTextColor(WHITE);
  display.setCursor(10,4);
  display.println("Wait");
  display.display();
  LoadCell.begin();
  LoadCell.start(2000); 
  LoadCell.setCalFactor(883.24); 
  weightAsFloat = 0.0;
  lastWeightAsFloat = 9999.0;
  t = 0;
}

void displayWeight(float weight){
  int weightAsInt = int(weight+0.5);
  char weightAsString[6] = {0};
  dtostrf(weightAsInt,5,0,weightAsString);
  display.clearDisplay();
  display.setCursor(0,4);
  display.println(weightAsString);
  display.display();
}

void doTara(){    // tara
  LoadCell.tareNoDelay();
  display.clearDisplay();
  display.setCursor(10,4);
  display.println("Wait");
  display.display();
  while(LoadCell.getTareStatus()== false){
    LoadCell.update();
    delay(50);
  }
  tLastChange = millis();
}

void taraEvent(){
  taraRequest = true;
}

void sleepAndWakeUp(){
  LoadCell.powerDown();            // switch off HX711
  display.ssd1306_command(SSD1306_DISPLAYOFF);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // deep sleep mode
  cli();
  sleep_enable();
  sleep_bod_disable(); // disable brown-out detector
  sei();
  sleep_cpu();
  /* ATmega328P sleeps */
  sleep_disable();
  LoadCell.powerUp();            // switch on HX711
  display.ssd1306_command(SSD1306_DISPLAYON);
  initBalance();
}

 

Mit diesem Aufbau habe ich im Schlafmodus einen Stromverbrauch von 139 Mikroampere ermittelt. Das sind 3.3 Milliamperestunden pro Tag. Ein Akku sollte also einige Zeit halten.

Die Waage ganz ausschalten

Dann habe ich mir überlegt, wie man die Waage ganz ausschalten kann, ohne einen zusätzlichen Schalter einzubauen (denn das kann ja jeder!). Genau genommen lautet die Frage, wie sich die Waage selbst ausschalten kann.

Ich habe die Aufgabenstellung mit einem Thyristor gelöst. Ein Thyristor hat eine gewisse Verwandtschaft mit einem Transistor. Er besitzt drei Anschlüsse, nämlich die Kathode, die Anode und das Gate. Ein kleiner Stromimpuls am Gate macht den Übergang von Anode zu Kathode leitend. Im Gegensatz zum Transistor bleibt der Thyristor leitend, solange der sogenannte Haltestrom überschritten wird. Bei dem von mir verwendeten MCR100-6 liegt der Haltestrom typischerweise bei 0.5 Milliampere. Da der Stromverbrauch im Sleep Modus wesentlich geringer ist, schließt der Thyristor. „Gezündet“ wird der Thyristor mit Hilfe des Taraknopfes. So sieht die Schaltung dazu aus:

Die sich selbst abschaltende HX711 Waagenschaltung
Die sich selbst abschaltende Waagenschaltung

Dabei gab es noch ein Problem: Solange der Thyristor leitet, bleibt auch die Spannung am Gate hoch. Da wir hier nun eine Verbindung zur Tarafunktion haben, bleibt auch die Spannung am Interruptpin hoch (orangefarbene Leitung). Damit funktioniert die Tara Anforderung nicht mehr. Deshalb habe ich noch eine Diode eingebaut, die den Weg in diese Richtung versperrt.

Ihr könnt den vorherigen Sketch verwenden. Zeile 122 bis 125, also die Aktionen nach dem Wake-Up, werden natürlich nie ausgeführt und können entsprechend gelöscht werden. 

Bei der Auslegung der Stromversorgung ist zu beachten, dass am Thyristor ca. 0.8 Volt abfallen. Entsprechend weniger steht den Bauteilen zur Verfügung. Bei 5 Volt Stromversorgung ist das für die hier verwendeten Bauteile kein Problem. 

Danksagung

Bei Olav Kallhovd möchte ich mich für seine schöne Bibliothek bedanken. Die Bibliotheken von Adafruit haben mir bei der Ansteuerung des Displays geholfen. 

Die Waage auf dem Beitragsbild habe ich Gerhard Gellinger auf Pixabay zu verdanken. Den Arduino im Hintergrund habe ich schon mehrfach verwendet. Er stammt von Seven_au auf Pixabay

207 thoughts on “HX711 basierte Waage

  1. Hallo,
    ein super Beitrag wie so viele.
    Eine Frage hätte ich. Ist es denn möglich den aktuellen Messwert zum vorherigen Messwert zu addieren (lastWeightAsFloat + weightAsFloat)? Werden beim Summieren von float nicht die Dezimalstellen verschluckt?
    Auslösen möchte ich die Berechnung über einen zusätzlichen Pin. Ziel ist, dass das gewogene Gesamtgewicht, je nach Zeitspanne z.B. pro Tag, am Display ausgegeben wird.
    Danke und VG Tobi

    1. Hallo Tobi,
      auf einem klassischen Arduino ist ein Float auf ca. 7 Ziffern (Vor- und Nachkommastellen) genau. Dahinter ist alles Zufall. Und mit dieser Genauigkeit lassen sich Float-Werte addieren. Auf sieben Stellen genau wirst du aber sicherlich wiegen können. Damit spielt dann aber auch die begrenzte Auflösung der Float-Werte keine Rolle mehr.
      Und ja, und ich würde der Waage auch über einen zusätzlichen Taster „sagen“, dass der Wert jetzt zur Gesamtsumme addiert werden soll. Das kann ich hier aber nicht Detail ausführen, sondern nur skizzieren. Ich würde über den Taster einen Interrupt auslösen und in der Interruptroutine eine Bool Variable wie „add_weight“ auf true setzen. Dann würde ich eine globale Variable „total_weight“ einführen. Bei der nächsten Messung über weightAsFloat = LoadCell.getData(); wird dann der weightAsFloat zu total_weight addiert, wenn add_weight true ist. Und dann setzt du add_weight wieder auf false. Ungefähr klar? Dann würde ich mir durch Ausgabe von total_weight noch bestätigen lassen, dass das Gewicht übernommen wurde.
      VG, Wolfgang

  2. Hallo , ist ein super Beitrag , hat auch alles Prima geklappt. Wäre es eigentlich möglich einen festen wert zu dem Messwert entweder zu addieren oder subtrahieren und diesen dann anzeigen zu lassen ?

    D.h ich verwende die Waage als Filamentrollenwaage, ich verwende immer die gleiche Marke welche ein Leergewicht von 190g hat. Vor jedem Druck hebe ich die Rolle kurz an , tariere es mit einer Leerrolle und lege die mit der ich drucke dann wieder in die Halterung. Es muss doch einen leichteren weg geben.

    Ich hoffe ich konnte mich verständlich ausdrücken.

    Irgendwie muss es doch möglich sein , die Ergebnisse der Waage mit dem Gewicht der Leeren Rolle zu verrechnen.

    1. Hallo Michael,

      kein Problem. Ersetze einfach dort, wo du das Gewicht abfragst:

      LoadCell.getData(); durch LoadCell.getData() – 190;

      Dann zeigt er dir immer das Gewicht minus die 190 g an.

      VG, Wolfgang

      1. Darf ich dich nochmal kurz nerven ? Ich hab das noch etwas weitergesponnen. 1 Meter Filament wiegt 2,985g , gibt es die Möglichkeit eine Formel dafür anzuwenden und evtl die Aktuell möglichen Meter auf dem Display über Print anzeigen zu lassen ?
        So hätte ich xxx Meter / xxx Gramm auf dem Display stehen.

        Habe sowas ähnliches im Netz gefunden . Allerdings weiß ich nicht wie ihr die Formel am besten in den Sketch bringe .

        units = LoadCell.getData();
        g = (units *= 1000) – 200; // 200 g leergewicht spule
        cm = (g * 33.5) / 100; // 1 gramm 33.5 cm filament

        Wie würdest du es in deinen Sketch einbauen?
        Ich bin blutiger Anfänger, aber ziemlich begeistert von der ganzen Geschichte 😉

        1. Also du willst das Filamentgewicht in Meter umrechnen und ein Meter sind 2,985 g. D.h. die „Filamentmeter“ sind Gewicht [in Gramm] / 2,985.

          float g = LoadCell.getData() – 190.0; // g = Gewicht
          float fm = g / 2.985; // fm = Filament in Meter

          Wie du das auf dem Display anzeigen lässt, hängt vom Display ab. Das Display, das ich verwendet habe, wäre zu klein, um beides bei dieser Schriftgröße abzubilden. Da müsste man entweder ein größeres Display verwenden, die Schriftgröße verringern oder das Gewicht und die Länge abwechselnd anzeigen. Aber ich ich nicht die notwendige Zeit, dir den Sketch umzuschreiben. Da müsstest du dich dann selber durchbeißen.

          VG, Wolfgang

          1. Hi Wolfgang , ich hab´s dank deiner Hilfe geschafft. Er zeigt mir bei 1 kg Filament 335 Meter an. So wie es sein soll ! vielen Dank !!!

            1. Hallo Michael, schön, es freut mich dasses klappt und auch dass du das noch einmal teilst!

              Viel Spaß und Erfolg mit kommenden Projekten.

              VG, Wolfgang

          2. Ich hab die Schriftgröße verkleinert , Meter und Gewicht werden jetzt schön nebeneinander angezeigt, die Messwerte ordentlich darunter. Hat ein Moment gedauert bis ich verstanden hatte wie ich deine Float variable auf das Display bekomme , aber am Ende hat’s geklappt und ich hab wieder was gelernt. Muss einfach tiefer in Arduino eintauchen.

    2. Hallo,
      ein super Beitrag wie so viele.
      Eine Frage hätte ich. Ist es denn möglich den aktuellen Messwert zum vorherigen Messwert zu addieren (lastWeightAsFloat + weightAsFloat)? Werden beim Summieren von float nicht die Dezimalstellen verschluckt?
      Auslösen möchte ich die Berechnung über einen zusätzlichen Pin. Ziel ist, dass das gewogene Gesamtgewicht, je nach Zeitspanne z.B. pro Tag, am Display ausgegeben wird.
      Danke und VG Tobi

  3. Hallo Wolfgang,
    jetzt bin ich’s leider noch einmal.
    Mir ist aufgefallen, dass sich bei mir der Sketch
    balance_with_tft_display.ino Nach ca. 10 Minuten aufhängt.
    Woran kann das liegen?
    Grüße Joachim

    1. Hallo Joachim,

      da er es bei mir nicht tut, kann ich dir das nicht so ohne Weiteres beantworten. Hast du den Sketch so gelassen, wie er ist und auch die Schaltung so aufgebaut wie abgebildet? Was für ein Board verwendest du?

      Und was heißt „hängt“? Anzeige friert ein und reagiert nicht auf Tara-Knopf drücken?

      VG, Wolfgang

      1. Sorry das Gewicht bleibt plötzlich stehen wird nicht mehr aktualisiert reagiert auf Tara und dann kommt wait und fertig…
        Geht nur noch Stecker raus und von vorne

        1. Hallo Joachim,

          ich schlafe mal eine Nacht darüber. Vielleicht kommt mir noch eine gute Idee.

          VG, Wolfgang

        2. Hi Joachim,

          es hat mir keine Ruhe gelassen und deshalb habe ich das ganze noch einmal aufgebaut und Dauer-getestet. Ohne irgendwelche Änderungen, außer dass ich einen Arduino Nano verwendet habe, was aber keine Rolle spielen sollte. Es lief hier für 2 Stunden ohne Probleme. Wie auch immer fiel mir noch auf, dass ich vor dem „unsigned long t = 0;“ das „static“ vergessen habe (oder ich hätte t global definieren müssen). Dadurch ist „if (millis() > t + 250)“ immer true und die Waage wird im Dauerfeuer abgefragt. Ich habe das static zugefügt. Vielleicht läuft es damit besser? Ich bin nicht so optimistisch, weil es bei mir trotz des Fehlers lief, aber Versuch macht klug.

          Zusätzlich kannst du auch mal versuchen, loop zu ersetzen durch:

          void loop() {
            static boolean newDataReady = false;
            float weightAsFloat = 0.0;
            static unsigned long t = 0;
            
            if (LoadCell.update()) newDataReady = true;
            
            if (newDataReady) {
              if (millis() > t + 250) {
                weightAsFloat = LoadCell.getData();
                displayWeight(weightAsFloat);
                newDataReady = false;
                t = millis();  
              }
            }
            
            if(taraRequest){
              doTara();
              taraRequest = false;
            }
          }
          

          Da ist noch eine Extra-Abfrage drin, ob neue Ergebnisse tatsächlich vorliegen.

          Ansonsten gibt es noch die Standardempfehlungen: Kabel tauschen, Kontakte überprüfen, Spannungsversorgung überprüfen. Allerdings würde ich bei solchen Problemen immer erwarten, dass sie sofort und nicht nach 10 Minuten auftreten.

          VG, Wolfgang

  4. Hallo und Danke für den tollen Beitrag,

    ich habe jedoch noch eine Frage:
    Ich möchte gerne anstelle von Tara = 0
    den Wert von 11 Kg setzen.
    Wie kann ich das machen?
    Vielen Dank schon mla für die Hilfe.
    Viele Grüße
    Joachim

    1. Hi Joachim,

      da wäre ich ganz pragmatisch und würde die 11 kg einfach zu den Gewichten addieren, also nachdem du das Gewicht abgefragt hast fügst du einfach die Zeile ein:
      weightAsFloat += 11000.0;
      Das ist auf jeden Fall einfacher als an den Kalibrierwerten rumzurechnen und kommt dasselbe heraus.

      VG, Wolfgang

      1. Hallo Wolfgang,
        Danke für die schnelle Antwort.
        Sorry aber mir ist nicht ganz klar wo das rein muss 🤷‍♂️
        Grüsse Joachim

        1. In dem Sketch mit dem TFT Display wäre es hinter Zeile 39:
          weightAsFloat = LoadCell.getData();

          In dem Sketch für den Regelbetrieb würdest du hinter dieser Zeile (73):
          float i = LoadCell.getData()
          einfügen:
          i += 11000.0;

          Hoffe, das hilft!?

  5. Hallo Wolfgang,
    wirklich ein toller Beitrag. Ich habe seit einer Weile Bienenwaagen im Betrieb, Skripte letztlich aus den typischen Beispielen modifiziert. Die Daten (Gewichte in Gramm, namentlich markiert) werden per UDP an einen Server gesandt.
    Das funktionierte initial sehr gut, jetzt kommt es immer zu einer „magischen“ Zunahme des Gewichts. Meine Bienen sind außerordentlich fleißig, 20 kg Honig am Tag sind aber unplausibel.
    Ist dir irgendetwas bekannt bezüglich shiftender Messwerte? Kämpfe ich da mit kalten Lötstellen oder gibt es da Defekte Module?
    Stabilizing Time, Tara usw. habe ich bereits mehrfach geändert, nützen tut es nichts…
    Schonmal vorab Danke für die Hilfe!

    1. Hallo Jan,
      handelt es sich um Langzeitmessungen, d.h. hast du die Tara aus bzw. wiegst du über längere Zeit mit derselben Tara? So ein Langzeitdrift kann mehrere Ursachen haben. Das Messprinzip der Waagen sind Dehnungsmessstreifen, die ihren Widerstand mit der Längung oder Stauchung ändern. Zusätzlich zu der Dehnung durch das Gewicht kann es durch plastische Verformung der Waage (durch Dauerbelastung) oder durch thermische Ausdehnung oder Schrumpfung zu vermeintlichen Gewichtsänderungen kommen. Bei Kurzzeitmessungen, also Tara nehmen und direkt wiegen, sollten sich diese Effekte nicht auswirken. Oder aber die Dehnungsmessstreifen bzw. der Kleber gibt auf. Das könnte sich dann auch auf Kurzzeitmessungen auswirken. Theoretisch könnte es sein, dass ein Widerstand durch eine schlechte Lötstelle zu veränderten Spannungen und damit zu merkwürdigen Ergebnissen führt, aber nur auf der Seite vom HX711 Modul zur Wägezelle. In den meisten Fällen würde ich aber eher erwarten, dass eine schlechte Lötstelle zum Komplettausfall oder zu sinnlosen Werten führt und nicht zu driftenden Werten. Leider kann ich nicht mehr auf die Ferne sagen.
      VG, Wolfgang

      1. Vielen Dank,
        manchmal ist ja das Fehlverhalten von bestimmten Modulen bekannt und man sucht sich an der falschen Stelle zu Tode. Ich werde mir trotzdem mal die Lötstellen vorknöpfen und die Mechanik überprüfen.
        Wenn ich den Fehler (hoffentlich) finde, werde ich berichten!

  6. Hallo Wolfgang,

    tolle Arbeit hast du da geleistet und auch danke für den tollen Beitrag!

    Ich werde eine ähnliche Waage als meine Diplomarbeit verwenden. Vorab bräuchte ich, um es meine Direktorin zu zeigen, ein Paar Bilder. Dürfte ich deine Bilder die du hier gepostet hast verwenden?

    Liebe Grüße aus Österreich!

    1. Hallo Büsra,

      alle Bilder, bis auf das Titelbild, und alle Schaltungen stammen von mir und du kannst sie gerne verwenden. Freut mich! Bei den auf manchen Bildern abgebildeten Lebensmitteln ist allerdings markenrechtliche Vorsicht geboten.

      Liebe Grüße aus Deutschland!

  7. Guten Morgen.
    Ich habe eine Frage zu „HX711 basierte Waage“

    Ich habe gehört das ein HX 711 Modul 2 Kanäle hat.
    Ist es somit möglich am dem Modul 2 Vollmessbrücken mit 4 jeweils 4 Wiegezellen anzuschließen?
    Und die Messwerte getrennt auszulesen?

    1. Hallo,
      technisch geht das. Allerdings, soweit ich weiß, nicht mit der hier verwendeten Bibliothek. Ob es eine andere Bibliothek gibt, die das kann, weiß ich nicht. Da müsstest du mal auf GitHub suchen.

      Wie man den HX711 ohne Bibliothek ansteuert, das habe ich hier beschrieben:
      https://wolles-elektronikkiste.de/dehnungsmessstreifen#HX711
      Damit kannst du dann auch problemlos Kanal B auslesen.

      Der Nachteil an Kanal B ist die geringere Verstärkung (32fach) ggü. Kanal A (128 oder 64).

      VG, Wolfgang

  8. Nach all der Zeit habe ich doch nochmals Fragen….
    Mir fehlt gerade das Hintergrundverständnis. In vielen deiner Beiträge gehst du der Sache ja so richtig auf den Grund, bevor du eine Bibliothek anfasst (IR – Fernbedienungen z.B.). In diesem Beitrag hast du die Bibliothek direkt eingesetzt und ich kann an einem Punkt nicht 100% folgen. Es handelt sich scheinbar um eine Art one-way SPI-Protokoll, richtig? Ich habe mir die GitHub-Seite von Olav Kallhovd’s HX711_ADC angesehen und verstehe die Bibliothek nicht so richtig. Etwas besser verstehe ich das Datenblatt, welches er freundlicherweise in Extras abgelegt hat. Mein Ausgangsproblem ist, dass mir einige Pins fehlen. Daher habe ich von vier HX711-Modulen, die ich benötige, jeweils zwei SCK-Pins „zusammengefasst“, also den Pin doppelt als SCK definiert und Zwei HX711 SCK Pins mit nur einem GPIO verbunden (in dem Fall Pins eines ESP8266 D1). Das funktioniert praktisch gut, aber ich habe etwas Skrupel, weil ich nicht ganz erklären kann, warum. Ich habe folgenden „educated guess“: DOUT geht bei beiden überbrückten HX711-Modulen mehr oder weniger zum gleichen Zeitpunkt down, ich habe einen CLK-Pin „überschrieben“, sodass nur einmal 25 Pulse für Kanal A mit 128 Gain gesendet werden. Währenddessen sendet jedes HX711-Modul seine Daten über DOUT an seinen eigenen dedizierten „Eingangspin“. Ich müsste demnach eigentlich zusätzlich sicherstellen, dass beide DOUT initial vor Abfrage „LOW“ sind. Ist das richtig? Oder habe ich mir das verkehrt zusammengereimt?

    Ich kann Dir für all die Infos und Geduld gar nicht genug danken….

    1. Hallo Leif,
      die Datenübertragung folgt keinem standardisierten Format. Wie man den HX711 „zu Fuß“ anspricht, also ohne Bibliothek, habe ich in einem Beitrag über Dehnungsmessstreifen beschrieben:
      https://wolles-elektronikkiste.de/dehnungsmessstreifen#HX711
      Ich denke, du hast das schon alles richtig erfasst und ich würde mich deiner Meinung anschließen, dass alle DOUTs, die zu der kombinierten SCK Leitung gehören, auf LOW stehen müssen, da man die Sequenz von 25 Pulsen einhalten muss. Schickt man mehr, verstellt man das Gain. Ist eines der DOUTs erst später auf LOW verarbeitet es nur einen Teil der SCK Pulse und bleibt dann mitten in der Abfragesequenz stehen. Du kannst ja per digitalRead prüfen ob die DOUTs auf LOW sind oder nicht.

      1. Danke für Deine Prompte Antwort und den Hinweis auf den zweiten Beitrag. Zu Fuß bin ich nun fast geneigt einmal 25 und einmal 26 Pulse zu senden und so Kanal A und B zu nutzen, anstatt zweier Module mit kombinierter SCK…. das überlege ich mir nochmals ganz genau. Vielen herzlichen Dank!

  9. Servus,

    funktioniert so weit ganz gut jedoch bekommen ich es nicht hin nach einem Reset kein Tara auszuführen zu lassen

    1. Hi, eigentlich musst du nur beim Starten der Waage ein „false“ übergeben, also: LoadCell.start(stabilizingtime, false);
      Dann sollte kein Tara ausgeführt werden. Hast du das schon probiert?

      1. Wo genau soll ich das einfügen ? da steht nur LoadCell.start(2000)

        void setup() {
        pinMode(interruptPin, INPUT);
        attachInterrupt(digitalPinToInterrupt(interruptPin), taraEvent, RISING);
        display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128×64)
        display.clearDisplay();
        display.setTextSize(4);
        display.setTextColor(WHITE);
        display.setCursor(10,4);
        display.println(„Wait“);
        display.display();
        LoadCell.begin();
        LoadCell.start(2000);
        LoadCell.setCalFactor(-82.97);
        }

            1. Wenn du die Tara nicht ausführst, dann startet er nicht bei Null. Darum macht man ja die Tara. Schau mal weiter oben im Beitrag:

              Vielleicht wollt ihr beim Einschalten nicht tarieren? Dann ändert in Zeile 48 den Wert für _tare auf false. Ihr bekommt dann einen „Fantasiewert“ als Messergebnis. Schreibt euch diesen Wert auf und zieht ihn von zukünftigen Messergebnissen ab. Damit habt ihr die Tara sozusagen eingefroren.
              Der Startwert bleibt aber durch verschiedene Einflüsse (z.B. Temperatur, geringfügige dauerhafte Verformung) nicht dauerhaft absolut konstant.

  10. Hallo Wolfgang
    vielen Dank für deinen Beitrag, besonders interresiert hat mich das abschalten der Waage, welches ich noch einbauen werde.

    Habe meine Waage-Mechanik mit dem 3D-Drucker erstellt.
    – die Wägezelle ist eine 1 kg
    – das Modul ist ebenfalls ein HX711
    – die Anzeige besteht aus einem 4-stelligen 7-Segment-Modul welches via I2C angesteuert wird.
    – die CPU ist ein 8-Pin ARM: STM32G031J6
    – programmiert habe ich alles in FORTH:
    – bis 100 g ist die Anzeige auf 1/10 g danach auf 1 g Auflösung eingestellt
    – nach einer minute get das ganze auch in den Sleep modus
    – das Tarieren und das wakeup geschieht mit einem Taster

    Gruss Ralph

  11. Hallo,
    ein guter Rat noch zur Mechanik: die Wägeplatte sollte mindestens zwei Führungen bekommen. So kann sie
    sich nicht seitlich veschieben, was die Genauigkeit beeinträchtigen würde. Eine weitere Fehlerquelle ist ein
    Schutz gegen Überlastung. Die Wägeplatte sollte also bei ca. 10% Überlast auf einen Anschlag laufen.
    Der Grund: Eine einmal überdehnte Wägezelle ist irreversibel beschädigt und wird nie wieder zuverlässige
    Werte über den gesamten Messbereich liefern.
    Die Mechanik wird durch diese Maßnahmen allerdings schon recht anspruchsvoll.

    Viele Grüße aus dem Norden
    Henning

  12. Hallo, ich habe diese Waage genauso aufgebaut als Abschlussprojekt, nur anstatt dem OLED Display habe ich ein LCD Display. Dieses flackert allerdings, wenn sich das Gewicht aktualisiert.. Was Kann ich tun?

    1. Hi Jannik, wenn du sagst es flackert beim Gewichtauflegen, dann gehe ich davon aus, dass es nicht mehr flackert, wenn sich das Gewicht stabilisiert hat, richtig? Das würde heißen, dass das Display zu langsam auf Änderungen reagiert. Eine gewisse Abhilfe würde dann ein Reduzieren der Update Frequenz bringen, sprich du setzt den Zahlenwert in
      if (millis() > (t + 250)) {
      In loop hoch. Allerdings ist das ein gewisser Komfortverlust.
      Also müsste man eher schauen, ob man die Anzeige etwas schneller machen kann. Das hängt davon ab, welches Display du benutzt, welche Bibliothek und wie dein Code geschrieben ist. Von der LiquidChrystal Bibliothek weiß ich, dass man die Funktion clear sehr langsam ist. Besser ist es, die Werte zu überschreiben, ggf mit Leerzeichen. Auch home ist langsam.
      Bei solchen Problemen ist es ratsam, erst einmal zu vereinfachen. Also Waage weglassen und einfach nur alle 0.25 s einen Zufallswert ausgeben. Dann weißt du schon einmal, ob es mit dem Rest des Codes zusammenhängt oder nur mit dem Display.
      VG, Wolfgang

  13. Hallo Wolfgang,

    vielen Dank vorweg!!!:-)
    meine Waag läuft und den Display hab ich angeschlossen.
    Wie füge ich nun die Erweiterung für den Oled im Prg. ein?
    Vielen Dank vorweg
    Tobias

    1. Hallo Tobias,
      ich verstehe gerade nicht, was du meinst. Welche Erweiterung? Funktioniert „balance_with_tft_display.ino“ nicht?
      VG, Wolfgang

      1. Hallo Wolfgang,

        tut mir leid, dass war ganz allein Fehler;-)
        Egal, in dem Zuge kann ich mich bei dir herzlich Bedanken für dein Projekt.
        Ich hab mir eine Waage mit dem 3d Drucker gebaut und dank dir funktioniert sie nun einwandfrei.
        beste Grüße

  14. Bei mir hat sich jetzt nur das Problem Drift (expotentielle steigerung bei Tara0 zu >2000g in nur 12Std) aufgetan.
    Habt ihr hierfür schon eine Lösung erarbeitet/ gefunden?
    Meine Lösungsansätze waren von Austausch meherer HX711, Verkabelung gesteckt, gelötet, änderung des GAIN so wie Änderung der Spannung.

    Leider bis heute kein Erfolg

    1. Die Waage arbeitet mit Dehnungsmessstreifen (DMS). Wenn die Waage driftet, heißt das, dass die DMS gedehnt oder gestaucht werden bzw. das Material darunter. Ursache 1: Temperaturschwankungen, wobei die DMS eigentlich so aufgeklebt sein sollten, dass sich der Effekt ausgleicht. Ursache 2: Verformung der Waage über die Zeit. Ursache 3: Schlecht geklebte DMS. Temperatur lässt sich beeinflussen, der Rest nicht wirklich.

  15. Salut Wolfgang,

    Ist es möglich die Schaltung so zu programmieren, dass wenn ein bestimmtes Gewicht überschritten wird ein Ausgang der PI schaltet?

    Gruess Pipo

    1. Klar, warum nicht? Einfach in einer Dauerschleife das Gewicht abfragen und mit dem Limit vergleichen. Aber du erwähnst den PI, das wäre also in Python, richtig? Ich habe aber nur Arduino Programmierung betrachtet. Oder habe ich das falsch verstanden?

  16. Hallo Wolfgang,
    ersteinmal und vielen Dank für die super Anleitung. Ich hätte mal eine Frage und zwar, wenn ich die Kalibrierung anfange und mein Gewicht platziere und das Gewicht eingebe, dann drücke ich auf ‚y‘ damit er weiter den Wert merkt. Dann bekomme ich ein Fehlermeldung wie folgt:

    Known mass is: 1000.00
    New calibration value has been set to: 0.00, use this as calibration value (calFactor) in your project sketch.
    Save this value to EEPROM adress 0? y/n
    Load_cell output val: nan
    Load_cell output val: nan
    Load_cell output val: nan
    Load_cell output val: nan
    Load_cell output val: nan
    Load_cell output val: nan
    ….

    Was könnte hier das Problem sein?

    Viele Grüße

    1. Hi Lindrit,

      beim Kalibrieren der Waage werden Rohdaten mit und ohne Gewicht ermittelt. Diese werden dann mit den Gewichten, also Null und dem bekannten Gewicht zu einem Steigungsfaktor umgerechnet. Simpler Dreisatz. Wenn dabei ein Kalibrierwert 0.0 herauskommt, dann heißt das, dass die Rohdaten nach Tara und Auflage des Gewichtes gleich waren. Folgerichtig erhält man dann „nan“ („not a number“) für die Gewichte, da die Rohdaten durch den Kalibrierwert geteilt werden und Division durch 0 nicht möglich ist.

      Ein ganz einfacher Fehler wäre, dass du das Gewicht schon bei der Tara aufgelegt hattest. Ansonsten spricht dann alles dafür, dass mit der Verkabelung etwas nicht stimmt. Die Kabel selbst oder Lötstellen könnten das Problem sein oder vielleicht hast du dich bei den Pins vertan. Oder das HX711 Modul ist schlicht kaputt – das würde ich aber als am unwahrscheinlichsten ansehen.

      Du könntest mal im Sketch Read_1x_LoadCell.ino in Zeile 44 einen fiktiven Kalibrierwert eintragen (z.B. 800.0) und dann verschiedene Gewichte auflegen. Wenn da immer derselbe Wert herauskommt (nach Tara: 0), dann weißt du sicher, dass die Waage / das Modul irgendwie nicht richtig verbunden ist.

      VG, Wolfgang

  17. Hallo Wolle,

    prima Beitrag, aber es hat sich ein Fehler eingeschlichen: Beim Anschlußplan muß es heißen: „Grün an A+“.

    Gruß Uwe

  18. Hallo Wolfgang,
    guter Beitrag! Nutze die Winterpause für den weiteren Ausbau meines Wohnmobils. Zur Zeit, mit ESP32 –
    den Füllstand von 2 Gasflaschen testen. Fernanzeige auf e-Paper Display, Abschaltung und ggf. Umschaltung der Gasflaschen per WiFi bzw. BT. Nutze hier 8x half Bridge Load Cells“ (YZC-161E) mit 2x HX711 und BME280 als Temperatur Kompensation. Deep Sleep zur optimale Energie Bilanz aus der Sicht der Wohnraum Lithium Zellen. Will am Ende ein komplexes Smart Home System realisieren mit Server, Kameras und Internet Kommunikation.
    Relativ umfangreiches Thema, im Netz bin ich bisher nicht wirklich fündig geworden mit Blick auf den speziellen Einsatz in div. Wohnmobilen (Mechanik, Elektronik, Software etc.). Entwickle bisher alles in übersichtlichen handhabbaren modularen Teilbereichen. Eine interessante anspruchsvolle, Zielstellung.
    Ob jemand Interesse an einer Mitarbeit hat? Unterstützung willkommen. Soll über Dich laufen oder? Habe keine Internetpräsens und keine diesbezügliche Ahnung!.
    Viele Grüße Peter aus dem Ruhr Pott ;-)).

    1. Hallo Klaus-Peter,
      auch ich habe mich in Anlehnung an eine Veröffentlichung im Wohnmobilforum damit beschäftigt, konnte es leider nicht zum Erfolg führen. Meine Programmierkenntnisse haben jedoch noch Lücken.
      Schau mal dort hin https://www.wohnmobilforum.de/w-t106200.html
      Mein neustes Projekt ist Homeassistant für das Wohnmobil zu nutzen.
      Viele Grüße Peter

      1. @ Dr. Kaulen,
        der o.g. Link ist alt… 2019. Für mich nicht zielführend.
        Aktuell: eine der Waagen funktioniert jetzt statisch… korrekt.
        Will mit einer Langzeit Messreihe die Trift vom gemessenen Gewicht als Faktor zur Kalibrierung ermitteln. Gewicht der Stahlflasche + Fahr-Erschütterungen sind ein nicht zu unterschätzender mechanischer Einfluss Faktor auf die Dehnungsmessstreifen.
        Ermittle at hoc die Veränderung der gemessenen Last einer vollen Flasche. Plus aller Störgrößen, erfasst mit den Möglichkeiten einer Raspberry Pi Sense HAT. Protokolliere alles in einer Datei.
        Will die Messreihen anschließend graphisch auswerten. Bin auf das Resultat gespannt.
        Eventuell ist muss ich das mechanische Konzept noch anpassen. Temporäre Arretierung der Flasche während der Fahrt zur Entlastung der Dehnungsmesstreifen mittels Magnet gesteuerter Blockade o.ä.
        Welche Probleme hast Du aktuell?
        Viele Grüße Peter

        1. Guten Morgen Peter,
          ich erkenne bei Dir ein sehr ambitioniertes Projekt. Wegen des Aufwandes habe ich mich letztlich für Truma Levelcontrol entschieden. Wenn man sie zum Laufen gebracht hat, funktionieren sie ganz gut.
          Mein Projekt ist, mit Homeassistant und ESPHome Meß- und Schaltvogänge von einem Tablet aus zu steuern. Für das WLAN und evtl. auch MQTT nutze ich den RUT 950. Projekte um das Wohnmobil füllen einen großen Teil meiner Freizeit, mit 71 hat man davon eine ganze Menge, aus.
          Viele Grüße Peter

          1. @ Dr. Kaulen
            Hallo Peter,
            scheint als ob wir an den gleichen Themen arbeiten, auch vom Zeitfaktor als Rentner ;-)) Ich programmiere u.a. in C++ und Python. Wegen der Hardwarenähe -ESP… -RPi… -ATMEL… Mich würden Deine Lösungsansätze interessieren. Können wir uns im Detail austauschen?
            Viele Grüße Peter

            1. Hallo Peter,
              weil ich glaube, daß unsere Konversation sich vom eigentlichen Thema zu weit entfernt, möchte ich Dir anbieten sie nur zwischen uns durchzuführen.
              Wenn Du damit einverstanden bist, warte ich auf eine Mail von Dir.
              Viele Grüße peter(at)kaulen.de

            2. Hallo Peter, da sich unser Austausch vom eigentlichen Thema zu sehr entfernt, können wir uns gern über peter(at)kaulen. de weiter austauschen. Ich warte auf eine Mail von Dir.
              Viele Grüße Peter

        2. Hallo… und überraschung, grob habe ich die gleiche Idee…
          Bei mir hat sich jetzt nur das Problem Drift (expotentielle steigerung bei Tara0 zu >2000g in nur 12Std) aufgetan.
          Habt ihr hierfür schon eine Lösung erarbeitet/ gefunden?

  19. Hallo zusammen,

    ich habe eine Frage zu dem Projekt.
    Ich habe folgendes Display verbaut: https://www.reichelt.de/index.html?ACTION=446&LA=0&nbc=1&q=ard%20shd%20lcd3%2C5
    Die SD Karten Funktion benötige ich bei meinem Projekt nicht. Das Display belegt am Arduino UNO folgende Pins:

    A0, A1, A2, A3, A4
    GND, 5V
    2, 3, 4, 5, 6, 7, 8, 9

    Die Anschlüsse DAT und CLK vom HX711 habe ich auf die Arduino UNO Pins 11 und 12 gelegt.

    Jetzt zu meiner Frage, wie muss ich das Arduino Programm abändern damit es bei mir funktioniert?

    Ich würde mich über eine Antwort sehr freuen.
    Danke, Gruß Melissa

    1. Hallo Melissa,

      mittlerweile ist das Display eingetroffen und es funktioniert. Wenn man es nicht direkt auf ein UNO-Board setzt, ist es eine ziemliche Kabelsteckerei.

      Ich habe nicht die Zeit, dir ein komplettes Programm zu schreiben. Daher hoffe ich, dass dich einige Hinweise auf die richtige Spur bringen. Ich gehe dabei davon aus, dass du die Bibliothek MCUFRIEND_kbv nutzt.

      Erstmal würde ich – ohne Waage – mit dem Beispielprogramm „Font_simple“ herumspielen. Zum einen, um zu testen, ob das Display funktioniert, zum anderen um auszuprobieren, welche Schriftgrößen und Farben du nutzen willst. Und darüber hinaus nmatürlich, um die Funktionen kennenzulernen.

      Der Kopf des Sketches würde dann so ausssehen:

      #include <Wire.h>
      #include <HX711_ADC.h>
      #include <Adafruit_GFX.h>
      #include <MCUFRIEND_kbv.h>

      HX711_ADC LoadCell(11,12);
      MCUFRIEND_kbv tft;

      #include <Fonts/FreeSans12pt7b.h> // such dir die Schriften aus, die du nutzen möchtest
      #include <FreeDefaultFonts.h>

      #define BLACK 0x0000 // definiere die Farben die du nutzen möchtest.
      #define GREEN 0x07E0
      #define WHITE 0xFFFF

      Im Rest des Programms schmeißt du alles raus, was mit „display.“ beginnt und ersetzt es durch die entsprechenden Anweisungen der MCUFRIEND_kbv Bibliothek. Da das Display Objekt „tft“ genannt wurde, also „tft.irgendeineFunktion()“.

      Ein gewisses Problem ist, dass die Interruptpins 2 und 3 belegt sind. Und ich weiß leider nicht, wie man die Pinbelegung für das Display ändert. Das ist blöd, weil ich die Tarataste in meinen Programmen über Interrupts steuere. Da fallen mir nur zwei Möglichkeiten ein: 1) eine Arduino MEGA2560 verwenden, da dieser noch mehr Interruptpins hat. 2) Anstelle des Interrupts den Zustand eines Tasters an einem freien Pin permanent mit digitalRead(Pin) abfragen.

      Ich hoffe, das hilft erst einmal weiter.

      VG, Wolfgang

    2. Und jetzt habe ich doch noch herausgefunden, wie man die Pins ändern kann. Gehe in die Bibliotheksdateien (Arduino/libraries und dort zu MCUFRIEND_kbv/utility. Öffne die Datei mcufriend_shield.h und ändere die Zeilen 40 und 41 von:

      #define BMASK 0x03
      #define DMASK 0xFC

      in:

      #define BMASK 0x07
      #define DMASK 0xF8

      Damit hast du den Anschluss von LCD_02 vom Arduino Pin 2 nach Pin 10 verschoben. Die Verkabelung musst du entsprechend ändern. Und dann hast du den Pin 2 als Interruptpin frei.

      1. Hallo Wolfgang,
        Danke für deine Antwort.
        Mein Display bleibt, egal was ich ausprobiere, immer weiß.

        Würdest du mir evtl. dein komplettes Programm zukommen lassen?

        Gruß Melissa

        1. Hi Melissa, ich habe kein komplettes Programm für dieses Display und die Waage geschrieben. Ich habe lediglich mithilfe des Beispielsketches Font_Simple.ino probiert, ob das Display bzw. die Bibliothek überhaupt funktioniert. Und das tut es. Vielleicht probierst du das auch erst einmal. Und dann habe ich in einem zweiten Schritt getestet, ob ich die Pins ändern kann, um einen der Interruptpins freizubekommen. Das ging auch nach längerem probieren und recherchieren. Aber probiere Font_Simple erst einmal ohne jede Änderung. Fehlersuche heißt vor allem erst einmal Fehlereingrenzung.
          VG, Wolfgang

          1. Hallo Wolfgang,
            Der Beispielsketch Font simple hat leider auch nicht funktioniert.
            Deshalb weis ich momentan nicht weiter.
            Gruß Melissa

            1. Hallo, das führt jetzt im Rahmen der Kommentare ein wenig zu weit bzw. hat nicht mehr viel mit dem Beitrag zu tun. Ich sende dir eine Antwort per E-Mail. VG, Wolfgang

  20. Hallo Wolfgang,
    auch von mir erstmal ein Dankeschön für diesen aufschlussreichen Beitrag! Habe alle so in Betrieb nehmen können.

    Ich möchte jetzt mit 3 Wägezellen und 3 HX711-Modulen arbeiten und damit 3 Füllstände überwachen.
    Wahrscheinlich muss ich dann auch 3 mal kalibrieren und alle drei Werte nacheinander ins EEPROM speichern, oder? Oder ist der CalibrationValue immer gleich für diese Kombination aus Zelle und Modul?
    Falls das nicht so ist, muss ich dann ja auch die drei CalibrationValues in das read_cell-Skript einlesen. Also eigentlich das Skript drei mal hintereinander basteln, damit es jede Zelle einzeln auswertet.

    Weißt Du, wie es den CalibrationValue ins EEPROM abspeichert?
    Ich hatte 237,30 und habe nachgeschaut, er lag auf den ersten 8 byte nacheinander von Stelle 0 bis 7 auf dem EEPROM. Weißt Du wie die Umrechnung da funktioniert?
    Ich hatte dann noch einmal kalibriert und als calVal_eepromAdress die 8 festgelegt, weil ich dachte dass der Wert also immer 8 byte einnimmt, es waren aber dann nur noch 4… also von 8 bis 11 stehen Werte die sich von 255 unterscheiden…

    Tut mir Leid, dass ich jetzt so viele Dinge wild hinein frage. Ich hoffe du verstehst wo meine Probleme sind und kannst mir vielleicht weiter helfen.

    Viele Grüße
    Moritz

    1. Hallo Moritz,

      jede Wägezelle ist ein bisschen anders, d.h. du brauchst drei Kalibrierwerte die du einzeln ermitteln musst. D.h. 3 x den Calibrationsketch laufen lassen und wenn du die Werte ins EEPROM schreiben möchtest, dann musst du die Adresse für jeden Kalibrierwert ändern. Ein Float nimmt 4 Byte ein (zumindest ist das auf dem Arduino und dem ESP32 so), also:
      EEPROM.put(0, newCalibrationValue);
      Im zweiten Durchlauf:
      EEPROM.put(4, newCalibrationValue);
      und schließlich EEPROM.put(8, newCalibrationValue);
      Du kannst aber auch Lücken im EEPROM Speicher lassen. Hauptsache, Abstand ist groß genug und du holst die Werte von der richtigen Adresse wieder ab mit EEPROM.get(0 bzw 4 bzw 8, calibrationValue_1 bzw calibrationValue_2 bzw calibrationValue_3);. Um den Rest musst du dich nicht kümmern.
      Für den Regelbetrieb musst du dann drei Load_Cell Objekte erzeugen:
      HX711_ADC LoadCell_1(HX711_dout_1, HX711_sck_1);
      HX711_ADC LoadCell_2(HX711_dout_2, HX711_sck_2);
      HX711_ADC LoadCell_3(HX711_dout_3, HX711_sck_3);
      …. und dann alle getrennt initialisieren, tarieren, usw.
      Viel Erfolg!
      VG, Wolfgang

  21. Moin,
    ich wollte mal fragen wie ich heraus bekomme wie ich das Display beim ESP32 anschließe, da dort die analogen Ausgänge verwendet werden und ich diese nicht aus dem Code heraus lesen kann, weil ich noch recht neu bin. Also ich bräuchte einfach nur die Codierung, welche mir sagt wo das display angeschlossen wird.

    Mit freundlichen Grüßen
    Maxi

  22. Hallo Wolfgang,

    hast du schon mal getestet ob ein Moment, das durch die exzentrische Position der zu wiegenden Masse entsteht, einen Einfluss hat?

    Viele Grüße
    Felix

    1. Hallo Felix,
      interessante Frage, die ich mir auch gestellt habe. Zu meinem Erstaunen war das gemessene Gewicht bei meinem superprofessionellen Selbstbau 😉 weitgehend unabhängig von der Position des Gewichtes. Wenn man aber eine große Wägefläche auf die Wägezelle setzt, wird sicherlich irgendwann der Hebel zuschlagen und das Ergebnis verfälschen.
      VG, Wolfgang

  23. Hallo Wolfgang,

    danke für deinen Beitrag!

    Der Sketch zum Kalibrieren der Waage hat bei mir einwandfrei funktioniert.

    Nutze ich den Sketch für den Regelbetrieb der Waage, werden nur irgendwelche Zeichen ohne Zeilenumbruch am seriellen Monitor ausgespuckt:
    ⸮⸮o⸮E⸮⸮⸮kH#⸮dj@r⸮⸮H⸮⸮%⸮[h⸮%⸮Fh⸮⸮kH#⸮⸮WI⸮⸮d⸮z⸮o⸮E⸮⸮⸮kH#⸮ez@r⸮d⸮{⸮⸮ezEr⸮$⸮[*⸮⸮{.

    Ich habe den Sketch 1:1 kopiert und nur den Kalibrierwert geändert.
    Zum Einsatz kommt ein Arduino Mega 2560.

    Hast du eine Idee woran das liegen kann?

    Besten Dank vorab und viele Grüße
    Colin

    1. Hi Colin,

      bei komischen Zeichen fällt mir nur eine falsch eingestellte Baudrate ein. Aber eigentlich ist die bei beiden Sketchen 57600. Und es gibt keine Fehlermeldungen oder Warnhinweise beim kompilieren? Vielleicht kannst du die beiden Punkte erstmal prüfen? Sonst melde dich nochmal.

      VG, Wolfgang

      1. Hallo Wolfgang,

        habe die Baudrate auf 9600 geändert und siehe da –> es funktioniert.
        Warum auch immer war die Baudrate in meinem Sketch zur Kalibrierung auch auf 9600.

        Besten Dank für die schnelle Antwort!

        Viele Grüße und einen schönen Abend
        Colin

        1. Ich habe neulich die Baudraten in den Sketchen angeglichen, damit genau das nicht mehr passiert! Welche Baudrate du nimmst, ist bei dieser Anwendung egal. Hauptsache, die Baudrate im Sketch und im Serial Monitor ist identisch.

  24. Reinhard
    Danke. Es ist ein sehr guter Beitrag.
    Einen Teil (Kalibrierung, Messung, OLED display) habe ich umgesetzt.
    Nun kommen Tara Taster und Thyristor. Einen Vorschlag zur Stromversorgung haben Sie nicht gemacht.

    Können Sie einen beispielhaften Vorschlag machen?

  25. Hallo Wolfgang,

    vielen Dank für deine super Anleitung und deinen Block.
    Ich habe aber irgendwie ein Problem bei deinem Sketch.
    Mit dem Kalibrierungs-Sketch misst der HX711 einwandfrei aber wenn ich deinen Sketch hochlade
    fährt er zwar ganz normal hoch aber bleibt auf 0 stehen, egal was für ein Gewicht ich drauflege.
    Ich finde einfach den Fehler nicht, weil es mit anderen Sketchen funktioniert.
    Ich habe deinen 1:1 übernommen.
    Vielleicht hast du eine Idee was bei mir der Denkfehler ist, weil wenn die Verkabelung nicht stimmen würde, dann dürfte ja auch nichts anderes funktionieren.

    Gruß
    Stefan

    1. Hallo Stefan,

      du schreibst, dass der Kalibrierungssketch einwandfrei funktioniert. D.h. am Ende liefert er auch richtige Messwerte? Dann schreibst du, dass du den Sketch 1:1 übernommen hast – du meinst den Read_1x_load_cell.ino? Oder einen der folgenden Sketche? Ganz einfach 1:1 übernehmen kannst du ihn ja nicht. Mindestens den Kalibrierwert aus dem Kalibriersketch musst du eintragen. Hast du das gemacht? VG, Wolfgang

      1. Vielen Dank für deine rasche Antwort.
        Kalibrierwert aus dem Kalibriersketch habe ich nicht übernommen.
        Ich habe diesen Sketch “ balance_with_tft_display.ino “
        übernommen.
        Der Kalibrierungssketch hat das richtige Ergebnis angezeigt.
        Dein Sketch funktioniert auch jetzt.
        Ich hatte die Pins für den Wägebalken im Sketch getauscht, weil es es bei mir anders angeschlossen ist.
        Als ich auf (4, 5) zurückgewechselt habe lief es dann :).
        Jetzt habe ich nur ein anderes Problem, was ich noch am Versuchen bin zu beheben.
        Da ich das nicht gelernt habe muss ich mich da etwas durchfuchsen.
        Ich möchte die Waage als Motorprüfstand für Modellmotoren einsetzten und dafür noch eine Servofunktion einbetten, um per Knopfdruck den Motorregler immer um 10% zu erhöhen.
        Einzeln habe ich das schon hinbekommen aber, wenn ich es in deinen Sketch übernehme, dann funktioniert die Waage nicht mehr .
        Ich teste noch ein wenig rum, weil ich dich nicht unnötig damit beschäftigen möchte, da du bestimmt genug zu tun hast.
        Gruß
        Stefan

        1. So der Prüfstand läuft.
          Wäre nur schön, wenn er anstatt den Winkel des Servos den Prozentwert ausgeben würde.
          Mit 0-100% kann ich mehr anfangen als mit 60-114°.
          Ich weiß nicht wie ich das mit map hinbekomme.
          Falls du mir da eine kleine Hilfe geben könntest, wäre ich dir sehr dankbar.

          VG
          Stefan

          1. Hallo Stefan,
            map(gemessenerWinkel, unteresWinkelLimit, oberesWinkellimit,unteresProzentlimit, oberesProzentlimit). Als wenn deine Winkel zwischen 60 und 114° variieren und du 60° als 0% und 114° als 100% ansehen willst dann wäre das:
            WinkelInProzent = map(WinkelInGrad, 60, 114, 0, 100);
            Zu beachten ist, dass map() einen Integerwert liefert.
            VG, Wolfgang

  26. Hallo Wolfgang,
    danke für den Beitrag, alles sehr verständlich und nachvollziehbar. Meine Frage bezieht sich auf eine Anwendung im Langzeitbetrieb. Wenn ich alles verstanden habe, ist jedes Aufwecken mit einem Reset oder Tara-Abgleich verbunden. Jetzt beginnt wieder die Grillsaison und mein unvollendetes Projekt vom vorigen Sommer kommt wieder hoch. Ich möchte den Inhalt der Gasflasche vom Grill als Füllstandsanzeige wiegen. Das Leergewicht kenne ich (5,6kg), so dass ich kein Tara zur Nullstellung benötige. Wie kann ich den alten Wert von voriger Woche als neuen Startwert verwenden? Hast Du Erfahrungen mit so langen Messzyklen, dass ich wie in Deinem Beispiel den Wert vor Einschlafen in den Speicher schreibe, dieser auch als Startwert ein- zwei Wochen später verwenden kann? Viele Grüße von Rolf

    1. Hallo Rolf,
      schau mal in den Sketch Read_1x_Load_Cell.ino, Zeile 48. Wenn du dort _tare=false setzt, dann wird keine Tara gemessen. Die Waage arbeitet linear, d.h. die Messwerte sind dann alle um diesen Wert verschoben. Wenn du einen AVR Arduino (z.B. Uno, Nano, Pro Mini, Mega) hast, dann könntest du diesen Wert in den EEPROM schreiben. Unter Umständen verschiebt sich der Nullpunkt auf Dauer. Das passiert, wenn sich die Waage unter dem Gewicht auf Dauer verformt. Das muss man ausprobieren, aber das ist ja einfach.
      VG, Wolfgang

  27. Hallo ersteinmal und vielen Dank für die super Anleitung hat mir sehr geholfen.
    Jedoch habe ich ein Problem, die Waage misst aufbauend (was ich damit meine man stellt ein Gewicht mit 100g ab und im ersten update schreibt es 10.00g dann 33.00g, 56.00g, 87.00g und dann erst 100g).
    Ich möchte sie so Programiren das sei Hausnummer 5 Sekunden misst und dann mir das Endgewicht anzeigt.
    Ich brauche es um zwei Abläufe zu Triggern, der eine soll zwischen 0g und 50g getriggert werden, der andere zwischen 50g und 100g. Hätte diesbezüglich schon ein funktionierendes Programm, doch durch das aufbauende Messen, triggert es zuerst den ersten Messbereich und dann den zweiten.
    Kann mir jemand helfen?

    Herzliche Grüße,
    Markus

    1. Hi Markus,

      du könntest bei einer Veränderung des Gewichts prüfen, ob sich dieses noch weiter verändert oder nicht. Und erst wenn zwischen der letzten und der aktuellen Messung der Unterschied kleiner x ist, dann verwendest du den Messwert. Du speicherst also den aktuellen Wert in einer Variable „lastWeight“ und nach der nächsten Messung rechnest du Differenz = Aktuelle Wert – lastWeight. Das ganze machst du bis Differenz < x.

      VG, Wolfgang

      1. Hi Wolfgang,

        danke für die schnelle Rückmeldung. Ich habe es probiert aber leider geht es immer noch nicht, vielleicht findest du kurz Zeit mein Programm auf Fehler zu Prüfen.
        (Bin noch Anfänger)

        Hier der Code:

        …..

        1. Hi Markus,

          schicke mir den Code bitte mal per mail. Das Problem ist – und ich muss mal schauen, ob ich das irgendwie ändern kann – dass > und < hier im Kommentar als HTML Steuerzeichen interpretiert werden.
          Ich habe den Code erstmal ganz entfernt.
          Mail Adresse ist: wolfgang.ewald@wolles-elektronikkiste.de

          VG, Wolfgang

  28. Hallo Wolfgang,

    vielen Dank für die ausführliche Dokumentation, Schalpläne und Bilder! Ich muss/ darf für die Uni einen ähnlichen Aufbrau mit einem Raspberry Pi machen. Das Ziel ist hierbei eine möglichst feine Waage bzw. einen Aufbau für sehr geringe Masseänderungen von wenigen Gramm zu konstruieren. (Auf die Wägezelle soll eine kleine Kondensatorplatte und damit die Kraft F zwischen geladenen Platten in Abhängigkeit von der Spannung U bei konstantem Plattenabstand d gemessen werden.. also Elektrostatik-Versuche).
    Hast du da eine Idee wie man es auch für geringe Massen nutzen kann? Ich habe bei meinen (billigen) Wägezellen (500g und 1kg) stets das Problem mit der Nullpunktkalibrierung.. und bekomme weiterhin schwankende Spannungen raus..

    Eventuell hast du oder ein interessierter MitleserIn ja einen guten Gedankengang.

    Vielen Dank und liebe Grüße
    Raphael

    1. Hi Raphael,

      für meine in dem Beitrag beschriebene Waage habe ich auch eine dieser Wägezellen genommen, die es für ein paar Euro im Paket zusammen mit dem HX711 gibt. Wir reden über dieselben Teile, richtig? Du kannst dir das Foto oben ja noch mal anschauen. Und du steuerst die Wägezelle auch über den HX711 an, richtig? Im Gegensatz zu dir bin ich sehr begeistert von der Leistungsfähigkeit. Mit zwei einfachen Brettern konnte ich reproduzierbar auf das Gramm genau wiegen. Oder nutzt du etwas anderes, um die Wägezelle zu lesen? Beim HX711 gibt es ein paar Dinge zu beachten, zum Beispiel dass man mit 10 Hz und nicht mit 80 Hz messen sollte und dass man die Werte mittelt.
      Also bevor du die Wägezelle abschreibst, sage mir und den anderen Lesern erst einmal genau, wie du die Wägezelle ansteuerst und ausliest. Wenn du Schaltpläne, Programme, Fotos o.ä. hast kannst du mir das auch per mail zusenden (wolfgang.ewald@wolles-elektronikkiste.de).
      Die Wägezellen arbeiten ja mit Dehnungsmessstreifen (DMS), die als Wheatstone Brücke angeordnet sind. Ich habe in einem separaten Beitrag auch etwas über DMS gemacht, das könnte dir auch weiterhelfen.
      https://wolles-elektronikkiste.de/dehnungsmessstreifen
      Ist zwar alles Arduino / C++ aber vom Prinzip lässt sich das auf Python übertragen. Ich gehe zumindest davon aus, dass du Python benutzt, wegen des Raspberry Pi, richtig?
      Wir kriegen das hin. Milligramm wäre eine Herausforderung, Gramm ist kein Thema!
      VG, Wolfgang

  29. Hallo Wolfang!

    Zuerst möcht ich mich für den tollen Beitrag bedanken, der ist sehr hilfreich.

    Zu meinem Problem – bin noch Anfänger was dies angeht, ich versuche den gemessenen Wert an einem LCD-TFT Display auzugeben. Die Verkabelung sollte stimmen, aber wie gebe ich nun den Wert am Display aus?

    Ich wär mehr als glücklich wenn du mir weiterhelfen könntest.

    BG Olaf

    1. Hallo Olaf,

      ich kann in einem Kommentar kein Tutorial für LCDs unterbringen. Ich kann dir den Weg nur skizzieren. Wenn ich etwas neues angehe dann teile ich dass Problem erst einmal. Kannst du mit dem TFT Display umgehen, d.h. mit dem Arduino etwas ausgeben? Falls nein, dann arbeite eines der vielen Tutorials durch, die es dazu gibt, z.B.:

      https://www.makerguides.com/character-lcd-arduino-tutorial/
      https://docs.arduino.cc/learn/electronics/lcd-displays

      Und wenn du dann weißt wie es geht, dann musst du im Sketch „balance_with_tft_display.ino“ lediglich alles rausschmeißen, was zum TFT Display gehört und durch den LCD Code ersetzen, d.h. die LiquidCrystal Bibliothek einsetzen, ein LiquidCrystal Objekt anstelle eines TFT Objektes erzeugen und dann schließlich die das Gewicht mit der lcd.print() Funktion ausgeben.

      Mehr ins Detail kann ich hier nicht gehen.

      VG, Wolfgang

  30. Hallo Wolfgang,

    Super Hilfe dein Beitrag. Läuft alles gut. Ich würde die Wägezelle für einen Prüfstand für Modellturbinen nehmen. Da bräuchte ich eine etwas schnellere Aktualisierung der Werte. Ist das möglich?

    Gruß Michael

    1. Hallo Michael,

      es gibt im Wesentlichen zwei Schrauben an denen du drehen kannst: Standardmäßig sind die HX711 Module auf eine Messfrequenz von 10 Hz. Man kann sie auf 80 Hz erhöhen, sofern das auf dem Modul vorgesehen ist. Hier ist ein Beispiel, bei dem es geht:
      https://wolles-elektronikkiste.de/wp-content/uploads/2021/10/HX711_module_balance-1024×350.jpg
      Einfach den 0 Ohm Widerstand bei 10 Hz entfernen und die beiden Kontakte bei 80 Hz überbrücken. Probiert habe ich es nicht, aber es wird mehr Rauschen geben. Ein Hochsetzen der Frequenz per Software geht nicht.

      Die zweite Schraube lässt sich per Software drehen. Und zwar ist das die Anzahl der zu mittelnden Messungen. Der Autor der Bibliothek hat 16 voreingestellt. In den Bibliotheksdateien gibt es eine Datei namens config.h, da kannst du die Einstellung vornehmen. Da steht auch schön beschrieben, wie man die maximale Messfrequenz errechnet.

      Mit beiden Maßnahmen ist es möglich, von 1.8 Sekunden auf 1/80 Sekunden herunterzugehen. Aber wie gesagt, das Rauschen wird zunehmen.

      VG, Wolfgang

      1. Hallo Wolfgang,

        Danke für die schnelle Antwort. Habe es in der config.h Datei bearbeitet und es ist jetzt deutlich schneller. Ich werde es mal so testen. Jetzt muss ich nur noch ein nettes Startbild beim einschalten hinbekommen 🙂

        Noch eine kurze Frage. Die Messung geht je nach Turbine bis 20 kg. Da ist die Anzeige in Gramm etwas doof 🙂 Wenn ich die Anzeige anstatt in Gramm mit kg kalibriere, zeigt es mir nur ganze kg Werte an. Kann man sich auch Komma Werte anzeigen lassen?

        Gruß Michael

        1. Wenn du das Gewicht in Kilogramm als Float hast, dann kannst du es in einen String umwandeln:
          String weightAsString = String(weightAsFloat , 2);
          Die 2 bedeutet dabei die Nachkommastellen.
          Dann muss man nur schauen, wie man es rechtsbündig auf das Display bekommt. Über weightAsString.length() weiß man, wie lang der String ist und lässt links entsprechend viel Platz. Vielleicht gibt es auch fertige Funktionen dafür in irgendwelchen Display Bibliotheken.

          1. Danke schaue ich mir mal an. Habe es jetzt auf die schnelle nicht hinbekommen.
            Kann man den Höchstwert auch anzeigen lassen? Habe die Schriftart kleiner gemacht und habe so noch eine Zeile unter dem aktuellen Wert frei 🙂 Dann wäre mein Code für mein Projekt perfekt 🙂

            1. Was meinst du mit Höchstwert? Den höchst möglichen Messwert? Vielleicht verstehe ich dich gerade falsch.

              1. Sorry habe mich auch etwas doof ausgedrückt. Den höchsten Wert der gemessen wurde. Möchte damit messen, wie viel Schub die Turbine hatte ohne dabei immer auf das Display schauen zu müssen. Sobald ich die Turbine abschalte, könnte ich so zu dem Display gehen und sehen was sie in dem Testlauf hatte. Beim erneuten einschalten von der Waage wäre dieser wieder bei Null. Zusätzlich sollte aber weiterhin den aktuellen Wert auch dran stehen.

                1. Du führst eine Variable ein und die heißt z.B. maxValue. maxValue bekommt den Startwert 0.0. Und dann vergleichst du das jeweils aktuelle Gewicht mit dem maxValue:
                  if (weightAsFloat > maxValue){maxValue = weightAsFloat;}

                  Das führt jetzt aber schon ziemlich weit vom Blogthema weg…

  31. Ich weiß, ich frage jetzt ein klein wenig off Topic. Das Projekt ist aber eine Inspiration für mich.
    Wenn man jetzt beschließen würde, statt eines Thyristors einen Transistor zu verwenden und diesen über einen PIN zu schalten der ab Start auf High geschaltet ist. Und wenn statt eines Arduino ein ESP8266 die Arbeit macht. Und das mit 4 AA Batterien die über einen Festspannungsregler der 3,3V bei max 800mA für den ESP liefert. Welchen Transistor und welchen Widerstand für die Basis würden Sie empfehlen? Ich blicke einfach nicht durch bei der Berechnung und ich kenne auch die Unterschiede bei den Transistoren nicht.
    Mit den 5v am PIN eines Arduinos und einem BC337-40 mit 270 Ohm an der Basis gelingt mir die Sache problemlos.
    Bei 3,3v weiß ich einfach nicht welcher Transistor geeignet ist…. Ich frage für einen Freund 😀

    Herzliche Grüße und Danke, egal ob mit oder ohne Hilfe

  32. Hallo Wolfgang
    Danke für die vielen tollen Imformationenin den Beiträgen von Dir !
    Ich bin 63 Jahre alt und habe mich seit einem Jahr mit dem Arduino beschäftigt.Als erstes hab ich mir das Starterkit von Elegoo gekauft .Die Projekte hab ich auch nachgebaut .Einiges in Programierung habe ich verstanden aber auch so manches noch nicht.Da bin ich auf deinen Kanal gestoßen.
    Das Projekt „Waage“ interesiert mich ganz besonders. Ich bin Hobbyhühnerhalter und wollte mir schon immer etwas zur automatischen Fütterung bauen wen ich mal paar Tage in Urlaub bin .Meine Frage : Kann man den Sketsch so abwandeln,das wenn eine mechanische Schnecke z.B.1kg Körner gefördert hat, über einen Impuls
    der Antrieb abschaltet wird ? Über ein Antwort würde ich mich freuen.Viele Grüße aus Sachsen Andreas.N.

    1. Hallo Andreas,

      ja, natürlich. Vom Prinzip her kein Problem. Das Gewicht kann man ja regelmäßig messen und wenn es gleich oder größer als 1 kg ist, dann folgt das Abschalten. Zum An-/Abschalten gibt verschiedene Möglichkeiten: z.B. Relais, Schaltsteckdose, Mosfet. Das kommt auf dein Gerät an.

      VG, Wolfgang

      1. Hallo Wolfgang,
        erst eimal vielen herzlichen Dank für die schnelle Antwort. Wenn das also nicht das Problem ist den Sketch anders zu schreiben mus ich mich erst einmal damit auseinandersetzen. Darf ich dich wenn ich nicht klar komme konsultieren ? Ich denke ich muss da noch viel lese und lernen.
        Danke noch mal und viele Grüße A.N.

        1. Hallo Andreas,

          ich helfe gerne. Limitierender Faktor ist nur manchmal die Zeit. Melde dich einfach.

          VG, Wolfgang

    2. Hallo Wolfgang, hallo Andreas,
      ein weiterer toller Artikel von Dir, Wolfgang. Danke für die vielen Ideen, die von Dir kommen.
      Ich habe Deinen Sketch für eine Dosierwaage für die Espresso-Mühle umgesetzt. Das funktioniert auf dem Breadboard schon hervorragend mit einer Genauigkeit von etwa 0,1 g Dosiergenauigkeit.
      Ich habe einen Rotary Encoder eingesetzt, um das Zielgewicht einzustellen, und schalte ein Relais, um die Mühle an- und abzuschalten. Es wird direkt in den Siebträger gemahlen, der auf der Waage liegt. Den Code kann ich gerne bei Bedarf teilen.
      Etwas Off-Topic: Ich habe zum Sparen von Steckdosen in der Küche versucht, eine Spannungsversorgung für den µ-Controller und die elektronischen Komponenten zu erstellen, also 5 V DC, und dafür die Eingangsspannung von der Mühlennetzleitung abzuzweigen. Als Print-Netzteil setze ich das folgende ein: https://www.amazon.de/gp/product/B073QH1XT8/ref=ppx_yo_dt_b_asin_title_o08_s00?ie=UTF8&psc=1
      Und hier fängt es an, schwierig zu werden. Auf einmal treten Input-Signale auf, die nicht mit den zugeordneten Tastern korrelieren. Kann das ein Einstreuen von hochfrequenten Störsignalen sein, die in dem Netzteil entstehen? Und wie könnte man eine 5V-Spannungsversorgung aus der Netzleitung erstellen, die ja schon in meiner Waageneinheit liegt, so dass so etwas nicht passiert?
      Herzliche Grüße

      Bernhard

      1. Hallo Bernhard,

        schönes Projekt! Zum Problem: was so ein Netzteil an Spannung liefert, ist vielleicht nicht immer ganz sauber, ich kann mir aber nicht vorstellen, dass es so unsauber ist, dass Taster falsche Zustände liefern. Wenn bei mir mal ein Taster nicht das tut, was er soll, dann fehlt meistens schlicht ein Pull-Up oder Pull-Down Widerstand. Zumindest würde ich erst einmal nach einfachen Ursachen suchen, bevor du anfängst, Rauschfilter (RC-Glieder o.ä). einzubauen. Ich muss allerdings sagen, dass sich meine 220 Volt Erfahrungen in Grenzen halten.

        VG, Wolfgang

        1. Hallo Wolfgang,

          ist es Deiner Erfahrung nach ein Unterschied, ob man die internen Pull-Ups (per Software aktiviert) des Arduinos verwendet oder selbst verbaute 10kOhm-Widerstände auf Masse zieht?
          Die internen nutze ich bereits (gerade noch einmal doppelt geprüft). Und da gibt es immer mal wieder bei Druck des einen Tasters auch die Antwort eines zweiten Tasters.
          Danke für Deine Einschätzung.

          Gruß, Bernhard

          1. Hallo Bernhard,

            die internen Pull-Ups sollten funktionieren. Dann muss es doch woanders dran liegen. Auf die Ferne schwer zu sagen. Kannst du einfach mal das Netzteil abklemmen und durch eine andere 5V Stromquelle ersetzen?

            Grüße, Wolfgang

            1. Hallo Wolfgang,

              danke für Dein Feedback. Das habe ich nun gerade mit einem USB-Ladegerät getestet. Und tatsächlich verhält sich das System auf einmal wunderbar robust. Sehr merkwürdig. Nächster Schritt: Testen, ob mit elektromagnetischer Abschirmung des ersten Netzteils die Robustheit steigt. Ich verwende Alufolie.

              Gruß, Bernhard

              1. Hallo Wolfgang,

                gefunden: Es ist das Relais, das offenbar nicht sauber arbeitet. Wenn am Relais 230 V geschaltet werden, kommt es zu dem beschriebenen Verhalten. Also austauschen und nochmal versuchen. Ich bin gespannt.
                Danke für Deine Ideen zur Problemlösung.

                Gruß, Bernhard

                1. Ich erbastel mir gerade das gleiche (Espressomühle – Mahlen nach Gewicht). Wenn du ein SSR nimmst, zum Schalten des Motors sollte gewährleistet sein, dass dieser sich nicht induktiv ins Stromnetz zurück entlädt.

                  1. Hallo Fritz, danke für die Anregung. Die Lösung habe ich inzwischen auch schon gefunden und erfolgreich umgesetzt. Die Mühle lässt sich jetzt wunderbar steuern. Ich bin sehr zufrieden.
                    Nächstes ToDo: Integration eines Menüs, so dass man die Kalibrierung, ein Einwiegen der Siebträger und automatisches Erkennen der Siebträger umsetzen kann. Das Ganze wird jetzt mit einem Farb-TFT umgesetzt. Weil’s schöner aussieht.
                    Gruß Bernhard.

                    1. Hallo Wolfgang, kannst Du Fritz und mich irgendwie vernetzen, so dass wir uns weiter über das Thema austauschen können? Das wird hier vermutlich zu speziell für diesen Artikel.

  33. Danke für diesen Beitrag und danke für die vielen Antworten auf die gestellten Fragen. Ich arbeite gerade an 4 Vollbrücken an 4 HX711 mit einem ESP8266 – genauer an einem entkernten Wii Balance Board, dass mit die Gewichtsverteilung von Patienten nach Beinverletzungen als JSON bereitstellen soll. Zwar bin ich noch nicht am Ziel, jedoch hat mir dieser Beitrag hier sehr weitergeholfen.
    DANKE!

  34. Hallo,
    dies ist mein erstes Projekt mit einem Arduino, weswegen ich bei ein paar Sachen nicht weiterkomme.
    1: Wie verbinde ich die verschiedenen Sketche miteinander? Z.B. die Kalibrierung und den für die LED?
    2: Ich habe anstatt von einer OLED eine lcd1602, muss ich den Sketch dafür anpassen, und wenn ja, wie ungefähr?

    Danke im voraus,
    Freundliche Grüße

    1. Hallo,

      der Sketch für die Kalibrierung ist nur dazu da, den Kalibrierwert zu ermitteln, den man dann im endgültigen Sketch verwendet. Man verbindet die Sketche also nicht wirklich, sondern lässt erst den Kalibriersketch nur einmalig laufen und muss ihn nicht wiederholen, solange man nichts baulich an der Waage ändert.
      Zur anderen Frage: es gibt für die lcd1602 Display eine Bibliothek namens LiquidCrystal. Ein Dokumentation mit Beispielen gibt es hier:
      https://www.arduino.cc/en/Reference/LiquidCrystal
      und dann muss man das, was der Waagensketch mittels LoadCell.getData(); „ausspuckt“ (ich habe es weightAsFloat genannt mithilfe der Funktionen der LiquidCrystal Bibliothek auf das LCD Display bringen.
      Mehr ins Detail kann ich im Rahmen eines Kommentars nicht gehen.
      Viel Erfolg & viele Grüße, Wolfgang Ewald

  35. Ich habe ein Problem und zwar habe ich schon mehrere Codes ausprobiert für einen Tara Button aber jeder Code hat Fehler die ich nicht verstehe. Ich hoffe das jemand von euch mir helfen kann, da ich das schon seit 5 Stunden versuche und es einfach nicht hinbekomme. Ich muss dazu noch erwähnen das ich alles für den Seriellen Monitor brauche und nicht auf einem Display

    Hier der Code:
    #include
    #include
    #define OLED_RESET 7

    //we don’t have a reset, but the constructor expects it

    HX711_ADC LoadCell(4, 5);
    byte interruptPin=2;
    volatile bool taraRequest = false;
    void setup() {
    pinMode(interruptPin, INPUT);
    attachInterrupt(digitalPinToInterrupt(interruptPin), taraEvent, RISING);
    Serial.begin ; // initialize with the I2C addr 0x3C (for the 128×64)
    Serial.clear();
    Serial.setTextSize(4);
    Serial.setTextColor(BLACK);
    Serial.setCursor(10,4);
    Serial.println(„Wait“);

    LoadCell.begin();
    LoadCell.start(2000);
    LoadCell.setCalFactor(883.73);
    }
    void loop() {
    float weightAsFloat = 0.0;
    unsigned long t = 0;

    LoadCell.update();

    if (millis() > t + 250) {
    weightAsFloat = LoadCell.getData();
    SerialWeight(weightAsFloat);
    t = millis();
    }
    if(taraRequest){
    doTara();
    taraRequest = false;
    }
    }
    void SerialWeight(float weight){
    String weightAsString = „“;
    weightAsString = floatToDisplayString(weight);
    Serial.clear();
    Serial.setCursor(0,4);
    Serial.println(weightAsString);

    }
    void doTara(){
    LoadCell.tareNoDelay();
    Serial.clear();
    Serial.setCursor(10,4);
    Serial.println(„Wait“);

    while(LoadCell.getTareStatus()== false){
    LoadCell.update();
    delay(50);
    }
    }
    void taraEvent(){
    taraRequest = true;
    }
    String floatToSerialString(float floatValue){
    String stringValue=“ „;
    int intValue = (int)(round(floatValue));
    if(intValue<0){
    stringValue="";
    }
    uint8_t blanks = 3 – int(log10(abs(intValue)));
    for(int i=0; i<blanks; i++){
    stringValue+=" ";
    }
    stringValue+=(String)intValue;
    return stringValue;
    }

    1. Hallo Alexander, die Funktionen „setTextSize“, „setTextColor“, usw. gehören zur Adafruit_SSD1306.h Bibliothek. Das heißt, du musst ein Objekt erzeugen, z.B. „display“:
      Adafruit_SSD1306 display(OLED_RESET);
      Und dann kannst du die Funktionen für das Objekt verwenden, also z.B. display.setTextSize(….);. Serial versteht diese Funktionen nicht. Den Funktionsumfang von Serial findest du hier:
      https://www.arduino.cc/reference/en/language/functions/communication/serial/
      Für deine Zwecke reichen print und println.
      Ich würde den Sketch Read_1x_load_cell.ino sketch nehmen und diesen um den Tara Button erweitern.

      1. Danke für die schnelle Antwort und den code den sie mir per email gesendet haben. Der Code hat funktioniert nur die Zahlen die rausgekommen sind waren ganz andere und es ist ein bisschen zu schnell

        1. Das mit dem „zu schnell“ lässt sich ja über ein ein delay steuern. Wenn andere Zahlen herauskommen, dann liegt das wahrscheinlich am Kalibrierwert. Eine HX711 basierte Waage muss auf jeden Fall kalibriert werden. Dafür gibt es den Sketch Calibration.ino.

          1. Hallo Wolfgang
            erst mal danke für die schnelle Antwort. Bei mir funktioniert alles immer besser nur habe ich das Problem das wenn ich die Waage kalibriere und dann den anderen Code hochlade, die Waage nicht mehr kalibriert ist.

            1. Hast du denn den Kalibrierwert übertragen? Die Wägezelle liefert ein Signal, das sich linear mit dem Gewicht ändert. Die Steigung der Gerade (calibrationValue) ist für jede Waage unterschiedlich. Du musst ihn einmal bestimmen, den Wert aber in jeden neuen Sketch übertragen. Die Taramessumg setzt den Nullpunkt.

  36. Hallo,
    erstmal danke für den Beitrag.
    Wir stellen aktuell das Projekt nach und es läuft soweit auch alles gut, wir kriegen die richtigen Werte auf dem Seriellen Monitor und die Tara Funktion über den Taster macht eben auch das was sie soll.

    Nun der Haken an der Sache: versuchen wir nun diesen Wert über unser Display auszugeben ( ein Adafruit SSD1306 ) so friert unser Programm ein und nichts geht mehr voran. Warum auch immer können wir immer nur mit dem HX711 kommunizieren oder mit dem Display, niemals mit beiden gleichzeitig bzw. nacheinander. Sobald mit der Funktion ‚display.display();‘ der Buffer für den Text übertragen werden soll bleibt das Programm stehen und nichts geht mehr voran. Der einzige unterschied sonst noch ist das wir keinen Arduino UNO sondern NANO verwenden, doch daran dürfte es doch nicht scheitern? Sonst ist alles angeschlossen so wie auch hier im Projekt beschrieben. Haben Sie evtl. eine Idee was genau das Problem sein könnte?

    MfG

    1. Hallo,
      ich kann sagen, dass es nicht am Arduino Nano liegt oder dass das zumindest sehr unwahrscheinlich ist.

      Woher wisst ihr denn, dass ihr mit dem HX711 kommunizieren könnt, wenn das Display nicht funktioniert?

      Und verwendet ihr den unveränderten balance_with_tft_display.ino sketch? Sonst schaue ich mir euren Sketch mal an (an wolfgang.ewald@wolles-elektronikkiste.de). Hat euer TFT Display andere Abmessungen? Ist vielleicht einfach nur der Cursor an einer falschen Stelle (display.setCursor())? Habt ihr die richtige I2C Adresse (0x3C für 128×32 / 0x3D für 128×64).

      VG, Wolfgang

      Mehr fällt mir aus der Ferne nicht ein.

  37. Hallo Wolfgang

    Zuerst einmal ein dickes Lob für Dein Blog, das ist für mich als Anfänger sehr informativ und gut verständlich. Nun habe ich eine Waage mit 4 x 50Kg Zellen nachgebaut mit Taster und TFT. Das funktioniert alles auch, jedoch nur bis 9999 Gramm, danach schaltet das Display ab, eine kleinere Schrift bringt auch nicht mehr Stellen. Wo und wie könnte ich zu mehr Stellen im Display kommen oder noch besser von Gramm auf Kilo mit 1-2 Dezimalstellen nach dem Komma in der Anzeige zu wechseln. Habe im Sketch „balance_with_tft_display.ino“ nichts gefunden das darauf hindeutet. Könntest Du mir erklären wie ich mein Projekt fertigstellen kann? Herzlichen Dank Markus

    1. Hallo Markus,

      vielleicht schreibe ich das nochmal um, damit der Code etwas unabhängiger Stellenanzahl und Display wird.

      Es müsste reichen, wenn du in Zeile 77 die Zahl der Blanks auf 4 setzt. Wenn der Platz nicht ausreicht, musst du die Textgröße kleiner machen (Zeile 18). Und dann evtl. noch den Cursor an eine andere Stelle setzen (Zeile 50). Probier einfach mal ein bisschen. VG , Wolfgang

      1. Hallo Wolfgang

        Vielen lieben Dank für die prompte Antwort! Mit den Blanks und Textgrösse passt es nun. Bis ca 30Kg funktioniert die Waage, danach kommt ein Negativwert und nach diesem unsinnige Werte. Der Sketch „Regelbetrieb“ zeigt im Seriellenmontior die richtigen Messwerte. Ich versuche es weiter.

        1. Das liegt am Wertebereich von integer, der hört nämlich bei 2^15 -1 = 32767 auf. Wenn du auf long wechselst (Zeile 73), dann sollte es gehen.

          long intValue = (long)(round(floatValue))

          Wenn man den Fehler schon mal hatte, dann fällt einem das auf, ansonsten kann man recht lange danach suchen.

          1. Wolfang Du bist ein Genie! Nun habe ich es geschafft. Die Waage zeigt nun alles korrekt an so wie ich es mir gewünscht habe und mich schon lange damit beschäftigt habe. Die Darstellung von Kilo werde ich später mal angehen, jetzt bin ich einfach nur glücklich.
            1000 Dank für Deine Hilfe Markus

  38. Super Anleitung, die mir sehr gut weitergeholfen hat.
    Ich würde gerne das gemessene Gewicht an ein Victron Tanksensor weitergeben, dieses Teil kann Sensorsignale mit 4-20mA oder 0-10V an ein Anzeigegerät mit TouchScreen weitergeben. An dem Victron Venus OS Gerät kann dann definiert werden, welcher Wert für 0% (Leer) und 100% (Voll) verwendet werden soll. Z.B. Leer ist 7mA oder 1,2V und Voll ist 17mA oder 3,2V.

    Wie kann ich das Sketch erweitern, dass das gemessene Gewicht als Stromwert oder Spannungswert ausgegeben wird?
    Das maximale Gesamtgewicht ist bekannt und ist 20Kg.

    Danke!

    1. Ist das nicht einfach nur ein (erweiteter) Dreisatz? Du willst einen Wert auf einer Gewichtsskala in einen Wert auf einer Spannungs- oder Stromskala umrechnen.
      Wenn einerseits das Gewicht in Gramm weightAsFloat ist, und das maximale Gesamtgewicht maxWeight ist 20000g und anderseits „Leer“ 7mA ist und 17mA ist „Voll“, dann ist der gesuchte Strom I = 7.0 + weightAsFloat * (17.0 -7.0) / maxWeight

      Oder mit der map() Funktion. Die „schluckt“ allerdings nur Ganzzahlen, deswegen muss man ein wenig tricksen:
      I * 1000 = map(weightAsInt, 0, 20000, 7000, 170000)

      Oder sehe ich das zu einfach?

      1. Vielen Dank für diesen Lösungsansatz! So könnte ich das recht einfach umsetzen.
        Leider bin ich Arduino Neuling.
        Ich wäre sehr dankbar für Hinweise, wie ich mit dem Arduino Strom- oder Spannungswerte ausgeben kann?
        Wäre das auch für 2 Waagen mit einem Arduino gleichzeitig möglich?
        Es handelt sich dabei um 2 Gasflaschenwaagen im Wohnmobil.

        Nochmals vielen Dank!

        1. Ich weiß nicht, ob ich die Frage richtig verstehe. Soll der Arduino einen Strom- oder eine Spannung ausgeben, der/die proportional zum Gewicht ist? Einstellen kann man nur eine Spannung (mit analogWrite()). Der Arduino hat aber keinen echten analogen Ausgang, analogWrite() gibt PWM Signale aus. D.h. die Spannung schwankt sehr schnell zwischen 0 und 5 Volt und über das Verhältnis der 0 Volt Zeit zur 5 Volt Zeit wird die mittlere Spannung gesteuert. Man könnte dann das Signal mit einem RC Glied glätten, wenn notwendig. Das ist aber alles nicht so wirklich gut, weil nicht besonders genau.

  39. Mache gerade ein Projekt für die Schule…
    Beim kalibrieren kommt immer der Wert 0.
    Woran könnte liegen?
    Habe eine 1kg wähezelle, gewichte 300g
    Würde mich über eine schnelle Rückmeldung freuen

    1. Hallo,
      also du hast den Sketch Calibration.ino (unverändert?) auf den Arduino (?) geladen und versuchst mit einem bekannten 300g Gewicht zu kalibrieren, richtig? Und der Sketch liefert bei „Calculated calibration value is: “ eine 0? Ich würde ja zunächst sagen, dass es ein Fehler in der Verkabelung ist, aber dann solltest du eine Fehlermeldung bekommen: „Tare timeout, check MCU>HX711 wiring and pin designations“. Oder hast du das Gewicht vielleicht einfach zu früh aufgelegt? Es muss ja der Messwert ohne und mit Gewicht verglichen werden.

    2. Hallo Hannes,
      habe das Selbe Problem, hast du den Fehler gefunden? Verkabelung habe ich geprüft, dennoch kommt im Kalibirierungssketch immer der Kalibrierungsfaktor 0 heraus (der Testsketch liefert auch dauerhaft eine 0). Bin etwas ratlos..

      1. Merkwürdig. Hast du den Calibration Sketch aus meinem Beitrag genommen oder direkt aus der Bibliothek? Vielleicht hat der Autor der Bibliothek inzwischen etwas geändert. Das kann ich nicht permanent anpassen. Probiere mal den Sketch direkt aus der Bibliothek. Ich kann es selbst gerade nicht testen.

  40. Hallo Wolfgang,

    ist ein sehr interessanter Beitrag.
    Ich würde gerne mehrere HX711 seriell abfragen und die Werte in die Datenbank schreiben.
    Leider habe ich nicht gefunden welches Protokoll HX711 verwendet.
    Im Prinzip sollen es 10 Wagen geben die permanent den Wert ermitteln.
    Ändert sich das Gewicht hat sich Lagerbestand geändert.
    Dann wird Lagerbestand in der Datenbank aktualisiert.

    1. Hallo Eduard, der Autor der Bibliothek hat einen Beispielsketch für den Betrieb mehrerer HX711 mitgeliefert. Du findest ihn in Arduino IDE unter den Beispielen oder du suchst im Bibliotheksordner oder gehst direkt auf github:

      https://github.com/olkal/HX711_ADC/blob/master/examples/Read_2x_load_cell/Read_2x_load_cell.ino

      Bei 10 Waagen wird es mit den Pins eng. Ich würde dann einen MEGA2560 einsetzen. Und anders als in dem Beispielsketch würde ich die Waagen als Array anlegen, dann kannst du viel Schreibarbeit sparen.

  41. Hallo Wolfgang,
    natürlich auch von mir erstmal großes Lob zu diesem Projekt. Ich spiele mit dem Gedanken die Wiegezelle mit einem Schrittmotor zu kombinieren, damit ich Gewicht/Strecke abbilden kann. Wieviel Messwerte liefert den Dein Projekt den dafür und ließe sich das so umsetzen?

    1. Hallo Raik, wenn du mit „wieviel Messwerte“ die Messfrequenz meinst, dann ist die einstellbar. Laut Datenblattblatt lassen sich 10 oder 80 Messungen pro Sekunde (SPS) einstellen. Der Autor der Bibliothek hat 10 SPS eingestellt, um das Rauschen gering zu halten. Zusätzlich wird eine gewisse Anzahl von Messungen gemittelt. Dadurch werden die Messzeiten höher. Einstellen lässt sich das über die Datei Config.h (darin wird das auch erklärt). Voreingestellt ist ein Wert von 16. Die „Settling Time“ beträgt dadurch etwas mehr als 1.6 Sekunden. Durch Reduktion des Wertes bekommt man eine höhere Datenrate, aber auch mehr Rauschen. Müsstest du mit Rumspielen. Wenn man mit einer bewegten Messzelle vernünftige Werte ermitteln möchte, muss man nach Möglichkeit Vibrationen verhindern, da diese den Messwert schwanken lassen. Oder man mittelt genügend Messwerte, was dann aber wieder auf die Messfrequenz geht. Es gibt also keine ganz einfache Antwort!

      1. Moin Wolfgang, ich habe eine ähnliche Frage bezüglich des Themas.
        Ich habe vor einen Cocktailmixer mittels dieser Wiegezelle zu realisieren (Orangensaft einfüllen bis 200 Gramm dann Vodka einfüllen bis 250 Gramm usw…).
        Jetzt stehe ich allerdings vor dem Problem, dass dieses Programm je recht träge ist und das ganze so recht ungenau ist.
        würdest du mir noch etwas genauer beschreiben, wie ich das Ganze etwas schneller bekomme.

        1. Hallo Florian,

          die Antwort ist dieselbe wie oben. Die Einstellungen (Messrate und Anzahl der zu mittelnden Messwerte), die die Geschwindigkeit beeinflussen, kannst du in der Datei Config.h vornehmen. Das ist dort auch ganz gut kommentiert. Schnellere Messungen bedeuten mehr Rauschen. Wieviel mehr Rauschen auftritt und was für deine Anwendung akzeptabel ist, das musst du schlicht ausprobieren. Ich selbst habe mit diesen Parametern bisher nicht herum experimentiert. VG, Wolfgang

  42. Hallo Wolle,
    erst einmal mein dickes Kompliment für deine tollen Beiträge hier!
    Ich habe schon eine Menge gelernt!
    Vielleicht kann ich im Gegenzug auch ein wenig hilfreich sein:
    Du tatest dich mit der rechtsbündigen Ausgabe etwas schwer.
    Ich habe da eine, wie ich meine recht einfache Idee.
    Angenommen, du möchtest n Zeichen rechtsbündig ausgeben,
    dann beginne mit einem String mit n Leerzeichen und hänge das an, was du ausgeben möchtest.
    Dann nutze die Funktion substring ab length() – n.
    Dann stehen Deine Zeichen ganz rechts und der String hat die gewünschte Länge.
    Geht natürlich auch mit führenden Nullen oder anderen Zeichen Deiner Wahl.
    Viele Grüße
    Wolfram

    1. Hallo Wolfgang,
      ich habe mich nun auch ziemlich intensiv mit der rechtsbündigen Darstellung auf Displays beschäftigt. Ich finde, dass dtostrf() hier einen ziemlich guten Job macht. Damit reduziert sich die Aufgabe auf die Definition eines char[] und eine Zeile im Code. Funktioniert bei mir sehr gut.
      Beste Grüße

      Bernhard

  43. Hi Wolle,
    danke für die schnelle Antwort.
    Die Sensoren arbeiten jetzt genau, ich hatte keine Halterungen installiert, sodass die Sensoren nicht vernünftig arbeiten konnten. Mein Fehler 🙁
    den Schalter werde ich mal überdenken, wie und wo ich den im Sketch unterbringe.
    Habe heute recherchiert und bin auf eine AZ Delivery Lösung gestossen:#include

    Preferences preferences;

    void setup() {
    Serial.begin(115200);
    Serial.println();

    preferences.begin(„az“, false); //Ordner az anlegen/verwenden

    //preferences.clear(); //Alle „Dateien“ unter dem Ordner az löschen

    //preferences.remove(„Start“); //“Datei“ Start löschen

    unsigned int counter = preferences.getUInt(„Start“, 0); //“Datei“ Start auslesen und in Variable counter schreiben
    //“, 0″ bedeutet, falls Start nicht existiert standardwert 0 übergeben

    counter++; //Variable counter um 1 erhöhen

    Serial.printf(„Anzahl Starts: %u\n“, counter); //Variable counter Seriell ausgeben

    preferences.putUInt(„Start“, counter); //Variable counter unter „Datei“ Start speichern

    preferences.end(); //Preferences beenden

    Serial.println(„Neustart in 10 Sekunden…“);
    delay(10000); //Wartezeit 10000ms = 10s

    ESP.restart();
    }

    void loop() {}

    das werde ich mal verfolgen und möglicherweise, wenn das funktioniert mit einem MQTT Client einen Wert für den WägeSketch „PUSHEN“, sodass die Variable fürs Gewicht stimmt, ??hm. Vielleicht klappt das. Was meinst du?

    vg

    Gerd

  44. Hallo Wolle,

    bin durch Zufall auf deine Seite gestoßen und finde die sehr gut gelungen, danke fürs teilen.

    Meine Suche führte mich über den HX711 mit Wägesensor auf deine Homepage, sehr interessant auch für weitere Projekte.
    Mein Projekt, das mir schon lange im Kopf geistert ist folgendes:

    In unserem Wohnmobil habe ich EINE Propanflasche, bei der ich nie weiß, wie voll die ist. Immer ausbauen und auf die Personenwaage stellen ?, nee …
    Also 4 Fach ( jeweils 25Kg) Wägesensor über HX711 und ESP32 Mini D1 auswerten über MQQT auf einen Broker übertragen und dann mittels WebServer (der 2. Nodemcu) und altem ausrangierten Iphone5 anzeigen. Auf dem Iphone habe ich den geführten Betrieb eingestellt, dann läuft er nur noch der Webbrowser und stellt auch andere Sensorwerte zur Verfügung (Temp, Luftdruck, Luftfeuchte) dazukommen sollen noch Stromverbrauch, RestKapazität der Bordbatterien und mein Lieblingsprojekt Wasserstand für Frischwasser.

    Habe gestern Abend den WägeSensor verlötet, angeschlossen und in Betrieb genommen, abgesehen von vielen unterschiedlichen Werten !!??, läuft der Mechanismus aber erst mal provisorisch.

    Hab jetzt allerdings folgende Probleme bzw. Fragen, hoffe du kannst da weiterhelfen?
    1. Die Genauigkeit ist nach bisherigem Augenschein äußerst schlecht, permanent unterschiedliche Werte. Arbeite noch mit dem Calibrierungstool von Olav Kallhovd.
    2. Falls das mal irgendwann laufen sollte, stellt sich die Frage
    a. Wenn das Fahrzeug stromlos ist und wieder Plusspannung an den ESP kommt, wie kann ich erreichen, das der letzte Wert gehalten wurde, ohne das ich neu Kalibrieren muss, bzw. die Gasflasche neu aufsetzen muss? um einen Messwert zu erhalten?
    3. Wie kann ich erreichen, das nach Flaschenwechsel das Tara geändert werden kann, ohne Arduino usw. die Propanflaschen haben teilweise unterschiedliche Eigengewichte, die abgezogen werden müssen?

    Viel Grüsse und danke schon mal vorab für deine Mühe.

    VG

    Gerd

    1. Hi Gerd, also was sie Genauigkeit angeht, bin ich von diesen Wägezellen eigentlich absolut begeistert. I habe allerdings immer nur mit einer Zelle gearbeitet.

      Wenn du verhindern möchtest, dass eine Taramessung stattfindet, dann musst du nur im Beispielsketch boolean _tare = true durch boolean _tare = false ersetzen. Dann ermittelst du einmal das Leergewicht (was absurd hoch sein wird) und ziehst diesen Wert bei zukünftigen Messungen ab. Du hast dann sozusagen eine eingefrorene Tara.

      Wenn die Propanflaschen alle unterschiedliche Gewichte haben, wird es ein kleines bisschen schwieriger. Vom Prinzip her müsstest du jedes mal die oben beschriebene Prozedur mit der vollen Flasche wiederholen. Du bekommst dann halt negative Werte. Nun möchtest du wahrscheinlich nicht jedes mal wieder im Sketch den Startwert ändern und alles neu uploaden. Du könntest dafür einen extra Taster installieren und das Programm so ändern, dass beim Drücken des Tasters der Startwert gemessen und ins EEPROM geschrieben wird. Hoffe das hilft – viel Erfolg & Spaß.

      VG, Wolfgang

  45. Danke für die coole Doku!
    Ich verwende vier Loadcells + einen HX711. Das ganze Setup funktioniert einwandfrei. Fällt dir eine Möglichkeit ein auf den Taraknopf als Interrupt zu verzichten?
    Eine Änderung des Gewichts ist auch immer eine Änderung der anliegenden Spannung. Ließe sich das – irgendwie – als Interruptsignal nutzen?
    Mir selbst fällt um ehrlich zu sein nix ein, außer ein externen Input wie der Knopf oder ein weiterer Sensor (ich habe an einen Beschleunigungssensor gedacht – wobei ich mir nicht sicher bin, ob die Gewichtsänderung ausreichend ist).

    1. Hallo Daniel, ein ungewöhnlicher Wunsch. Die Spannungsänderung zu nutzen ist schwierig, da sie sehr klein ist. Deswegen benutzt man auch den HX711 mit seinen gigantischen 24 Bit Auflösung. Du kannst ja einfach die Gewicht regelmäßig abfragen. Und bei einer gewissen Ab- oder Zunahme in einer gewissen Zeit soll er eine Tara durchführen. Da muss man sich aber die Bedingungen genau überlegen. Wenn du etwas auflegst und durch die Gewichtsänderung eine Tara auslöst, dann nimmt er ja die Tara mit dem Gewicht drauf, das du messen willst – auch blöd. Ein Näherungssensor mit Interruptfunktion wäre vielleicht etwas: https://wolles-elektronikkiste.de/apds-9960-das-multitalent.

  46. Hallo Wolfgang
    Vielen Dank für Deine ausführliche Antwort. es war tatsächlich so dass ich den cal Factor durch Probieren ermitteln musste dann flutschte es. Leider Leider klappt es mit „dem Piepsen nicht Habe
    if (weightAsFloat>1000.0)
    { digitalWrite(13, HIGH)
    else
    digitalWrite(13, LOW)}
    eingefügt.
    Dann kommt „weightAsFloat‘ was not declared in this scope“
    ????? Hast Du noch ne Idee ? Das wäre toll Vielen Dank

    1. Hallo Hannes, jede Wägezelle hat ihren individuellen Kalibrierfaktor. Um die Kalibrierprozedur kommst du also nicht herum. Allerdings kann man sich die händische Übertragung der Kalibrierwerte sparen, wenn man sie ins EEPROM schreiben lässt. Dazu muss man nur die entsprechenden Programmzeilen entkommentieren.

      Wenn der Compiler weightAsFloat nicht erkennt, dann hast du entweder die Variable für das Gewicht anders benannt als ich oder du hat die Zeile an einer Stelle zugefügt an der sie nicht gültig ist. Und bei deinem eingefügten Code fehlen zwei Klammern: } else {

      Wenn du nicht klar kommst dann schick mir deinen Sketch per mail.

  47. Hallo Wolfgang, danke erstmal für diese sehr ausführliche und wirklich tolle Erklärung! Ich habe alles wunderbar umsetzen können mit meinem ESP-32 Adafruit Huzzah. Alles funktioniert einwandfrei.
    Allerdings brauche ich für mein Projekt ein WLAN fähiges Board und ich verwende hier das ESP8266 Feather Huzzah. Ich habe die Änderungen angenommen, die du ebenfalls erwähnt hast. Allerdings zeigt es mir nur komische Codes und am Ende „Starting…“ im Seriellen Fenster an und das wiederholt sich nach ein paar Sekunden. Ich habe die Baudrate angepasst und den richtigen Kalibrierungswert angegeben. Hättest du eine Idee für die Lösung meines Problems? Ich wäre sehr dankbar! Viele Grüße Sarah

    1. Hallo Sarah, wie es aussieht, schlägt hier der Watchdog Timer zu. Am Ende meines Beitrages über Watchdog Timer schreibe ich auch etwas über den ESP8266:

      https://wolles-elektronikkiste.de/watchdog-timer

      Due Kurzversion lautet: der ESP8266 hat einen Watchdog Timer, der eigentlich dazu dient abgestürzte Sketche durch ein Reset wieder zum Laufen zu bringen. Nur leider reagiert dieser Timer auch manchmal, wenn man es nicht möchte. Vor allem ist das bei while Schleifen, in denen nur gewartet wird, dass eine bestimmte Bedingung eintritt, der Fall. Der sogenannte Software Watchdog „beißt“ nach drei Sekunden. Wenn du in das setup die Zeile ESP.wdtDisable(); einfügst, stellst du den Software Watchdog ab. Leider gibt es dann noch den Hardware Watchdog, der ca. alle acht Sekunden zuschlägt. Probiere es mal. Wenn sich das Reset Interval auf acht Sekunden erhöht, dann weißt du zumindest schon mal, dass es genau dieses Problem ist. In den kryptischen Meldungen taucht dann auch irgendwo „wdt reset“ auf.

      Und dann musst du im Code nach Stellen suchen, wo der ESP8266 nichts macht außer warten und Bedingungen prüfen, also wie gesagt vor allem while Schleifen. Dort kannst du – wie man so schön sagt – den Watchdog füttern, indem du ein ESP.wdtFeed(); einfügst. Ggf. muss du auch ein ESP.wdtFeed(); in die Hauptschleife (loop()) einfügen. Melde dich nochmal, wenn es dann immer noch nicht geht. Und wenn es, geht wäre eine Rückmeldung auch nett! VG, Wolfgang

      1. Vielen Dank für die schnelle Rückmeldung! Ich werde es gleich ausprobieren und mich dann melden, ob es geklappt hat! Danke Wolfgang!

      2. Hallo Wolfgang,

        ich habe die Commands eingefügt, wie du es vorgeschlagen hast. Leider kommt immer noch die Meldung:
        ets Jan 8 2013,rst cause:4, boot mode:(3,6)

        wdt reset
        load 0x4010f000, len 3584, room 16
        tail 0
        chksum 0xb0
        csum 0xb0
        v2843a5ac
        ~ld

        Starting…

        Das wiederholt sich dann.
        Ich habe es mit 115200 probiert.
        Vielleicht hast du ja noch eine Idee, wie ich das ändern könnte? Danke und Viele Grüße Sarah

        1. Kannst du mir mal deinen ganzen Sketch schicken (wolfgang.ewald@wolles-elektronikkiste.de)? Vielleicht fällt mir ja etwas auf. Und dann könntest du auch mal schauen, wo das Programm aussteigt. Ich mache so etwas für gewöhnlich ganz pragmatisch, indem ich einfach systematisch „Serial.println(„Hallo hier ist Zeile X“); einfüge. So lässt sich eingrenzen, wie weit das Programm kommt.

  48. Hallo Wolfgang!
    Danke für die exacte Darstellung dieses tollen Projektes….
    Bei mir hat alles geklappt .Nach dem Tarieren g genaue Angabe des Gewichtes. Nur nach dem ich auch das Display angeschlossen habe stimmt irgendwas nicht mehr. Nach Drücken des TARA schalters kommt wait . Das Display zeigt dann 0 an. Lege ich aber ein Gewicht auf die Waade wird immer nur ca 1/4 des tatsächlichen Gewichts angezeigt. In der Wiederholung dann aber immer das gleiche exakte Gewicht. Mein Display unterscheidet sich von dem Deinigen bei der Pin belegung dass SDA ganz aussen ist und zwischen VCC und SDA ein PIN namens SCK statt SCL (bei Dir) ist. Die Belegung bei A4 und A5 habe ich dementsprechend geändert. Hast Du ne Idee? Und wenn ich schon beim Schreiben bin. Sicher kann man doch eine Funktion einfügen dass bei einem Gewicht von z.B. 1000g und mehr ein Signal ertönt. Vielen Dank für eine Antwort. Gruß Hannes

    1. Hallo Hannes, das ist ja sehr merkwürdig. Das Display kann ja nicht die Werte verändern. Wenn du die Daten gleichzeitig auf dem seriellen Monitor ausgibst, sind sie dann dort richtig? Mein Sketch ist hinsichtlich der Ausgabe auf dem Display recht spezifisch. Wird vielleicht einfach nur etwas abgeschnitten? Oder ist es wirklich immer ein Viertel? Das könntest du prüfen, indem du die Textgröße mit setTextSize mal änderst. Dass die Pins anders belegt sind bei deinem Display, kann eigentlich auch keinen Einfluss haben. Ich würde dann eher erwarten, dass es gar nicht geht. Vielleicht wiederholst du auch noch mal die Kalibrierung?
      Die Funktion mit der Gewichtswarnung ist kein Problem (if(weightAsFloat>1000.0) {…..}). Nur wie das Piepen ertönen soll, hängt natürlich davon ab, was du für einen Tongeber dran hängen hast. VG, Wolfgang

  49. Hallo Wolfgang,

    die Erklärung ist echt super!
    Aufgrund der Größe meiner Stockwaage und weil ich mehr Pins brauche, bin auch auf einen ESP32 umgestiegen.
    Hier habe ich ein Problem und evtl. hast du mir eine Idee oder einen Tipp. Der ESP32 bietet einen Deep Sleep an. Dieser Startet das ganze System neu und somit auch die Waage immer bei Null. Auf der Wage stehen aber die Bienenkästen und wenn das System bei Null startet, messe ich kein Gewicht. Ich zerbreche mir seit Tagen den Kopf, wie ich die Wage beim Reset richtig starte, aber das System nicht Null ausgibt.
    Hast du evtl eine Idee oder mir einen Tip. Das Prblem hatte ich auch beim Wemos D1.

    Gruß

    Kay

    1. Hallo Kay, du möchtest also keine Tara beim Start. Die kannst du verhindern, indem du _tare auf false setzt.

      boolean _tare = false;
      LoadCell.start(stabilizingtime, _tare);

      Den Wert, den du damit bei deiner ersten Messung ermittelst (der dürfte sehr groß sein) musst du dann später von deinen Messwerten abziehen. Eine fixe Tara, sozusagen.

      Hoffe das hilft!

  50. Hallo,
    ich habe eine Frage.
    Ich möchte gerne 2 Wägezellen benutzen. Eine Anzeige habe ich, ihr kann ich sagen das bei einem bestimmten Ohmwert 0kg und bei einem höheren Ohmwert zb 10kg sind. Die Werte dazwischen werden dann selbst erzeugt. Brauche ich dafür überhaupt den HX711?

    Gruß Peter

    1. Hallo Peter, die Wägezelle ändert ihren Widerstand mit dem Gewicht. Das funktioniert über Dehnungsmessstreifen. Der Effekt, also die Widerstandsänderung ist allerdings äußerst gering. Der Widerstand wird über die abfallende Spannung gemessen. Die Spannungsänderung ist entsprechend auch sehr gering. Da kommt der HX711 ins Spiel, der eine gigantische Auflösung von 24 bit (= 16.777.216) hat. Da ist zum Beispiel der A/D-Wandler des Arduino mit seinen 10 bit ( = 1.023) sehr grob dagegen. Das reicht schlicht nicht aus. Wenn man einen Widerstandsmesser mit ausreichender Empfindlichkeit hat, kann man sich den Umweg über den HX711 im Prinzip sparen. VG, Wolfgang

  51. Hallo zusammen,
    Ich möchte mir eine Waage bauen für meine Bienen Völker um die Futter Vorrat zu ermitteln.
    Die Bienen stehen ca.5 bis 10 Entfernung von meinem Haus entfernt,
    Mene Frage ;
    Könnte mir jemand helfen eine Waage zu bauen und die daten per SMS übermittelt?
    Danke im voraus
    Micha

    1. Hallo Micha,

      ich kann dir keine Fertiglösung anbieten, aber zumindest vom Prinzip her ist das nicht schwer. Du brauchst außer den im Beitrag beschriebenen Teilen lediglich ein SMS-fähiges Modul wie z.B. das SIM800L und eine SIM Karte. Ich wollte immer mal einen Beitrag über solche Module machen, bin aber noch nicht dazu gekommen. Nachteil ist, dass man erst mal die SIM Karte braucht mit der ganzen Registrierung und Identifikation und dann laufende Kosten für die SMS hat. Ich würde deshalb andere Möglichkeiten in Betracht ziehen. Reicht dein W-Lan vielleicht bis zu den Bienen? Dann könntest du die Daten auf den Browser übermitteln, z.B. mit einem WEMOS Board. Das habe ich hier beschrieben. Oder du könntest die Daten über IFTTT (if this then that) als Benachrichtigung (also nicht SMS) auf das Handy schicken. Das habe ich hier beschrieben. Oder Übermittlung per 433 MHz Funk, dann hast du die Daten allerdings nicht auf dem Handy, sondern auf einem zweiten Arduino, aber könntest sie z.B. auf einem Display anzeigen.

  52. Hallo Wolfgang,
    das ist ein tolles Projekt und ich möchte mich bei Dir für die klasse Dokumentation bedanken.
    Ich möchte mehrere Waagen gleichzeitig über längere Zeiträume betreiben um Gewichtsveränderungen zu protokollieren und dann grafisch darzustellen. Hast Du eventuell einen Tip für mich wie ich den Wert regelmässig an eine LANAdresse:Port senden kann um ihn dann dort mit vorhandenenTools abzugreifen und in eine DB zu schreiben bzw. grafisch aufzubereiten?
    Danke für jede Hilfestellung.
    Liebe Grüsse,
    Rudi

    1. Hallo Rudi,

      vielen Dank für’s Feedback. In meinem Beitrag über ESP-01 Boards habe ich beschrieben, wie man Daten per W-LAN an einen Browser sendet. Allerdings würde ich als Board nicht den ESP-01 nehmen, da er nicht genügend Pins hat. Nimm ein ESP-12 Board wie z.B. das WEMOS Board. Alternativ kannst du auch einen Arduino mit W-LAN oder LAN Modul einsetzen.

      Damit hast du allerdings die Daten erst im Browser, aber noch nicht in einer Datei oder Datenbank. Mit HTML kommt man da nicht weit, sondern müsste php oder Java Script Lösungen einsetzen. Damit müsste ich mich selbst auch erstmal beschäftigen. Aber dazu gibt es bestimmt einiges im Netz.

      VG, Wolfgang

  53. Hallo, ich habe die Waage bereits zum Laufen gebracht, verzweifle aber gerade an einer „Kleinigkeit?“.
    Ich möchte, dass sich die Waage nach dem Einschalten nicht automatisch tariert. Hab schon mit der calibrationValue experimentiert, kam aber zu keiner Lösung. Können Sie mir da Weiterhelfen?

    MfG
    Simon Wagner

    1. Hallo Simon, das haben wohl auch andere vermisst. Und die gute Nachricht ist, dass der Autor der Bibliothek da etwas implementiert hat. Installiere – falls nicht schon geschehen – die aktuellste Version der Bibliothek und schau dort in den Read_1x_load_cell.ino Beispielsketch. Anscheinend ist die LoadCell.start() Funktion erweitert worden. Ändere einfach _tare von true in false und schon wird nicht mehr tariert:

      boolean _tare = true; //set this to false if you don’t want tare to be performed in the next step
      LoadCell.start(stabilizingtime, _tare);

      Ich muss das gelegentlich mal in meinem Beitrag ergänzen.

  54. Hallo,
    danke für den Artikel. Ich habe da eine Frage zum Anschluss von mehreren Wägezellen an einer Waage (Gewicht soll über 3-4 Wägezelle gemessen werden). Kann man das über ein HX711 machen oder pro Wägezelle ein HX711? Ich habe zwar Schaltungen gefunden, wo 4 Wägezelle an einen HX711 angeschlossen wurden, diese Wägezellen haben aber nur 3 Kabel. Ist auch möglich, diese Art von Wägezellen (mit 4 Adern) an einem HX711 anzuschließen?
    Schonmal Danke und Grüße,
    Stefan

    1. Hallo Stefan,

      interessante Frage. Eigentlich hat der HX711 nur zwei Kanäle und die Bibliothek benutzt nur den Kanal A. Kanal B soll eine zu geringe Verstärkung haben um gut messen zu können. In der Bibliothek findet man einen Beispielsketch, der zeigt, wie man zwei (oder mehr) HX711 Module ausliest. Das würde bedeuten, dass man nur eine Wägezelle pro HX711 Modul auslesen kann. Kann es seine, dass dort wo mehrere Zellen verwendet werden, diese zusammengeschlossen sind? So etwas kann man machen, wenn man z.B. eine 200 kg Waage bauen will und die auf 4 x 50 kg Zellen aufgebaut ist. Dann liest du einen Gesamtwert aus. Ein individuelles Auslesen ginge nicht nach meinem Verständnis. Vielleicht kannst du mir mal den Link zusenden für das Beispiel, dass du gefunden hast.

      VG, Wolfgang

      1. Hallo Wolfgang,
        genau sowas ähnliches wie dein Beispiel (4x50kg > 200kg Waage) hatte ich vor.
        Ein Beispiel habe ich hier:
        https://youtu.be/LIuf2egMioA?t=40 (Schaltbild bei Sekunde 40)
        und bei der ct 2/2018 (leider hinter einer Paywall):
        https://www.heise.de/select/ct/2018/2/1515450954216728
        Bei beiden werden vier (dreiadrige) Wägezelle an ein HX711 angeschlossen und ausgelesen. Ein Beispiel mit vieradrigen habe ich leider nicht gefunden. Das Beispielsketch mit mit zwei HX711 Module habe ich auch gesehen. Ich hatte nur gehofft, dass es eine elegantere Lösung als vier HX711 gibt, weil dann das Kalibrieren etwas aufwändiger ist.

        Grüße, Stefan

  55. Hallo Wolfgang
    Dank Deinem Blog habe ich es geschafft 2 Waagen zu bauen, als Basis nutzte ich jedoch einen Wemos D1 mini. Eine Waage mit einer 20Kg Zelle und die Zweite mit 4 x 20Kg Zellen, das läuft mit dem CalibSketch und dem Sketch aus dem Abschnitt Regelbetrieb, tiptop.
    Ich schaffe es jedoch nicht dem Sketch mit TFT und Tara Button zum laufen zu bringen. Der D1Mini blinkt ununterbrochen nach dem Upload, das Display bleibt dunkel und im seriellen Monitor sehe ich nur wirre Zeichen.
    Hast Du mir ein Tipp woran das liegen könnte, respektive wie ich Deinen „TFT Tara Button Sketch“ auf einem D1 Mini zum laufen bringe? Als TFT habe ich übrigens SSD1306 und SH1105 zur Verfügung.
    Mit den Besten Grüssen
    Fredi

    1. Hallo Fredi,

      Fehlersuche aus der Ferne ist noch schwieriger als so schon. Ich würde jetzt so vorgehen:
      1) Prüfen, ob der Pull-Down Widerstand am Taster richtig verbunden ist
      2) wegen der wirren Zeichen: ist die Baudrate richtig eingestellt
      3) Generell alle Kabel überprüfen und evtl. mal austauschen (ich hatte mal ein kaputtes Steckbrückenkabel und habe mir einen Wolf gesucht)
      4) Das TFT Display mal entfernen – geht es jetzt mit dem seriellen Monitor?
      5) Das TFT Display separat versuchen „zum Laufen“ zu bringen.
      6) Ist die Displaygröße bei der Initialisierung richtig gewählt? display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

      Mehr fällt mir erstmal nicht ein. Wenn du das Problem identifizieren kannst, wäre es schön, wenn du das teilen könntest. Viel Erfolg!

      VG, Wolfgang

      1. Hallo Wolfgang
        Besten Dank für Deinen Input, werde mich der Sache annehmen und hier berichten. Vielen Dank für Deine Unterstützung.
        Fredi

  56. Hallo Wolfgang!
    Herzlichen Dank für die Zusammenstellung und das Bereitstellen der Informationen und Sketches zum HX711, dies hier hat erheblich zu meinem Verständnis der elektronischen Waage geholfen!

    Ich habe das ganze mit einem Arduino Nano ausprobiert, wenn ich Deinen Sketch mit Display und Tarafunktion verwende, sind Messungen zwar möglich, aber werden dauernd durch „Wait“ und einer (ungewollten) Tarierung der Waage unterbrochen, irgendeine Fehlerschleife muss vorliegen. Zuerst hatte ich einen defekten Taster in Verdacht, aber dieser ist in Ordnung,auch so erkenne ich jetzt keinen offensichtlichen Fehler in meiner Schaltung. Habe ich da vielleicht etwas übersehen?

    Herzliche Grüße,
    Marcel

    1. Wenn die Waage immer wieder tariert, wird anscheinend immer wieder ungewollt ein Interrupt ausgelöst. Da hätte ich auch als erstes den Taster im Verdacht gehabt. Da er es nicht ist, würde ich als nächstes den Pull-Down Widerstand überprüfen. Ist der richtig an GND angeschlossen? Wenn es das auch nicht ist, wird es schwieriger. Irgendwo her muss das High Signal ja kommen, das den Interrupt auslöst.

      Oder du drehst die Logik dann mal um – Interrupt wird bei „LOW“ ausgelöst:
      pinMode(interruptPin, INPUT) –> pinMode(interruptPin, INPUT_PULLUP) und
      attachInterrupt(digitalPinToInterrupt(interruptPin), taraEvent, RISING); –> attachInterrupt(digitalPinToInterrupt(interruptPin), taraEvent, FALLING);
      und natürlich den Pull-Down Widerstand entfernen und den Taster an GND anstelle VCC.

      1. Danke für den Tipp!
        Da lag dann auch der Fehler, der Pull-down-Widerstand lief ins Leere… Jetzt geht alles wie gedacht! Vielen Dank!

  57. Hallo und danke für den tollen Beitrag.

    Auf der Suche nach einer Möglichkeit Meßdaten, hier Gewicht zu erfassen, kam ich auf deine Seite.

    Eine Frage hierzu:
    Ich möchte Milligramm bis max. 200 Gramm zu erfassen, ist dieses hiermit möglich?

    Lieben Gruß

    1. Hallo, ich selbst habe nicht im Milligramm Bereich getestet, aber ich habe bei den Kundenfragen bei Amazon einen Hinweis für die 1kg Version gefunden:

      Welche empfindlichkeit hat dieser 1kg sensor? ab welchem gewicht misst er und wie genau? max. 1kg, richtig?
      Antwort:Ich habe damit el. Bauteile gewogen welche unter 1g Gewicht hatten. Referenzgewichte von 0.5g bis 50g zeigten bei 10 Versuchen immer denn richtigen, gleichen Wert.
      Von W. R. am 10. September 2019
      Der Sensor hat eine Empfindlichkeit von 1mV/V. Habe damit ein Wägesystem mit einer Auflösung von 10 mg aufgebaut. Die Linearität ist sehr gut.
      Von 10mg bis 1 kg keine Abweichung.
      Von Wolfgang… am 11. September 2019

      Zumindest 10 mg Auflösung scheinen zu funktionieren. Aber nochmal, ich habe es selbst nicht ausprobiert (das war ein anderer Wolfgang!).

      1. Hallo ersteinmal und vielen Dank für die super Anleitung 🙂 hat mir sehr geholfen. Für so genaue Messungen sollte man eh mehrere Wägezellen nutzen oder?
        Bei einer Wägezelle würden die Werte schon varieren, weil je nach Position des Gewichts auf der Platte sich der Hebel und sich damit die Biegung der Wägezelle ändert, ist das richtig?
        Das würde sich bei z.B. vier Wägezellen dann ausgleichen.
        VG Mirko

        1. Ich habe nicht ausprobiert was passiert, wenn man das Wägegut mal am Rand und mal in der Mitte. positioniert. Ich habe mir bei Wiederholungsmessungen aber auch keine besondere Mühe gegeben, das Wägegut exakt in der Mitte zu positionieren. Trotzdem habe ich immer wieder auf das Gramm genau denselben Wert gemessen (bei Gewichten von mehreren hundert bis eintausend Gramm).

  58. Danke für den tollen Beitrag!
    Das wollte ich schon lange mal ausprobieren. Die Teile liegen schon ewig bei mir rum.
    Bin über den stabilen Wert (ohne Schirmung) erstaunt.
    Viele Grüße aus dem Süden

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert