Nochmal nachgemessen, und zwar bei E+ / E- am HX711-Ausgang mit angeschlossener Wägezelle, die bogde-lib schaltet die Spannung dort ab, wenn der WiPy auf dem extension board sitzt und das expansion board über USB mit 5 V versorgt wird. Stöpsle ich aber das USB-Kabel ab und versorge den WiPy über einen LiPo – entweder über das expansion board oder direkt über Vin / GND – hat die Wägezelle immer Strom, hmm seltsam?!
Nun habe ich mit gpio_hold_en bzw. gpio_deep_sleep_hold_en() den state auch im deep sleep festgetackert und das geschilderte Problem.
Wohl doch, wenn ich den code wie oben habe läuft das 1x durch und dann tut sich nichts mehr (vermutlich weil der HX711) durch den “festgestellten” pin nicht mehr initialisiert werden kann.
Hier nochmal Verbrauchswerte des WiPys bzw. des HX711 mit / ohne Wägezelle
die Bosche H30-Waage und der HX711 verbrauchen ab scale.power_up();11 mA
wenn ich die Wägezelle abklemme braucht der HX711 alleine noch 3 mA
HX711 und angeschlossene Waage alleine nach scale.power_down(); und WiPy im deep sleep 450 n(!)A
der WiPy braucht mit nur deep sleep-sketch 15 uA
das Gesamtsystem aus WiPy, HX711 und Wägezelle braucht 45 mA wenn das System “wach” ist
im deep sleep braucht das Gesamtsystem 40 uA
Das ist doch Mist! D.h. der für die [edit, s.u.] scale.power_down();-Funktion auf high gehaltene SCK braucht 40 - 15 = 25 uA!! Echt Grütze!
Code dazu:
// timekeeping / deep sleep
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 20 /* Time ESP32 will go to sleep (in seconds) */
// HX711
#include "HX711.h"
HX711 scale;
const int scalePinDout = 12; // HX711.DOUT
const int scalePinSck = 13; // HX711.PD_SCK
void setup() {
// deactivate pin freezing after deep sleep
gpio_hold_dis(GPIO_NUM_13);
// scale
scale.begin(scalePinDout, scalePinSck);
scale.set_scale(22158);
scale.set_offset(-32625);
}
void loop() {
// output weight
scale.power_up();
float weight = scale.get_units(5);
delay(10000);
scale.power_down(); // put the HX711 in sleep mode
// freeze SCK pin state in deep sleep
gpio_hold_en(GPIO_NUM_13);
gpio_deep_sleep_hold_en();
// repeat every x seconds
delay(5000); // wait 5 s to see difference between scale.power_down(); und system deep sleep
esp_sleep_enable_timer_wakeup(uS_TO_S_FACTOR * TIME_TO_SLEEP);
esp_deep_sleep_start(); // sleep for ESP32
}
Gerade nochmal bei anderen Beispielen im Netz geschaut, die nutzen esp_deep_sleep[...] auch ohne explizites include von esp_sleep.h, ich vermute der ArduinoCore bindet das default ein.
Danke für die einzeilige Abkürzung! – btw. das ist auch der code für den ESP8266.
wo hast Du denn eigentlich die Ströme gemessen - zwischen LiPo und seinen Anschluß auf dem Board?
Mindestens 1R18 kannst Du ablöten (das hatten wir hier festgestellt), das spart schon mal auch 25µA (auf dem 5V -rail namens “+5V”; siehe power tree).
Der Wert von 25 µA ist etwas verwunderlich, denn es ist nicht so ganz klar, wie der sich zusammensetzt:
25 µA an 3,3V wäre ein 130 kOhm -R , die weak pull-ups im ESP32 haben aber eher zwischen ‘nur’ 30 - 70 kOhm (nominell 45 kOhm)
über die drive strength der GPIO im deep sleep ist leider nix bekannt: es waren mal 2 µA , das wurde wieder auf undefined geändert (finde Quellen dafür gerade nur für den ESP8266)
über input leakage ist natürlich im HX711-Datenblatt nichts zu finden (beim ADS1231 wären es ±10 µA)
Dann hilft also nur ein externer (very) weak pull-up: probiere doch mal 470k (ca. 7µA) oder 1 M (ca. 3,3 µA) von SCK nach 3V3. Vor dem Schlafengehen aber das pin von der IOMUX trennen, damit kein leakage current fließen kann, also irgendwie so hier:
Leicht off-topic bzgl. ArduinoCore, aber ich frage auch für einen Freund (MicroPython): Wir sollten das dann dort genauso machen, ja?
Sollte das dann bei allen GPIOs passieren, also von 0…N? Es scheint mir irgendwie auch für diejenigen relevant, die nicht nur für die Ansteuerung von Peripheriegeräten benutzt werden.
Ja high side mit dem CurrentRanger zwischen LiPo und dem Vin des WiPy.
Ich habe “als Referenz” erst mal beim WiPy gemessen, da man da weniger zusätzliche Teile hat und der als ESP32 board auch den kleinsten Verbrauch, soweit ich bisher recherchiert habe, hat. Die Werte stammen also nicht vom T-Call! Sorry, wenn ich da Verwirrung gestiftet habe!
hattest Du das nun mal probiert, @clemens, den internen PU abzuschalten und einen externen R (z.B. 470k, 1M) am SCK zu verwenden (gpio isolate nicht vergessen) und dann gemessen?
Bin hier nicht weiter gekommen, weil mein (einziger) WiPy jetzt 300 mA verbraucht und auf einem Bauteil auch super heiß wird, so dass man schon nach einer halben Minute den Finger nicht mehr auf ein paar offen liegende Widerstände legen möchte.
Ich weiß nicht, ob ich etwas zerschossen habe, mal mit einem pin versetzt aufs expansion board oder falsch herum. Es trat aber noch den Experimenten oben mit gpio_hold_en usw. auf. Wie es ausschaut überlebt der hold-Befehl einen deep sleep. Auch einen reset? Ich habe vom board schon alles mit erase_all entfernt, die Erwärmung tritt aber immer noch auf?.Defekte hardware oder könnte ich auch was fehl-konfiguriert haben? Falls da irgendwelche Stati eingebrannt werden, kann man die auch wieder für alle pins resetten?
Nun ist ein neuer WiPy da, aber ich komme auf andere Werte:
Mit den neuen Board messe ich um die 100 uA! Keine Ahnung warum. Mit nur deep sleep-sketch (ohne HX711) sind es wie bisher 15 uA.
Ich habe schon verschieden pins ausprobiert, auch welche, die nicht in der RTC-Domäne sind (stand was in einem post, dass da der leak current ggf. weniger wäre), habe versucht die internen pullups zu deaktivieren und durch einen externen (1M) zu ersetzen aber immer so um die 80 - 100 uA, also deutlich schlechter als mit dem alten WiPy-board (sind beide WiPy3).
Der letzte Code mit externem Pullup sah so aus:
// timekeeping / deep sleep
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 20 /* Time ESP32 will go to sleep (in seconds) */
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc.h"
#include "driver/rtc_io.h"
// HX711
#include "HX711.h"
HX711 scale;
const int scalePinDout = 2; // HX711.DOUT
const int scalePinSck = 27; // HX711.PD_SCK
void setup() {
// deactivate pin freezing after deep sleep
gpio_hold_dis(GPIO_NUM_27);
// scale
scale.begin(scalePinDout, scalePinSck);
scale.set_scale(22158);
scale.set_offset(-32625);
}
void loop() {
// output weight
scale.power_up();
float weight = scale.get_units(5);
delay(10000);
scale.power_down(); // put the HX711 in sleep mode
// freeze SCK pin state in deep sleep
rtc_gpio_isolate(GPIO_NUM_27);
gpio_hold_en(GPIO_NUM_27);
gpio_deep_sleep_hold_en();
// repeat every x seconds
delay(5000); // wait 5 s to see difference between scale.power_down(); und system deep sleep
esp_sleep_enable_timer_wakeup(uS_TO_S_FACTOR * TIME_TO_SLEEP);
esp_deep_sleep_start(); // sleep for ESP32
}
Unsicher war ich noch bei der Pin-Benennung bei rtc_gpio_isolate(GPIO_NUM_27); da gebe ich doch die GPIO-Nummer an und nicht die RTCIO-Nummer (hier 17), hatte beides Versucht, machte keinen Unterschied.
Boah, war das jetzt eine schwere Geburt! Das posting oben war (fast) finale die Kapitulation nach einem halben Tag Rumprobiererei. Nun funktioniert es! 16 uA!!
Es geht mit dem externen pullup nur in der rtc-Domäne, dabei ist rtc_gpio_isolate(GPIO_NUM_17); nicht zwingend nötig, da rtc_gpio_hold_en(GPIO_NUM_17); das wohl mit macht.
gpio_hold_en(GPIO_NUM_17); und gpio_deep_sleep_hold_en(); brachten nix, da man damit – wie es ausschaut – die internen pullups/downs nicht los wird, auch wenn man vorher die mit gpio_pullup_dis(GPIO_NUM_17); und gpio_pulldown_dis(GPIO_NUM_17); abzuschalten versucht, was wohl nicht in den deep sleep rübergerettet wird, sondern nur der state, wenn man gpio_deep_sleep_hold_en(); aufruft.
// timekeeping / deep sleep
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 20 /* Time ESP32 will go to sleep (in seconds) */
//#include "soc/rtc_cntl_reg.h"
//#include "soc/rtc.h"
#include "driver/rtc_io.h"
// HX711
#include "HX711.h"
HX711 scale;
const int scalePinDout = 2; // HX711.DOUT
const int scalePinSck = 27; // HX711.PD_SCK
void setup() {
// deactivate pin freezing after deep sleep
rtc_gpio_hold_dis(GPIO_NUM_27);
// scale
scale.begin(scalePinDout, scalePinSck);
scale.set_scale(22158);
scale.set_offset(-32625);
}
void loop() {
// output weight
scale.power_up();
float weight = scale.get_units(5);
delay(10000);
scale.power_down(); // put the HX711 in sleep mode
// freeze SCK pin state in deep sleep
// rtc_gpio_isolate(GPIO_NUM_27);
// rtc_gpio_isolate(GPIO_NUM_12);
rtc_gpio_hold_en(GPIO_NUM_27);
// gpio_deep_sleep_hold_en();
// repeat every x seconds
delay(5000); // wait 5 s to see difference between scale.power_down(); und system deep sleep
esp_sleep_enable_timer_wakeup(uS_TO_S_FACTOR * TIME_TO_SLEEP);
esp_deep_sleep_start(); // sleep for ESP32
}
vielen Dank für Deine Nachforschungen! Dazu passend habe ich hier die Implementierung im Pycom MicroPython herausgesucht. Die pin.hold()-API verwendet ebenfalls die rtc_gpio_hold_{en,dis}()-Funktionen.
Nachtrag: Der code mit rtc_gpio_hold_en(GPIO_NUM_27);funktioniert auch ohne externen pullup!! und liefert 15 uA Verbrauch im deep sleep ab, sowohl mit einem WiPy3 als auch mit einem LoPy4!
Auch der Terkin-Code läuft ohne externen pullup und wie momentan im repo mit 15 uA deep sleep! (mit WiPy, HX711, sonst keine Sensoren!) Perfekt! [edit] Der LoPy4 braucht im deep sleep ebenfalls nur 16 uA!
Ich verwende ESP8266, und meine Erkenntnis ist, das die GPIOs während Deep Sleep den Status nicht behalten (oder nur seeehr schwach), jedenfalls reicht es nicht um den HX711 im power down Modus zu halten.
Mit einem externen Pull-Up Widerstand ist das Problem gelöst, aber auch der sollte nicht zu schwach sein, folgende habe ich getestet:
56kOhm (~59µA bei 3.3V): HX711 geht in power down
560kOhm (~5.9µA bei 3.3V): HX711 geht nicht in power down. Das erklärt auch, warum die im Link erwähnten mutmaßlichen 2µA des ESP8266 im Deep Sleep nicht ausreichen.