Seite 1 von 1
vorhandenen Code in Klasse packen
Verfasst: Samstag 3. August 2019, 10:05
von frost.1989
Hallo,
ich steuere mit einem Code einen Stepper-Motor an. Ich benutze dafür Micropython und einen ESP32. (funktioniert soweit)
Jetzt soll allerdings dieser Code in einer Klasse geschrieben sein.
Ich habe nur grundlegende Python Kentnisse und verstehe das Prinzip mit der Klasse nicht 100 prozentig.
Wäre jemand bereit diesen Code um eine Klasse zu erweitern? Der Motor soll anschließend das gleiche wie vorher machen. (Eine halbe Umdrehung, über move() in der Konsole)
Ich würde auch gerne eine Aufwandsentschädigung "zahlen" oder was auch immer.,
Alternativ würde ich mich über jede Hilfe freuen.
Dieses Thema ist nicht mein Fachgebiet.
Code: Alles auswählen
import machine
import time
# Definition der Pinbelegung
d1 = machine.Pin(19, machine.Pin.OUT)
d2 = machine.Pin(18, machine.Pin.OUT)
d3 = machine.Pin(17, machine.Pin.OUT)
d4 = machine.Pin(16, machine.Pin.OUT)
class Stepper():
def move(direction='counterclockwise'):
pins=[d1,d2,d3,d4]
if direction=='clockwise':
pins.reverse()
for steps in range(250):
for i in pins:
i.value(1); time.sleep(0.005); i.value(0)
steps+=1
move()
move('clockwise')
Re: vorhandenen Code in Klasse packen
Verfasst: Samstag 3. August 2019, 10:35
von __deets__
Da ist vieles im Argen. Auch ohne klasse. Die Idee, die drehrichtung über die Reihenfolge der Pins zu lösen, hat nicht nur unnötig hohe Kosten - sie ist auch falsch. Ruf mal zweimal clockwise hintereinander auf. Dann wird auch zweimal reversed. Und damit NICHT zweimal clockwise gedreht.
Das der schrittmotor sich so korrekt dreht kann ich mir auch nur schwer vorstellen. Entweder hast du einen Treiber verbaut der nur Richtung & schrittpuls kennt. Dann braucht’s aber nur zwei Pins. Oder 4 Pins (so wie dein Code suggeriert), doch dann muss da an den Pins ein bestimmtes Muster angelegt werden. Beschrieben zb hier :
https://www.tigoe.com/pcomp/code/circui ... er-motors/
Bist du sicher, dass das Ding vernünftig läuft?
Zum ersten Problem: da ist die Lösung einfach, statt die Datenstruktur zu manipulieren muss die Tabelle per Index durchlaufen werden, und die Schrittweite ist dabei entweder 1 oder -1. Dabei muss natürlich der Bereichsüber/unterlauf abgefangen werden. Klassisch so:
pos = (pos + direction) % len(tabelle)
Und dann zur Frage: die Klasse braucht einen Konstruktor. Der legt die Pins an, und merkt sich die, sowie die aktuelle Position in der Schrittansteuerungs-Tabelle.
Und dann kann man entsprechende Methoden aufrufen.
Re: vorhandenen Code in Klasse packen
Verfasst: Samstag 3. August 2019, 10:51
von __deets__
Und noch ein Problem: das steps += 1 ist wirkungslos, da steps in der for-Schleife der Wert neu zugewiesen wird. Kann also auch weg.
Re: vorhandenen Code in Klasse packen
Verfasst: Samstag 3. August 2019, 11:12
von Sirius3
Hast Du Dir schon ein Grundlagentutorial zu Klassen durchgearbeitet? Denn es hilft ja nicht viel, wenn jemand Dir das in eine richtige Klasse umschreibt, Du es aber dann nicht verstehst und auch nicht anwenden kannst.
Warum definierst Du d1 bis d4 die Du dann in eine Liste packst, anstatt die Pins gleich in eine Liste zu packen.
`i` ist ein ganz schlechter Name für einen Pin, `pin` wäre geeigneter. Pro Zeile nur eine Anweisung schreiben, vergiß am besten, dass es ; überhaupt gibt.
@__deets__: die Liste wird doch jedesmal neu erzeugt.
Re: vorhandenen Code in Klasse packen
Verfasst: Samstag 3. August 2019, 11:14
von __blackjack__
@__deets__: Das Problem mit dem `reverse()` sehe ich nicht – die Liste wird ja bei jedem Aufruf neu erstellt.
@frost.1989: Der gezeigte Code funktioniert so nicht, denn für die beiden `move()`-Aufrufe gibt keine Definition die da aufgerufen werden könnte → `NameError`.
Eingerückt wird in Python vier Leerzeichen pro Ebene.
`i` für etwas anderes als ganze Zahlen zu verwenden, insbesondere auch noch wenn es eine Laufvariable in einer Schleife ist, ist eine ganz schlechte, weil verwirrende Idee.
Das Semikolon wird in Python nur *sehr* selten verwendet. Eine Anweisung pro Zeile ist üblich.
Das erhöhen von `steps` am Ende der Schleife ist unsinnig weil der Wert beim nächsten Schleifendurchlauf sowieso gleich wieder überschrieben wird.
Re: vorhandenen Code in Klasse packen
Verfasst: Samstag 3. August 2019, 11:15
von __deets__
@Sirius3: wo du recht hast!
@TE: vergiss meine Bemerkungen zur Falschheit der Ansteuerung wegen dem Reverse. Teuer und mir unverständlich warum es funktioniert ist es immer noch, und ich würde bei meiner Lösung bleiben. Aber der grobe Schnitzer war bei meinem lesen. Nicht im Code.
Re: vorhandenen Code in Klasse packen
Verfasst: Samstag 3. August 2019, 11:30
von __blackjack__
Für eine Klasse gibt das IMHO keine Grund, die hätte ja nur eine `__init__()` und *eine* weitere Methode. Da reicht ein Closure (ungetestet):
Code: Alles auswählen
from machine import Pin
import time
STEPPER_PINS = [19, 18, 17, 16]
CLOCKWISE = 'clockwise'
COUNTERCLOCKWISE = 'counterclockwise'
def identity(argument):
return argument
def make_stepper_move(pin_numbers):
pins = [Pin(n, Pin.OUT) for n in pin_numbers]
direction2function = {
CLOCKWISE: reversed,
COUNTERCLOCKWISE: identity,
}
def move(direction=COUNTERCLOCKWISE):
direction_function = direction2function[direction]
for _ in range(250):
for pin in direction_function(pins):
pin.on()
time.sleep(0.005)
pin.off()
return move
move = make_stepper_move(STEPPER_PINS)
move()
move(CLOCKWISE)
Re: vorhandenen Code in Klasse packen
Verfasst: Samstag 3. August 2019, 11:44
von kbr
@frost.1989: Eine Klasse könnte so aussehen (wenngleich eine Klasse mit nur zwei Methoden, und eine davon __init__, etwas mager ist). Ich habe sie Dir geschrieben, damit Du lernbegleitend ein objektorientiertes Beispiel hast. Getestet habe ich es mangels geeigneter Hardware nicht.
Code: Alles auswählen
class Stepper:
def __init__(self, steps=250, duration=0.005):
self.pins = [machine.Pin(n, machine.Pin.OUT) for n in range(16, 20)]
self.steps = range(steps)
self.duration = duration
def rotate(self, clockwise=True):
pins = self.pins if clockwise else reversed(self.pins)
for step in self.steps:
for pin in pins:
pin.value(1)
time.sleep(self.duration)
pin.value(0)
stepper = Stepper()
stepper.rotate()
stepper.rotate(clockwise=False)
Re: vorhandenen Code in Klasse packen
Verfasst: Samstag 3. August 2019, 11:51
von __blackjack__
Wenn man `steps` zum Argument macht, dann wahrscheinlich eher von der `rotate()`-Methode. Vermute ich mal.
Edit: Das Closure noch mal überarbeitet:
Code: Alles auswählen
from machine import Pin
import time
STEPPER_PINS = [19, 18, 17, 16]
CLOCKWISE = 'clockwise'
COUNTERCLOCKWISE = 'counterclockwise'
def make_stepper_move(pin_numbers, duration=0.005):
pins = [Pin(n, Pin.OUT) for n in pin_numbers]
def move(direction=COUNTERCLOCKWISE, steps=250):
for _ in range(steps):
for pin in reversed(pins) if direction == CLOCKWISE else pins:
pin.on()
time.sleep(duration)
pin.off()
return move
move = make_stepper_move(STEPPER_PINS)
move()
move('clockwise')
Re: vorhandenen Code in Klasse packen
Verfasst: Samstag 3. August 2019, 12:02
von kbr
@__blackjack__: je nach gewünschter Flexibilität könnte man den Stepper natürlich entsprechend anpassen.