Wägezelle mit HX711 ohne Library

Hallo zusammen,

ich beschäftige mich in letzter Zeit ein bisschen mit dem Arduino und versuche eine Wägezelle für 2kg aufzubauen. Das ganze hat auch sehr einfach und schnell mit der HX711.h library funktioniert aber richtig verstanden habe ich das ganze nicht. Jetzt versuche den gleichen Aufbau ohne Library zu programmieren und komme nicht weiter.

Bis jetzt habe ich versucht mit Hilfe des Datenblattes (http://image.dfrobot.com/image/data/SEN0160/hx711_english.pdf) und der HX711.h Library das Programm zu schreiben.

Gibt es Beispiele ohne eingebundene Library?

Es stellen sich mir noch sehr viele Fragen vielleicht kann mir da ja jemand weiterhelfen :slight_smile:
Hier mal ein paar Basics die ich noch nicht durchblicke.

Generierung des Pulses mit einer For schleife?:

   for (unsigned int i = 0; i < 25; i++) { //25 um in Channel A mit Gain 128 zu kommen 
   digitalWrite(4, HIGH);
   delayMicroseconds(1);
   digitalWrite(4, LOW);
   delayMicroseconds(1);
   }

Erfassen der Daten auf DTN in einem Array oder Variable?:

   data[0] = shiftIn(3, 4, MSBFIRST);

byte incoming = shiftIn(3, 4, MSBFIRST);

Vielen dank :slight_smile:

Gruß
Platanda

Eine Bibliothek gibt neue Funktionen. Diese Funktionen im Falle der HX711.h dienen dazu das HX711 anzusprechen bzw auszulesen.
Du kannst natürlich den HX711 direkt ansprechen. Dazu solltest Du aber

  1. verstanden haben wie der HX711 auf der Registerebene funktioniert.
  2. wie das Interface funktioniert.

Grüße Uwe

@TO: Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
So ist er auch auf portablen Geräten lesbar. Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

uwefed:

  1. verstanden haben wie der HX711 auf der Registerebene funktioniert.
  2. wie das Interface funktioniert.

zu 1) Ich habe schon bei einem anderen Projekt auf der Registerebene und der Assemblersprache gearbeitet. Das war allerdings noch auf dem MSP430 von Texas Instruments. Habe daher schon ein bisschen Erfahrungen in der Richtung sammeln können.
Trotzdem erschließt sich mir nicht wirklich wie ich die Programmierung angehe. Ich meine der Code in der HX711.h war auch in C++ geschrieben. Wofür brauche ich die Registerebene?

zu 2) verstehe nicht genau welches Interface du meinst? :wink:

Danke für die schnelle Antwort :slight_smile:

Platanda:
Ich meine der Code in der HX711.h war auch in C++ geschrieben. Wofür brauche ich die Registerebene?

Er meinte die Register des externen ICs. Das trifft hier aber nicht zu, da der HX711 anders funktioniert

verstehe nicht genau welches Interface du meinst

Die serielle Schnittstelle des ICs in diesem Fall

Hallo,

ich hab das noch nicht benutzt, aber ein Blick ins Datenblatt hilft in der Regel schon weiter.

link Datenblatt ob das jetzt Sinn macht das selber zu machen must Du entscheiden, ich denke ehr nicht.

Heinz

Hi

Wenn ich mir Das durchlese - viel Mehr, als DOUT LOW, beim ersten Impuls DOUT 'los lassen' - 24 Impulse rausschicken, um die 24 Bit Messwert zu erhalten und dann noch mit DOUT auf HIGH gezogen 1-3 Impulse für die nächste Messung (Gain ... A oder B ... whatever), sollte Es doch nicht sein, oder?
Wofür die Gain's sind ... vll. Mal mehr übersetzen, statt nur 'gain' ...

