Posts by Dennis89

    Hallo,

    Aber das kann ich eigentlich auch alles mit while lösen (glaube ich jedenfalls)

    und mit 'if'. Das Konzept könnte so aussehen: In einer Dauerschleife wird die aktuelle Position abgefragt, dann wird mit 'if'-Abfragen den Unterschied zwischen Ist und Soll ermittelt und entsprechend reagiert, sprich dem betreffenden Motor einen Impuls senden .


    Zu deinem Code:

    In Python schreibt man alle Namen klein_mit_unterstrich, Ausnahmen sind Konstanten KOMPLETT_GROSS und Klassen in PascalCase-Schreibweise.

    Auf Modulebene, der Code ohne EInrückungen, sollte kein ausführbarer Code stehen. Hier werden nur Konstanten, Funktionen, Klassen und der Einstiegpunkt in 'main' definiert. 'main' ist die Funktion, aus der das Programm gesteuert werden sollte. Hier könntest du deine Sensoren etc. definieren und dann an die Klasse übergeben.

    Wenn du sprechende Namen verwendest, sparst du dir einige Kommentare.

    'root.destroy()' wird nie aufgerufen, denn du verlässt die 'mainloop' nicht.

    'self.vor_aktion' ist zwar mit Hilfe deines Kommentars nachvollziehbar, bzw. man versteht was du machen willst, aber im Laufe des Codes ist es nicht gerade selbstredent. Du könntest auch einfach mit Worten angeben, was die vorherige Aktion war.

    Werte muss man in Pyhton nicht zwingend vorbelegen. Wenn man den Wert allerdings inerhalb der Klasse benötigt und nicht nur in einer Funktion einer Klasse, dann kann man Werte mit 'None' vorbelegen. 'self.PWMLI-wert' und 'self.PWMRe_wert' werden nur in Funktionen benötigt. Es wird nie der Wert, der daran gebunden wird abgefragt. Erst nach dem er in einer Funktion gesetzt wurde. Das heißt du benötigst kein 'self' und kannst den Namen in der Funktion definieren und verwenden.

    In 'AbstandVorne' definierst du Namen und bindest sie an 'self'. Üblich ist es, dass diese Namen in der '__init__' definiert werden. Ist aber nicht nötig, da der vorherige Wert nicht relevant für dich ist und du immer den aktuellen brauchst. Weiter ist es auch nicht nötig, da du 'sensor_vorne.distance' direkt abfragen kannst. Die Skaliererei der Werte wird wohl Geschmackssache sein.

    Die Steuerung der Leds würde ich in eine Funktion auslagern. Auch hier würde ich nicht immer hin und her rechnen, sondern einfach die Werte nehmen und anpassen.

    Hier mal ein ungetesteter Zwischenstand:

    Es fehlt noch einiges, aber du hast ja erwähnt das du noch nicht fertig bist.


    Viel Erfolg

    Dennis


    Edit: Ob die Steuerung an sich so für dein Vorhaben sinnvoll ist und/oder genau genug musst du natürlich auch selbst über denken. Die Steuerung der Led's benötigt ja auch schon Zeit, in der sich das Objekt bewegt.

    Hallo,


    der Code, der letztendlich den Text auf dem Display ändern soll ist dieser:

    Was soll deiner Meinung nach durch diesen Code auf dem Display passieren?

    Ich frage deshalb, weil hier im Bruchteil von Sekunden 11 verschiedene Texte an das Display gesendet, dann noch zwei Bytearrays und dann wird etwas in den RAM geschrieben (das passiert in der Funktion 'display').


    Schreib doch mal einen Text und mach dann eine Pause von zwei drei Sekunden (Stichwort 'sleep(2)') und dann den nächsten Text mit einer anderen Größe um zu sehen ob die sich ändert.


    Ich bin mir auch nicht sicher ob die Zahlen, die du übergibst die Schriftgröße ist oder die Position wo der Text stehen soll. Denn diese Angabe fehlt mir irgendwie. Im Quelltext werden die zwei Argumente mit 'width' und 'height' bezeichnet. Hm daraus kann ich nicht sicher sagen, was es letztendlich ist.

    Aber du hast das Display und kannst das mal versuchen.


    Grüße

    Dennis

    Hallo,


    hast du dir mal die Werte des Sensors ausgeben lassen? Bitte poste die vollständige Fehlermeldung.


    'as' wird zum umbenennen verwendet, du nennst GPIO in GPIO um. In Python wird ausführbarer Code nur in Funktionen definiert. Verwende konstant 4 Leerzeichen zum einrücken. 'var1' und 'var2' sagen einem Leser leider nicht viel. Du kannst den Datentyp auch gleich bei der Temperaturabfrage ändern, dafür brauchst du nicht einen weiteren Namen verwenden.

    Du erstellst in jedem Schleifendurchgang ein neues 'dhtDevice'-Objekt. Das würde man vor der Schleife einmal machen und dann damit in der Schleife arbeiten. Und wenn man schon dabei ist, in Python schreibt man Namen klein_mit_unterstrich. Ausnahmen sind Klassen in PascalCase-Schreibweise und Konstanten KOMPLETT_GROSS.


    Hast du keine weitere Fehlermeldung erhalten? GPIO benötigt noch einen 'cleanup' Aufruf.


    Grüße

    Dennis

    Hallo,

    da wird einiges an Grundlagenwissen m.E. sogar übersprungen

    wenn du die Programmiersprache lernen willst, dann könntest du das offizielle Tutorial dazu durcharbeiten:

    https://docs.python.org/3/tutorial/


    Wenn du etwas für eine bestimmte Anzahl machen willst, dann brauchst du eigentlich nicht unbedingt eine Dauerschleife, sondern du könntest eine Schleife verwenden, die eine bestimmte Anzahl an Durchläufen hat. In dem Fall wäre das eine for-Schleife mit der Funktion 'range'. Dadurch musst du selbst auch keinen Zähler mehr einabuen:

    'range(20)' gibt in jedem Durchgang von 0 beginnend die Zahl erhöht um eins zurück, bis 20 Durchläufe um sind. Die Zahl wird an einen Namen gebunden. In meinem Beispiel ist der Name, der Unterstrich. Das verdeutlicht dem Leser, dass mit der Nummer im Code nichts weiter passiert. Will man im Code mit der Nummer aber auch noch was machen, dann ersetzt man den Unterstrich durch einen sprechenden Namen und kann ihn dann verwenden.


    Grüße

    Dennis

    Hallo,


    Bisher habe ich gehört, dass Stepmotor sinnvoller wären, da man damit besser Anfang und Ende steuern kann

    der Vorteil ist, dass du in vielen Fällen um einen zusätzlichen Drehgeber drum herum kommst, dann die Schritte die der Schrittmotor macht gezählt werden können. Dann weist du wie weit sich der Motor gedreht hat. Das Problem für dein Anfang und Ende ist, dass dein Motor nicht weis wo das ist und auch nicht wo er selbst ist. Es werden nur Schritte gezählt.

    Wenn dein Kabel ganz aufgewickelt ist und du schließt deine Schaltung an und weist das du 200 Schritte bis Ende fahren musst, dann ist das ok. Du bist bei Systemstart auf 0 Schritte und dann geht los. Was aber, wenn du irgendwo in der Mitte stehst, zum Beispiel wegen eines Stromausfalls? Dann weist du nicht mehr wie weit du hoch oder runter fahren musst.


    Also es wird noch eine Referenz, bspw. ein Näherungsschalter, damit du irgendwie deine Position bestimmen kannst und bei Stromausfall eine Referenzfahrt machen kannst. Möglicherweise kannst du aber auch einen "normalen" Motor nehmen und einfach zwei Endlagenschalter um den Motor bei Anfang und Ende anzuhalten?


    Grüße

    Dennis

    Hallo,


    hier habe ich das mal detailliert und mit möglichst sprechende Namen, dass du siehst was gemacht wird, aufgeschrieben:


    Und zusammengefasst im Code:

    Code
    arguments = "-c:(125,25,30)"
    colors = [int(color) for color in arguments.replace('-c:', '').replace('(', '').replace(')', '').split(',')]
    print(colors)
    print(type(colors[0]))


    Grüße

    Dennis

    Hallo,


    in einer Unterhaltung hat sich ergeben, dass die eingesetzen Encoder sehr oft Probleme mit prellen haben.

    Hier habe ich mal eine stark vereinfachte Klasse geschrieben, die nur auf eine Flanke reagiert, keine Bitmuster abfragt und der du eine Entprellzeit mitgeben kannst.


    Da dein Handler ja eigentlich auch nichts anderes macht als +1 oder -1 zu rechnen, habe ich darauf mal verzichtet.

    Zum testen der Klasse, kannst du zum Beispiel sowas machen:

    Die Klasse unter 'Rotary.py' speichern. In meinem Beispiel ist 16 der Clock-Pin, 17 der Direction-Pin und 10 ist die Entprellzeit in Millisekunden. Damit kannst du ja etwas spielen, bis alles so funktioniert wie du willst.


    Könntest auch noch einen PWM-Pin definieren und Duty-Cycle abhängig vom Encoder laufen lassen und dann nochmal messen. Also sowas:


    Jeder Code ist ungetestet. Default-Wert für die Frequenz liegt (glaube ich) schon bei 5kHz, die müsste man nicht extra angeben.


    Grüße

    Dennis

    Hallo,


    Bernd666 ein Entprellen des Encoders kann ich in der Klasse nicht finden. Meiner Meinung nach wird lediglich der gesetzte Wert der Pins abgefragt und mit dem vorherigen Wert verglichen und je nach Zustand eine entsprechende Funktion aufgerufen.


    Franky07 eventuell ist "deine" Klasse nicht robust genug gebaut und schedule hat nicht genügend Durchsetzungskraft um jeden Puls zeitgerecht durchzusetzen. Dazu findet man in der Doku auch soetwas:


    Der ESP32 hat ja von Haus aus schon einen Pulse-Counter mit an Board, der ist also bestens dazu geeignet die Änderungen des Encoders zu zählen. Infos dazu findet man hier:

    https://docs.espressif.com/pro…nce/peripherals/pcnt.html


    Leider kannst du diese Funktion nicht in deiner MicroPython-Version finden.

    Es wäre aber denoch interessant wie sich dein Encoder mit dieser Funktion verhalten würde. Glücklicherweise gibt es jemand, der genau diese Funktion in MicroPython implementiert hat. Dazu musst du allerdings diese Version nutzen:

    https://github.com/deets/micropython/tree/mcpwm-and-encoder


    Die Doku dazu:

    https://github.com/deets/micro…kref.rst#pcnt-pin-counter


    Und um die MicroPython-Version zu kompilieren:

    https://github.com/bskp/microp…v-esp32-mcpwm/ports/esp32


    Ich habe das vor einiger Zeit erfolgreich verwendet. Der ESP32 hatte damit auch keinerlei Probleme die Impulse einer 60kHz Frequenz zu zählen.


    So, nur mal das du siehst, welche Möglichkeiten dir der ESP32 bietet. Ob das verwenden einer anderen MicroPython-Version zu aufwendig für ein Lernprojekt ist, kann ich nicht beurteilen. Aber ich denke die jetzt verwendete Klasse wird auch nur unbetrachtet im Hintergrund "stehen", dann könnte man auch den PCNT verwenden.


    Grüße

    Dennis


    Edit: Weitere Infos und auch eine Alternative zu "deiner" Klasse ist unter folgendem Link zu finden:

    https://forum.micropython.org/viewtopic.php?t=7685

    Hallo,


    nur mal ganz kurz: hast du den Encoder mal an andere GPIO's angeschlossen, weil 9, 10 und 11 sind laut hier nicht für Input geeignet.


    Schau dir mal die Seite an, da gibts noch eine recht schöne Tabelle.



    Grundsätzlich ist der ESP32 für sollche Aufgaben bestens geeignet.


    Grüße

    Dennis

    Hallo,

    Warum hast du noch die 256 in 255 geändert?

    Weil mit 256 der erste Schleifendurchgang 0 geben müsste und erst ab der zweiten Schleife werden die Zahlen von oben nach unten gezählt. Wenn ich 256 genommen hätte, dann hätte ich einen unschönen Sprung erwartet, wenn man die Schleife langsam laufen lässt.


    Hab das aber selbst nicht testen können.

    Du kannst ja mal die Werte ändern und dir die Werte, mit dem Rechenergebnis mit 'print' ausgeben lassen, dann siehst du was ich meine.


    Schön das alles geklappt hat.


    Grüße

    Dennis

    Es ist ja nicht nur ein Minus. Jetzt wird nicht mehr von 0 aufwärts gezählt, sondern von 255 abwärts. Dadurch drehen sich die 'wheel'-Argumente im Vergleich zum originalen Code.


    Von

    Code
    for j in range(255 * iterations)

    zu

    Code
    for j in range(255 * iterations, 0, -1)

    Grüße

    Dennis

    Hallo,


    mal etwas Abwechslung für Zwischendurch

    Alle Beispiele drehen im Uhrzeigersinn, nur der Rainbow.Cycle nicht. Kann man bei dem die Richtung tauschen?

    Was passiert damit wenn du die Funktion so änderst:

    Code
    def rainbowCycle(strip, wait_ms=20, iterations=5):
        """Draw rainbow that uniformly distributes itself across all pixels."""
        for j in range(255 * iterations, 0, -1):
            for i in range(strip.numPixels(), 0, -1):
                strip.setPixelColor(i, wheel(
                    (int(i * 256 / strip.numPixels()) + j) & 255))
            strip.show()
            time.sleep(wait_ms / 1000.0)


    Ich habe sowas noch nie angesteuert, aber das wäre mal meine erste Idee.


    Grüße

    Dennis

    Nach dem Erkennen eines Magneten kommt das:

    Ich hatte die falsche Exception verwendet :blush:



    Grüße

    Dennis