Forum: Mikrocontroller und Digitale Elektronik zwei Wägezellen an einem HX711 - Arduino Programmhilfe?!


von Flo K. (gasfisher)


Lesenswert?

Hallo zusammen,

ich will eine Waage mit zwei Wägezellen betreiben. Dazu verwende ich 
Wägezellen von Bosche H10A, einen HX711 AD Wandler und einen Arduino 
Uno.

Der HX711 hat zwei Kanäle, channel A und channel B.
Über die Einstellung des Gains lässt sich der jeweilige Kanal ansteuern.
Gain 128 ist für Kanal A und Gain 32 für Kanal B.

Ich bekomme auch beide Kanäle zum Laufen und kann mir die Werte anzeigen 
lassen. Das passt soweit. Problem ist, dass das nur einzeln 
funktioniert. Also wenn ich im Programm den einen Kanal oder den anderen 
verwende. Ich will aber gerne das beide im gleichen Programm 
funktionieren. Sodass ich zuerst Kanal A und dann Kanal B abfragen kann.

Leider spuckt er mir dann Müll aus. Sicher habe ich irgendwo einen 
Fehler...
Ich poste hier unten mal das Programm. Vielleicht hat ja jemand eine 
Idee wo der Fehler liegt???

(wenn ich in diesem Programm den entweder den Teil für Waage A oder B 
raus kommentiere, dann läuft es. nur eben nicht zusammen):
1
#include <Arduino.h>
2
#include "HX711.h"
3
4
// HX711 circuit wiring
5
const int LOADCELL_DOUT_PIN = 2;
6
const int LOADCELL_SCK_PIN = 3;
7
8
HX711 scale;
9
10
void setup() {
11
  Serial.begin(57600);
12
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
13
14
  Serial.println("Initializing scale A");
15
  scale.set_gain(128);
16
  scale.tare();               // reset the scale to 0
17
18
  Serial.println("After setting up the scale:");
19
  Serial.print("read: \t\t");
20
  Serial.println(scale.read());                 // print a raw reading from the ADC
21
22
  Serial.print("read average: \t\t");
23
  Serial.println(scale.read_average(20));       // print the average of 20 readings from the ADC
24
25
  Serial.print("get value: \t\t");
26
  Serial.println(scale.get_value(5));   // print the average of 5 readings from the ADC minus the tare weight, set with tare()
27
28
  Serial.print("get units: \t\t");
29
  Serial.println(scale.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided
30
            // by the SCALE parameter set with set_scale
31
32
  Serial.println("Readings:");
33
34
35
    
36
  Serial.println("Initializing scale B");
37
  scale.set_gain(32);
38
  scale.tare();               // reset the scale to 0
39
40
  Serial.println("After setting up the scale:");
41
  Serial.print("read: \t\t");
42
  Serial.println(scale.read());                 // print a raw reading from the ADC
43
44
  Serial.print("read average: \t\t");
45
  Serial.println(scale.read_average(20));       // print the average of 20 readings from the ADC
46
47
  Serial.print("get value: \t\t");
48
  Serial.println(scale.get_value(5));   // print the average of 5 readings from the ADC minus the tare weight, set with tare()
49
50
  Serial.print("get units: \t\t");
51
  Serial.println(scale.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided
52
            // by the SCALE parameter set with set_scale
53
54
  Serial.println("Readings:");
55
}
56
57
58
59
void loop() {
60
61
  scale.set_gain(128);
62
  scale.set_scale(299.604);
63
  
64
  Serial.print("S1: one reading:\t");
65
  Serial.print(scale.get_units(), 1);
66
  Serial.print("\t| average:\t");
67
  Serial.println(scale.get_units(10), 5);  
68
  delay(5000);
69
70
71
  scale.set_gain(32);
72
  scale.set_scale(66.398);
73
74
  Serial.print("S2: one reading:\t");
75
  Serial.print(scale.get_units(), 1);
76
  Serial.print("\t| average:\t");
77
  Serial.println(scale.get_units(10), 5);
78
79
 delay(5000);
80
}

[Mod: C-Tags das nächste mal bitte selber einsetzen.]

: Bearbeitet durch Moderator
von Rainer W. (rawi)


Lesenswert?

Flo K. schrieb:
> Ich poste hier unten mal das Programm. Vielleicht hat ja jemand eine
> Idee wo der Fehler liegt???

Welche Bibliothek verwendest du und wie muss die benutzt werden?
Fehlt in der Funktion loop() vielleicht ein scale.read()?

von Flo K. (gasfisher)


Lesenswert?

Das ist die "HX711 Arduino Library" V. 0.7.5
https://github.com/bogde/HX711

Dort steht dazu nur:
"It has a set_gain(byte gain) function that allows you to set the gain 
factor and select the channel. According to the datasheet,

Channel A can be programmed with a gain of 128 or 64, corresponding to a 
full-scale differential input voltage of ±20mV or ±40mV respectively, 
when a 5V supply is connected to AVDD analog power supply pin. Channel B 
has a fixed gain of 32.

The same function is used to select the channel A or channel B, by 
passing 128 or 64 for channel A, or 32 for channel B as the parameter. 
The default value is 128, which means "channel A with a gain factor of 
128", so one can simply call set_gain().

This function is also called from the initializer method begin()."

Damit komme ich aber leider nicht weiter. :(

von M. D. (derdiek)


Lesenswert?

Habs mal bei ChatGPT gepostet. Hier die Antwort:

Es scheint, dass das Problem in deinem Code darin besteht, dass du nur 
eine einzige Instanz der HX711-Klasse verwendest, um beide Wägezellen 
auszulesen. Die HX711-Bibliothek unterstützt jedoch nur eine einzelne 
Wägezelle. Um zwei Wägezellen gleichzeitig auszulesen, musst du separate 
Instanzen der HX711-Klasse für jede Wägezelle erstellen.

Hier ist eine überarbeitete Version deines Codes, die zwei 
HX711-Instanzen verwendet, um die Werte beider Wägezellen zu lesen:
1
#include <Arduino.h>
2
#include "HX711.h"
3
4
// HX711 circuit wiring
5
const int LOADCELL_DOUT_PIN_A = 2;
6
const int LOADCELL_SCK_PIN_A = 3;
7
const int LOADCELL_DOUT_PIN_B = 4;
8
const int LOADCELL_SCK_PIN_B = 5;
9
10
HX711 scaleA;
11
HX711 scaleB;
12
13
void setup() {
14
  Serial.begin(57600);
15
16
  Serial.println("Initializing scale A");
17
  scaleA.begin(LOADCELL_DOUT_PIN_A, LOADCELL_SCK_PIN_A);
18
  scaleA.set_gain(128);
19
  scaleA.tare(); // reset the scale to 0
20
21
  Serial.println("Initializing scale B");
22
  scaleB.begin(LOADCELL_DOUT_PIN_B, LOADCELL_SCK_PIN_B);
23
  scaleB.set_gain(32);
24
  scaleB.tare(); // reset the scale to 0
25
}
26
27
void loop() {
28
  // Read values from scale A
29
  scaleA.set_scale(299.604);
30
  scaleA.set_gain(128);
31
  Serial.print("Scale A: one reading:\t");
32
  Serial.print(scaleA.get_units(), 1);
33
  Serial.print("\t| average:\t");
34
  Serial.println(scaleA.get_units(10), 5);
35
  delay(5000);
36
37
  // Read values from scale B
38
  scaleB.set_scale(66.398);
39
  scaleB.set_gain(32);
40
  Serial.print("Scale B: one reading:\t");
41
  Serial.print(scaleB.get_units(), 1);
42
  Serial.print("\t| average:\t");
43
  Serial.println(scaleB.get_units(10), 5);
44
  delay(5000);
45
}
In diesem überarbeiteten Code werden zwei HX711-Instanzen (scaleA und 
scaleB) erstellt, um die Werte von Wägezelle A bzw. Wägezelle B zu 
lesen. Jede Instanz wird mit den entsprechenden Pins initialisiert und 
separat konfiguriert. Dadurch kannst du nun die Werte beider Wägezellen 
unabhängig voneinander abfragen.

Stelle sicher, dass du die richtigen Pins für LOADCELL_DOUT_PIN_A, 
LOADCELL_SCK_PIN_A, LOADCELL_DOUT_PIN_B und LOADCELL_SCK_PIN_B 
entsprechend deiner Schaltung konfigurierst.

Ich hoffe, das hilft dir weiter!

von Flo K. (gasfisher)


Lesenswert?

So sehen die Readings aus für den obigen Code und bei unbelasteten 
Zellen:

Readings:
S1: one reading:  -16.1  | average:  144.10020
S2: one reading:  651.2  | average:  -72.33651
S1: one reading:  -16.0  | average:  144.12023
S2: one reading:  649.6  | average:  -72.30639
S1: one reading:  -16.0  | average:  144.06015
S2: one reading:  650.3  | average:  -72.24615

Hier habe ich ein Gewicht von 1300g auf S1 gebracht:
S1: one reading:  329.6  | average:  144.11022
S2: one reading:  650.2  | average:  1487.60498
S1: one reading:  329.7  | average:  144.13024

und hier das Gewicht von S1 auf S2 rüber gebracht:
S2: one reading:  6752.2  | average:  -72.24615
S1: one reading:  -16.0  | average:  1496.41857
S2: one reading:  6752.4  | average:  -72.36664
S1: one reading:  -16.0  | average:  1496.46533


Also irgendwas läuft da schief... aber ich stehe voll auf dem Schlauch! 
:((
Würde mich freuen, wenn mir jemand weiterhelfen könnte!

von Flo K. (gasfisher)


Lesenswert?

M. D. schrieb:
> Stelle sicher, dass du die richtigen Pins für LOADCELL_DOUT_PIN_A,
> LOADCELL_SCK_PIN_A, LOADCELL_DOUT_PIN_B und LOADCELL_SCK_PIN_B
> entsprechend deiner Schaltung konfigurierst.
>
> Ich hoffe, das hilft dir weiter!

Danke für die Antwort!
Aber ich glaube das ist falsch.
Der HX711 hat ja zwei Channels für die beiden Waagen. Und vom HX711 geht 
man dann auf nur zwei Pins des Arduinos. Nicht auf 4 wie in deinem Code 
oben.
So wie du das beshcreibst könnte ich ja gleich zwei HX711 anschließen.

von A. Z. (donvido)


Lesenswert?

Vielleicht prüfst du bevor du ließt erstmal, ob das Teil überhaupt 
bereit ist?!
1
scale.is_ready();

von Ingo W. (uebrig) Benutzerseite


Lesenswert?

Soweit ich in Erinnerung habe, bestimmt die Anzahl der Leseimpulse, den 
Kanal und die Verstärkung der nächsten Messung. Daher würde ich mal 
die erste Messung auf dem neuen Kanal verwerfen, wiederholen und das 
zweite Ergebnis verwenden.

von Flo K. (gasfisher)


Lesenswert?

Also irgendwi eglaube ich es liegt an der Initialisierung.
Wenn ich nämlich wie unten die Initilisierung einer Waage 
rauskommentiere, dann funktioniert die andere korrekt. Umgedreht 
ebenfalls.
1
void setup() {
2
  Serial.begin(57600);
3
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
4
/*
5
  Serial.println("Initializing scale A");
6
  scale.set_gain(128);
7
  scale.tare();               // reset the scale to 0
8
9
  Serial.println("After setting up the scale:");
10
  Serial.print("read: \t\t");
11
  Serial.println(scale.read());                 // print a raw reading from the ADC
12
13
  Serial.print("read average: \t\t");
14
  Serial.println(scale.read_average(20));       // print the average of 20 readings from the ADC
15
16
  Serial.print("get value: \t\t");
17
  Serial.println(scale.get_value(5));   // print the average of 5 readings from the ADC minus the tare weight, set with tare()
18
19
  Serial.print("get units: \t\t");
20
  Serial.println(scale.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided
21
            // by the SCALE parameter set with set_scale
22
23
  Serial.println("Readings:");
24
25
*/
26
    
27
  Serial.println("Initializing scale B");
28
  scale.set_gain(32);
29
  scale.tare();               // reset the scale to 0
30
31
  Serial.println("After setting up the scale:");
32
  Serial.print("read: \t\t");
33
  Serial.println(scale.read());                 // print a raw reading from the ADC
34
35
  Serial.print("read average: \t\t");
36
  Serial.println(scale.read_average(20));       // print the average of 20 readings from the ADC
37
38
  Serial.print("get value: \t\t");
39
  Serial.println(scale.get_value(5));   // print the average of 5 readings from the ADC minus the tare weight, set with tare()
40
41
  Serial.print("get units: \t\t");
42
  Serial.println(scale.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided
43
            // by the SCALE parameter set with set_scale
44
45
  Serial.println("Readings:");
46
  
47
}
48
49
void loop() {
50
51
  scale.set_gain(128);
52
  scale.set_scale(299.604);
53
  Serial.print("S1: one reading:\t");
54
  Serial.print(scale.get_units(), 1);
55
  Serial.print("\t| average:\t");
56
  Serial.println(scale.get_units(10), 5);  
57
  delay(5000);
58
59
60
  scale.set_gain(32);
61
  scale.set_scale(66.398);
62
  Serial.print("S2: one reading:\t");
63
  Serial.print(scale.get_units(), 1);
64
  Serial.print("\t| average:\t");
65
  Serial.println(scale.get_units(10), 5);
66
67
 delay(5000);
68
}

: Bearbeitet durch User
von Harry L. (mysth)


Lesenswert?

Was ist an
"Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang"
eigentlich so schwer verständlich???

Alles, was nicht auf eine Bildschirmseite passt, ist "längerer Code"!

von Rainer W. (rawi)


Lesenswert?

Flo K. schrieb:
> Also irgendwi eglaube ich es liegt an der Initialisierung.

Du musst jedes Mal nicht nur Kanal und Gain umschalten, sondern auch den 
Offset wieder passend neu setzen.

: Bearbeitet durch User
von Flo K. (gasfisher)


Lesenswert?

Ok!
Danke für den Tip!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.