Man könnte aber Mal in die Lib reinschauen, ob man Das nicht nahezu auch so hätte lösen wollen - dann kann man sich Das nämlich wirklich sparen, da nichts Anders hinten bei rum kommt.

MfG

Platanda:
ich beschäftige mich in letzter Zeit ein bisschen mit dem Arduino und versuche eine Wägezelle für 2kg aufzubauen. Das ganze hat auch sehr einfach und schnell mit der HX711.h library funktioniert aber richtig verstanden habe ich das ganze nicht. Jetzt versuche den gleichen Aufbau ohne Library zu programmieren und komme nicht weiter.

Wenn Du die Arbeit mit der Lib (nicht deren Realisierung) nicht verstehst, ist die Wahrscheinlichkeit sehr hoch, dass Du ohne Lib noch größere Probleme hast, denn die Lib sollte für Dich das Handling vereinfachen.

Gruß Tommy

postmaster-ino:
Hi

Wenn ich mir Das durchlese - viel Mehr, als DOUT LOW, beim ersten Impuls DOUT 'los lassen' - 24 Impulse rausschicken, um die 24 Bit Messwert zu erhalten und dann noch mit DOUT auf HIGH gezogen 1-3 Impulse für die nächste Messung (Gain ... A oder B ... whatever), sollte Es doch nicht sein, oder?
Wofür die Gain's sind ... vll. Mal mehr übersetzen, statt nur 'gain' ...

Man könnte aber Mal in die Lib reinschauen, ob man Das nicht nahezu auch so hätte lösen wollen - dann kann man sich Das nämlich wirklich sparen, da nichts Anders hinten bei rum kommt.

MfG

Der Instrumentverstärker im HX711 hat 3 Verstärkungen. Es bedarf 24 Takte um die Daten der letzten A/D Wandlung aus dem HX711 zu lesen. Zusätzliche 1 bis 3 Takte stellen die Verstärkung bzw den Eingang für die darauffolgende A/D Wandlung ein.

Grüße Uwe

Aus dem Datenblatt:

Pin PD_SCK and DOUT are used for data retrieval, input selection, gain selection and power down controls.
When output data is not ready for retrieval, digital output pin DOUT is high. Serial clock input PD_SCK should be low.
When DOUT goes to low, it indicates data is ready for retrieval. By applying 25~27 positive clock pulses at the PD_SCK pin, data is shifted out from the DOUT output pin. Each PD_SCK pulse shifts out one bit, starting with the MSB bit first, until all 24 bits are shifted out.
The 25th pulse at PD_SCK input will pull DOUT pin back to high (Fig.2).
Input and gain selection is controlled by the number of the input PD_SCK pulses (Table 3). PD_SCK clock pulses should not be less than 25 or more than 27 within one conversion period, to avoid causing serial communication error.

Uwe

Danke für eure Antworten aber mir fehlt weiterhin ein Ansatz, wie ich beginne das ganze Aufzubauen...
Aus der HX711.h Library werde ich nicht schlau, wie das ganze funktioniert und auch aus dem Datenblatt gewinne ich keine weiteren Erkenntnisse.

Weiterhin meine Theorie:

  1. Checken ob der ADC Sendebereit ist (SCK=low, DOUT=low)

When output data is not ready for retrieval,
digital output pin DOUT is high. Serial clock
input PD_SCK should be low. When DOUT goes
to low, it indicates data is ready for retrieval.

  1. Einen Tackt erzeugen mit 25-27 positiven Impulsen
    --> Kann man das mit einer For schleife einfach machen ? Ich habe es versucht aber es hat nicht geklappt. Hat da jemand Erfahrungen?

By
applying 25~27 positive clock pulses at the
PD_SCK pin, data is shifted out from the DOUT
output pin.

  1. Zeitgleich schon die Daten erfassen:
    Weiter die Frage ob das mit einem Array möglich ist..? Hat da jemand Erfahrungen?
    Eventuell mit einem shiftIn()

