Ich steuere mit einem ESP32 4 DC Motoren (12V). Jeder Motor wird mit einer BTS7960 43A H-bridge gesteuert, welche vom ESP32 via PWM kontrolliert wird. Die Zuleitungen von den H-Bridges zu den Motoren ist über 1mm2 Klingeldraht von 1-3m Länge realisiert. Die Motoren werden von einem 14.4V Akku angetrieben. Das hat wunderbar funktioniert, so lange ich den ESP32 über einen kleinen Webserver am Handy bedient habe. Nun wollte ich die Schaltung mit 3 Buttons ergänzen, was auf dem Breadboard auch problemos funktioniert hat. Der Code für die Buttons ist hier: https://github.com/pluess/workbench-lift/blob/master/src/button.cpp Nachdem ich alles eingebaut hatte, gab es auf den GPIOs für die Buttons massenweise Geisterinputs. Die Buttons sind ca 1.5m vom ESP32 entfernt. Die Ursache war dann auch rasch gefunden: Die Zuleitungen für die DC Motoren und die Buttons liegen im gleichen Kabelkanal. Jedesmal wenn ein Motor ein-/auschaltet haben auch die GPIOs der Buttons reagiert. Ich werde die Kabel für die Buttons getrennt verlegen, ev. genügt das ja schon. Aber wenn ich schon mal dran bin: So viel ich ergoogelt habe wäre es sinnvoll vor den GPIOs einen physischen Pullupwiederstand und einen Kondensator einzubauen. Im Anhang seht ihr ein Foto der Schaltung und wie ich mir die Entstöhrung vorgestellt habe. Macht das so Sinn? Ev. gibt es ja noch bessere Lösungen. Ich habe z.B. noch ein paar NE555 rumliegen. Oder die Buttons mit einem ESP8266 auslesen und mit I2C Verbinden? Viele Grüsse Fredy
:
Bearbeitet durch User
Ernst P. schrieb: > Der Code für die Buttons ist hier: > https://github.com/pluess/workbench-lift/blob/master/src/button.cpp Nur weil man eine Funktion debounce nennt, entprellt sie noch lange nicht. Ich sehe darin nichts, was entprellen könnte. Eine Entprellfunktion muß ja Tastenänderungen sicher erkennen, d.h. braucht für jede Taste eigene Variablen zur Filterung. Bewährt hat sich eine Filterung über 4 oder mehr gleiche Zustände einer Taste je Zeitintervall (z.B. 10ms). Zusätzliche Hardware ist dann unnötig und die CPU-Last ist auch lächerlich gering.
Gut möglich, das es hier noch Verbesserungspotential gibt. Aber Entprellung ist hier nicht das Problem.
Ernst P. schrieb: > Gut möglich, das es hier noch Verbesserungspotential gibt. Aber > Entprellung ist hier nicht das Problem. Natürlich ist die fehlende Entprellung Dein Hauptproblem. Es gibt leider auch viele gewerbliche Programmierer, die das nicht einsehen wollen und der Benutzer muß dann darunter leiden (Aufzüge, Kaffeemaschinen, Oszilloskope und und und).
Ernst P. schrieb: > Nun wollte ich die Schaltung mit 3 Buttons ergänzen Du darfst die Dinger hier gerne "Taster" nennen ;-) > Nachdem ich alles eingebaut hatte, gab es auf den GPIOs für die Buttons > massenweise Geisterinputs. Wie sehen die "Geisterinputs" aus und wieviel Energie muss so eine Störung mitbringen, damit der ESP einen Puls erkennt. Vielleicht ist dein Eingang einfach zu hochohmig. Gegen kurze Störungen hilft ein Kondensator, aber bitte mit Serienwiderstand zur Strombegrenzung. Sonst gibt es jedes Mal beim Schließen des Kontaktes einen Funken, der langfristig deine Kontaktoberfläche verbrennt.
Ich bevorzuge immer die Entprellung/Entstörung eines ganzen IO-Ports per vertical Counter. Dann muß man nicht umständlich für jede Taste den Code copy & pasten. Das Main wählt dann einfach per Bitmaske aus, welche Taste man an einer Stelle gerade auswerten will. Ungenutze entprellte IO-Pins kosten weder Code noch RAM. Daß alle Pins parallel entprellt werden, macht es auch leicht, Zusatzfunktionen (repeat, lang/kurz Erkennung) zu implementieren. https://www.compuphase.com/electronics/debouncing.htm
:
Bearbeitet durch User
Ernst P. schrieb: > So viel ich ergoogelt habe wäre es sinnvoll vor den GPIOs einen > physischen Pullupwiederstand und einen Kondensator einzubauen. Im Anhang > seht ihr ein Foto der Schaltung und wie ich mir die Entstöhrung > vorgestellt habe. Macht das so Sinn? Ja. Die internen Pull-Up Widerstände im IC sind für die meisten Anwendungen zu hochohmig. Wegen Funkstörungen, aber auch weil die Kontakte der Taster ohne gemug Last nicht lange zuverlässig arbeiten. Gehe da ruhig auf 1k oder 2,2k Ohm runter. Ich würde noch 100 Ohm in Reihe zu den Tastern ergänzen, damit der Entladestrom (aus den Kondensatoren) nicht die Kontakte der Taster überfordert.
Monk schrieb: > aber auch weil die > Kontakte der Taster ohne gemug Last nicht lange zuverlässig arbeiten. Das betrifft nur Taster (250VAC/10A) für Grobmotoriker. Übliche Steuertaster (30V/100mA) brauchen keinen Frittstrom. Aber wie gesagt, wozu noch externe Hardware dranpappen, wenn ordentliche Firmware völlig ausreichend ist. Software schreibt man nur einmal, Hardware muß man jedesmal einlöten. Und als Lib ist das besonders komfortabel, man kann sie einfach einbinden und muß nicht jedesmal erneut darüber nachdenken, wie man eine Flanke erkennt usw.
:
Bearbeitet durch User
Ernst P. schrieb: > Der Code für die Buttons ist hier: > https://github.com/pluess/workbench-lift/blob/master/src/button.cpp Also mit C++ werde ich wohl nie warm werden. Man braucht Stunden, um sich durch die ganzen Abhängigkeiten der h- und cpp-Files durchzukämpfen, was wann passieren soll und wo. Das debounce prüft nur, ob zwischen 2 Aufrufen eine genügend lange Zeit vergangen ist. Wobei das nichtmal überlauffest passiert. Erfolgt dazwischen ein Überlauf, wird die Summe lastReadTime_ + DEBOUNCE_MILIS ganz klein und die Bedingung (fast) nie mehr wahr. Das check wiederum prüft nur, ob nach der Zeit eine Flanke erfolgt, mag sie auch noch so kurz sein. Da es in der Loop permanent aufgerufen wird, reagiert es sogar sehr wahrscheinlich auf jede Störung. Wie schon gesagt, eine Filterung (Test auf Plausibilität) erfolgt nirgends. Ich habe mir schon was dabei gedacht, daß bei mir die Filterung mit einem festen Zeitintervall im Timerinterrupt (Systick) erfolgt. Somit ist die Entprellung vollkommen unabhängig von jeglichen Programmlaufzeiten. Es werden sogar Tastendrücke gespeichert, wenn mal andere Tasks etwas länger beschäftigt sind und dadurch die Loop anhalten. Es gehen also keine Tastendrücke verloren, was auch ganz schön nervig für den Benutzer sein kann. Ich hatte auch erst mit nur 2 Samples gefiltert und dabei gemerkt, daß das noch nicht zuverlässig entprellt bzw. entstört. Daher habe ich den Code auf 4 gleiche Samples erweitert. Die Idee, zu den Tasten Callbacks zu hinterlegen, ist an sich nicht schlecht. Nur hat man oft Mehrfachbelegungen auf den Tasten und dann wird der ständige Wechsel der Callbacks schnell unübersichtlich und fehleranfällig. Ich bevorzuge daher, daß die gerade auszuführende Aktion direkt im jeweiligen Kontext steht und nicht irgendwo völlig anders.
Ernst P. schrieb: > Im Anhang seht ihr ein Foto der Schaltung und wie ich mir die > Entstöhrung vorgestellt habe. Macht das so Sinn? Nein, auch damit bekommst du irgendwelche Störungen (ohne 'h') nicht weg. Zumindest nicht zuverlässig. Und zeichen das nächste Mal besser einen Schaltplan deiner Schaltung. Du brauchst ihn sowieso, dass du in einem halebn Jahr noch verstehst, was du da gebastelt hast. > Ich habe z.B. noch ein paar NE555 rumliegen. Entprellung/Entstörung so eines Signals macht man in Software. Nicht in Hardware. > Oder die Buttons mit einem ESP8266 auslesen und mit I2C Verbinden? Abgesehen vom technischen Overkill ist das dann das Prinzip Hoffnung. Meinst du, die Störungen, die sich derzeit auf deinen Tasterleitungen finden, verschwinden dann auf dem I²C auf magische Weise? > Ich werde die Kabel für die Buttons getrennt verlegen, ev. genügt das ja > schon. Bis irgendwer in der Nähe eine Lampe oder gar den Mixer einschaltet... > So viel ich ergoogelt habe wäre es sinnvoll vor den GPIOs einen > physischen Pullupwiederstand Vorneweg: es ist ein Widerstand mit nur 1 'e' hinter dem 'd'. Wenn du bisher tatsächlich nur den eingebauten sehr hochohmigen 30..50k Pullup verwendest, dann wäre es zumindest nötig und sicher hilfreich, extern einen niederohmigen im Bereich 470R..1k an den Portpin zu schalten. Insofern würde dein Workaorund mit dem I²C sogar "besser" funktionieren als die Schaltung bisher, denn der I²C hat Pukkups zwischen 2k2 und 4k7. Peter D. schrieb: > Das debounce prüft nur, ob zwischen 2 Aufrufen eine genügend lange Zeit > vergangen ist. Richtig, der Name debounce() für diese Funktion ist absolut irreführend, das ist ein simples (nichtsperrendes) Delay aufwändig formuliert. > Somit ist die Entprellung vollkommen unabhängig von jeglichen > Programmlaufzeiten. Wenn man mit millis() arbeitet, dann bekommt man das genausogut (wenn auch nicht so kompakt) hin. Nur muss man eben den Taster auch tatsächlich mehrfach auf den selben Wert abfragen. Und nur, wenn der eingelesene Wert mehrmals (3..5x) innerhalb von z.B. 40ms immer gleich ist, dann liegt auch wirklich ein stabiler Wert am µC-Eingang an.
Peter D. schrieb: > Übliche Steuertaster (30V/100mA) brauchen keinen Frittstrom. Habe ich bei einigten Tastern anders erlebt. Aber ich verlange nicht, dass jeder die gleiche Erfahrung macht.
Peter D. schrieb: > Erfolgt dazwischen ein Überlauf, wird die Summe lastReadTime_ + > DEBOUNCE_MILIS ganz klein und die Bedingung (fast) nie mehr wahr. So passiert's, wenn jemand mit Integerrechnung nicht umgehen kann und schnell etwas hinpfuscht. Eigentlich ist das Problem gelöst: Beitrag "Re: Bug durch millis() Überlauf beim Vergleichen vermeiden"
Ernst P. schrieb: > Der Code für die Buttons ist hier: > https://github.com/pluess/workbench-lift/blob/master/src/button.cpp Ich hab ja doch riesen Probleme, mich durch C++ durchzufitzen. Und es wird auch nirgends kommentiert, wie der eigentliche Ablauf ist. Ich sehe nur, daß durch die Tasten irgendwelche Callbacks aufgerufen werden sollen, aber dann komme ich nicht mehr weiter. Versteht irgend jemand, wie sich die 4 Motoren mit den 3 Tasten steuern lassen und wo in dem ganzen Wust dieser Ablauf codiert ist?
Die .h Dateien kannst du für den Ablauf erstmal ignorieren. Den Ablauf sieht man in der main.cpp ganz unten. Das Programm läuft in einem “loop” und prüft dauernd ob einer der Buttons gedrückt oder losgelassen wurde(was keine Auswirkung hat). Wenn ein Button gedrückt wurde, wird die Funktion in Zeile 197 ausgeführt, welche den jeweiligen Motor in eine der 3 “Richtungen” (vorwärts, rückwärts und aus) drehen lässt.
Peter D. schrieb: > Also mit C++ werde ich wohl nie warm werden. me too, deine 10ms Timerentprellung bullet proof funktioniert auch prima am ESP!
Dennis S. schrieb: > Wenn ein Button gedrückt wurde, wird die Funktion in Zeile 197 > ausgeführt, welche den jeweiligen Motor in eine der 3 “Richtungen” > (vorwärts, rückwärts und aus) drehen lässt.
1 | void pushed(int pinNr) |
2 | {
|
3 | // LOG_INFO("touched pin: ", pinNr);
|
4 | for (int i = 0; i < motorArray.size(); i++) |
5 | {
|
6 | motorArray[i].setDirection(getDirectionFromPin(pinNr)); |
7 | }
|
8 | }
|
Das bringt mich leider auch nicht weiter. Welche der 3 Tasten bewirkt was? Wenn ich 4 Motoren mit 3 Tasten steuern sollte, würde ich das so implementieren: Taste 1: toggle Motor 1, Motor 2, Motor 3, Motor 4 Taste 2: toggle PWM 25%, 50%, 75%, 100% Taste 3: toggle Vorwärts, Stop, Rückwärts, Stop Kann es sein, daß mit den 3 Tasten nur die Richtung und Stop für alle 4 Motoren gleichzeitig gesetzt werden kann?
:
Bearbeitet durch User
> Kann es sein, daß mit den 3 Tasten nur die Richtung und Stop für alle 4 > Motoren gleichzeitig gesetzt werden kann? Ich seh in dem Code keine 3 Buttons, nur 2. Und einer davon steuert alle 4 Motoren in die eine, der andere Button alle 4 in die andere Richtung… wenn kein Button gedrückt ist bleiben die Motoren stehen.
Dennis S. schrieb: > Und einer davon steuert alle > 4 Motoren in die eine, der andere Button alle 4 in die andere Richtung… Das hatte ich befürchtet, die Tasten erlauben keine unabhängige Bedienung. Dennis S. schrieb: > wenn kein Button gedrückt ist bleiben die Motoren stehen. Da würde mich mal interessieren, wie das gehen soll. Beim Loslassen wird doch nur ein "tue nichts" Callback eingestellt:
1 | void released(int pinNr) |
2 | {
|
3 | // LOG_INFO("untouched pin: ", pinNr);
|
4 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.