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 sitzt ein Dehnungsmessstreifen, dessen 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. 

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 E+
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.h
// Arduino master library for HX711 24-Bit Analog-to-Digital Converter for Weigh Scales
// Olav Kallhovd sept2017
// Tested with      : HX711 asian module on channel A and YZC-133 3kg load cell
// Tested with MCU  : Arduino Nano, ESP8266
//-------------------------------------------------------------------------------------
// This is an example sketch on how to use this library
// Settling time (number of samples) and data filtering can be adjusted in the config.h file

// This example shows how to calibrate the load cell and optionally save the calibration  
// value to EEPROM, and also how to change the value.
// The value can later be fetched from EEPROM in your project sketch.

#include <HX711_ADC.h>
#include <EEPROM.h>

//HX711 constructor (dout pin, sck pin):
HX711_ADC LoadCell(4, 5);

int eepromAdress = 0;

unsigned long t = 0;

void calibrate() {
  Serial.println("***");
  Serial.println("Start calibration:");
  Serial.println("It is assumed that the mcu was started with no load applied to the load cell.");
  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 m = 0;
  boolean f = 0;
  while (f == 0) {
    LoadCell.update();
    if (Serial.available() > 0) {
      m = Serial.parseFloat();
      if (m != 0) {
        Serial.print("Known mass is: ");
        Serial.println(m);
        f = 1;
      }
      else {
        Serial.println("Invalid value");
      }
    }
  }
  float c = LoadCell.getData() / m;
  LoadCell.setCalFactor(c);
  Serial.print("Calculated calibration value is: ");
  Serial.print(c);
  Serial.println(", use this in your project sketch");
  f = 0;
  Serial.print("Save this value to EEPROM adress ");
  Serial.print(eepromAdress);
  Serial.println("? y/n");
  while (f == 0) {
    if (Serial.available() > 0) {
      char inByte = Serial.read();
      if (inByte == 'y') {
        #if defined(ESP8266) 
        EEPROM.begin(512);
        #endif
        EEPROM.put(eepromAdress, c);
        #if defined(ESP8266)
        EEPROM.commit();
        #endif
        EEPROM.get(eepromAdress, c);
        Serial.print("Value ");
        Serial.print(c);
        Serial.print(" saved to EEPROM address: ");
        Serial.println(eepromAdress);
        f = 1;

      }
      else if (inByte == 'n') {
        Serial.println("Value not saved to EEPROM");
        f = 1;
      }
    }
  }
  Serial.println("End calibration");
  Serial.println("For manual edit, send 'c' from serial monitor");
  Serial.println("***");
}

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

void setup() {
  Serial.begin(9600); delay(10);
  Serial.println();
  Serial.println("Starting...");
  LoadCell.begin();
  long stabilisingtime = 2000; // tare preciscion can be improved by adding a few seconds of stabilising time
  LoadCell.start(stabilisingtime);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Tare timeout, check MCU>HX711 wiring and pin designations");
  }
  else {
    LoadCell.setCalFactor(1.0); // user set calibration value (float)
    Serial.println("Startup + tare is complete");
  }
  while (!LoadCell.update());
  calibrate();
}
void loop() {
  //update() should be called at least as often as HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS
  //longer delay in sketch will reduce effective sample rate (be carefull with delay() in the loop)
  LoadCell.update();

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

  //receive from serial terminal
  if (Serial.available() > 0) {
    char inByte = Serial.read();
    if (inByte == 't') LoadCell.tareNoDelay();
    else if (inByte == 'c') changeSavedCalFactor();
  }

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

}

 

 

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:

Die Waage im "Regelbetrieb"
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 41 euren Kalibrierfaktor eintragen oder – falls ihr ihn im EEPROM habt – Zeile 45 entkommentieren. Ansonsten funktioniert der Sketch „out of the box“. Wenn ihr einen ESP8266 verwendet, müsst ihr zusätzlich noch Zeile 43 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>
#include <EEPROM.h>

//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;
long t;

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

  LoadCell.begin();
  float calibrationValue; // calibration value (see example file "Calibration.ino")
  calibrationValue = 696.0; // 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

  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) {
    float i;
    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. Ein bisschen Aufwand habe ich betrieben um das Gewicht rechtsbündig anzuzeigen. Das wird in der Funktion floatToDisplayString bewerkstelligt. Die Funktion ermittelt zunächst die Zahl der freien Stellen (blanks) und hängt dann das Gewicht als String dran. 

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 7 // we don't have a reset, but the constructor expects it 

Adafruit_SSD1306 display(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.73); 
}


void loop() {
  float weightAsFloat = 0.0;
  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){
  String weightAsString = "";
  weightAsString = floatToDisplayString(weight);
  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);
  }
}

void taraEvent(){
  taraRequest = true;
}

String floatToDisplayString(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; 
}

 

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 9 // we don't have a reset, but the constructor expects it 

Adafruit_SSD1306 display(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.73); 
  weightAsFloat = 0.0;
  lastWeightAsFloat = 9999.0;
  t = 0;
}

void displayWeight(float weight){
  String weightAsString = "";
  weightAsString = floatToDisplayString(weight);
  display.clearDisplay();
  display.setCursor(0,4);
  display.println(weightAsString);
  display.display();
}

/* The following function displays the weight. The weight is therefore
 * changed into a string. The weight shall be displaey on the right side,
 * therefore the string begins with blanks.  
 */
String floatToDisplayString(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; 
}

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

47 thoughts on “HX711 basierte Waage

  1. 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

  2. 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

  3. 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

  4. 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.

  5. 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.

  6. 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.

  7. 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

  8. 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!

  9. 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

  10. 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.

  11. 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

  12. 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.

  13. 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

  14. 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

  15. 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!

  16. 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).

  17. 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.