Shifts in a byte of data one bit at a time. Starts from either the most (i.e. the leftmost) or least (rightmost) significant bit. For each bit, the clock pin is pulled high, the next bit is read from the data line, and then the clock pin is taken low.

Each PD_SCK pulse shifts out one bit,
starting with the MSB bit first, until all 24 bits are
shifted out.

  1. Empfangenen Bits durch Boolsche Operatoren bereinigen:
    The 25th pulse at PD_SCK input will
    pull DOUT pin back to high

  2. Umwandlung Bytes in Int

  3. Kalibrierung

6...

Ich sehe hierbei keinen Grund mit Registern zu arbeiten, oder übersehe ich etwas ?

Vielen Dank & schönen Sonntag noch !

Platanda:
Ich sehe hierbei keinen Grund mit Registern zu arbeiten, oder übersehe ich etwas ?

Register sind hier irrelevant, aber was Uwe damit gemeint habe hatte ich in #4 erklärt

also sowas… habe den Fehler endlich gefunden :cold_sweat: :cold_sweat: :cold_sweat: ich hatte zwischenzeitlich einen anderen ADC angeschlossen. Beim zurückbauen habe ich dann aber die CLK an Pin 2 angeschlossen :cold_sweat: :cold_sweat: :cold_sweat:
Das habe ich schnell in Code angepasst und jetzt läuft alles :slight_smile:

Vielen dank für eure Hilfe :slight_smile:
Topic kann geschlossen werden.
Hier nochmal der Code:

void setup() {
  Serial.begin(9600);
  int kali = 0;
  // put your setup code here, to run once: 
}

long auslesen() {
  // put your main code here, to run repeatedly:
  int CLK=2;
  int DOUT=3;
  pinMode(CLK, OUTPUT);
  pinMode(DOUT, INPUT);

  unsigned long value = 0;
  uint8_t data[3] = { 0 };
  uint8_t korrektur = 0x00;
  
  data[2] = shiftIn(DOUT, CLK, MSBFIRST); //1 Byte 
  data[1] = shiftIn(DOUT, CLK, MSBFIRST); //2 Byte
  data[0] = shiftIn(DOUT, CLK, MSBFIRST); //3 Byte
  
  for (unsigned int i = 0; i < 1; i++) {
    digitalWrite(CLK, HIGH);
    delayMicroseconds(1);
    digitalWrite(CLK, LOW);
    delayMicroseconds(1);
  }

if (data[2] & 0x80) {
    korrektur = 0xFF;
  } else {
    korrektur = 0x00;
  }

  value = ( static_cast<unsigned long>(korrektur) << 24
      | static_cast<unsigned long>(data[2]) << 16
      | static_cast<unsigned long>(data[1]) << 8
      | static_cast<unsigned long>(data[0]) );
  return static_cast<long>(value);
}

void loop(){
  Serial.println((auslesen()-117455)/436);
  delay(1000);
}

Tipp:
shiftIn() ist eine Funktion für den Umgang mit Schieberegistern.
Da gibts keine 25 oder 27 Takte. Nur vielfache von 8.
Sie MUSS also falsch, für diesen Zweck, sein.

Man braucht außer den 24 Takten für das Auslesen der Daten noch 1 bis 3 Takte für das programmieren des HX711. (Eingang und Verstärkung der nächsten A/D Wandlung)

Uwe

Platanda:
also sowas... habe den Fehler endlich gefunden :cold_sweat: :cold_sweat: :cold_sweat: ich hatte zwischenzeitlich einen anderen ADC angeschlossen. Beim zurückbauen habe ich dann aber die CLK an Pin 2 angeschlossen :cold_sweat: :cold_sweat: :cold_sweat:
Das habe ich schnell in Code angepasst und jetzt läuft alles :slight_smile:

Ok, diesen Fehler konnten wir nicht finden.
Danke für die Rückmeldung
Uwe