Moin zusammen,
ich hab ein kleines Problem: Ich programmiere mit micropython meinen
esp32 für den Antrieb eines StepperMotors.
Dazu habe ich eine Klasse mit Methoden geschrieben. Es funktoiniert auch
alles soweit und der Motor lässt sich steuern. Was ich aber nicht ganz
verstehe ist, sobald ich eine Methode zur Stuerung des Motors aufrufe,
wird bei mir die _init_-Methode auch immer wieder aufgerufen. Dies
erkenne ich daran, dass in meinem Ausgabefenster für jeden Schritt des
Motors "Init der Klasse" erscheint. Warum deklariert er jedes Mal das
Objekt neu?
Kann es eventuell daran liegen, dass man in der _init_-Methode keine
Ausgänge definieren darf?
Danke für die Hilfe.
Hier mein Code:
class stepper_motor() :
def
__init__(self,step=0,times=0.005,Seq=[],out1=16,out2=17,out3=18,out4=19)
:
'''Initialisierung der Klasse'''
import machine
print('Init der Klasse')
self.step1 = step
self.times = times
self.out1 = machine.Pin(out1, machine.Pin.OUT)
self.out2 = machine.Pin(out2, machine.Pin.OUT)
self.out3 = machine.Pin(out3, machine.Pin.OUT)
self.out4 = machine.Pin(out4, machine.Pin.OUT)
self.out1.value(0)
self.out2.value(0)
self.out3.value(0)
self.out4.value(0)
Seq = [[1,0,0,0],
[1,1,0,0],
[0,1,0,0],
[0,1,1,0],
[0,0,1,0],
[0,0,1,1],
[0,0,0,1],
[1,0,0,1]]
self.Seq = Seq
def setzPin(self,w1,w2,w3,w4):
'''Methode zur Setzung der Ausgaenge'''
self.out1.value(w1)
self.out2.value(w2)
self.out3.value(w3)
self.out4.value(w4)
def vorwaerts(self, step):
'''Methode für vorwaerts'''
import time
for i in range(step):
for j in range(len(self.Seq)):
stepper_motor().setzPin(self.Seq[j][0], self.Seq[j][1],
self.Seq[j][2], self.Seq[j][3])
time.sleep(self.times)
Ich habe in uPyCraft programmiert. Dies hat eine Eingabefenster, sodass
man direkt im esp32 programmieren kann. Alternativ kann man auch Putty
nutzen.
Dann kann man recht einfach den Code auf den esp32 laden und ausführen.
c = stepper_motor()
Mit dieser Zeile wird das Objekt erzeugt und initalisiert. Es erscheint
einmal Init der Klasse, was auch richtig ist. Danach rufe ich die
Methode auf:
c.vorwaerts(30)
Anschließend sehe ich im Ausgabefenster 30mal Init der Klasse
auffloppen. Das müsste meiner Meinung nach eigentlich doch nicht
auftauchen.
test schrieb:> ist natürlich falsch, es muss>> srlf.setzPin(self.Seq[j][0], self.Seq[j][1], self.Seq[j][2],> self.Seq[j][3])
Danke dir das hat geklappt. Endlich den Fehler gefunden :)
Kannst du mir erklären, warum ich eigentlich nicht stepper_motor().
schreiben darf?
test schrieb:> "import time" kann natürlich nach _init_
Dann bekomme ich einen Fehler gemeldet, dass er time nicht kennt. Ich
weiß zurzeit noch nicht wie ich auf die Bibliothek in der init
verweisen kann. Kannst du mir da weiterhelfen?
Danke
dux1 schrieb:> warum ich eigentlich nicht stepper_motor(). schreiben darf?
Weil das der Name der Klasse (eine reine Schablone nach der die Objekte
erstellt werden) ist.
Schreibt du das hin dann erstellt Python auf Basis der Klasse ein neues
Objekt (also der eigentliche Programmcode).
Also Klassen sind Definitionen für Objekte, Objekte ist das was man
nutzt.
Du hast deine stepper_motor Klasse, dann erstellst du im Programm
basierend auf dieser Klasse dein Motor Objekt. Und dieses Motor Objekt
nutzt du.
Hast du zwei Motoren dann erstellst du halt ein motor1 und ein motor2
Objekt basierend auf deiner stepper_motor Klasse (Theoretisch, praktisch
müsstest du deine Klasse dafür anders programmieren). Dann kannst du
motor1.vorwaerts und motor2.vorwaerts im Code benutzen.
Ich hoffe das war halbwegs verständlich. Wenn nicht gibt es hier sicher
welche die es besser erklären können.
Und ein Buch/Kurs über objektorientierter Programmierung wäre evtl. auch
hilfreich. Das sind so die Grundlagen.
dux1 schrieb:> test schrieb:>> "import time" kann natürlich nach init>> Dann bekomme ich einen Fehler gemeldet, dass er time nicht kennt. Ich> weiß zurzeit noch nicht wie ich auf die Bibliothek in der init verweisen> kann. Kannst du mir da weiterhelfen?> Danke
Kann auch sein das ich mich da jetzt vertan habe. Lass einfach so wenns
geht, schad ja nix. Sah für mich erstmal nur seltsam aus.
test schrieb:> Ich hoffe das war halbwegs verständlich. Wenn nicht gibt es hier sicher> welche die es besser erklären können.
Doch das war für mich verständlich. Danke dir :)
Ich habe mir den Code Deiner Schrittmotor-Klasse eben mal angeschaut,
und mir sind da noch ein paar andere Sachen aufgefallen, die ich
persönlich ändern würde:
- Die Methode "vorwaerts" funktioniert nach einer etwas fragwürdigen
Logik: Durch die verschachtelte Schleife kann man den Motor immer nur um
ein Vielfaches der hartkodierten 8 Halbschritte bewegen; man kann also
auch nur 1/8 aller möglichen Schritte anfahren
- Du hast den Namen der Klasse klein geschrieben. Normalerweise beginnen
Klassennamen mit einem Grossbuchstaben. Auf diese Weise kann man auch
schneller einer Klasse an sich und den Instanzen dieser Klasse
unterscheiden; das hätte in diesem Fall evtl. auch den ursprünglichen
Fehler vermieden
- self.step1 wird offenbar gar nicht benutzt, auch der der
__init__-Funktion übergebene "step"-Parameter hat somit keine Funktion
- Man kann der __init__-Funktion zwar einen "Seq"-Parameter übergeben,
der wird in der Praxis aber komplett ignoriert, stattdessen wird
self.Seq in der __init__-Funktion eh auf einen hartkodierten Wert
gesetzt. Weiterhin würde ich empfehlen, diese Variable nicht "Seq",
sondern "seq" zu nennen, weil der Name "Seq" (also mit Grossbuchstabe am
Anfang) halt suggeriert, dass es sich dabei um eine Klasse handelt
- Eventuell wäre es sinnvoll, "import time" aus der "vorwaerts"-Funktion
vor die Klasse zu verschieben, damit time nur ein einziges Mal
importiert wird, statt bei jedem Aufruf der vorwaerts-Funktion.
Weil ich den Grundgedanken Deiner Schrittmotor-Klasse aber gar nicht
schlecht fand und so etwas bislang noch nicht in meiner Sammlung hatte,
habe ich Deine Klasse übrigens etwas angepasst folgendermassen in meine
Sammlung aufgenommen:
Hallo Joachim S.,
danke dir für deine Hilfe. Man sieht das du dich schon ausführlich mit
der Thematik beschäftigt hast. Ich beschäftige mich erstmals mit Klassen
und Objekten. Ist ne Laboraufgabe bei uns.
Joachim S. schrieb:> Die Methode "vorwaerts" funktioniert nach einer etwas fragwürdigen> Logik: Durch die verschachtelte Schleife kann man den Motor immer nur um> ein Vielfaches der hartkodierten 8 Halbschritte bewegen; man kann also> auch nur 1/8 aller möglichen Schritte anfahren
Du hast in dieser Sache recht, aber wenn ich nur ein Vektor dieser
Sequenz ausführe bewegt sich der Motor nicht. Der brauch einmal den
kompletten Durchlauf. Oder die Bewegung ist so minimal, dass die mit dem
Auge nicht sichtbar ist.
Mfg dux1
test schrieb:> "import time" kann natürlich nach _init_
Blödsinn. Alle Importe kommen global oben hin, das ist so Usus, und das
ist sinnvoll, viele erfahrene Leute haben lange und hart nachgedacht um
die empfohlenen Gepflogenheiten zu erarbeiten.
Grundsätzlich gilt: Vieles was bei statisch getypten Sprachen vom
Compiler erzwungen wird muss man sich bei dynamischen Sprachen per
Konvention festlegen und sich auch sklavisch dran halten (also in dem
Fall die offiziellen Styleguides für Python) sonst verliert man schnell
den Überblick und driftet in ein unstrukturiertes Chaos ab und alle
anderen (allen voran auch das zukünftge Selbst nach einigen Jahren
Erfahrung) werden den lieblos hingeworfenen Code hassen und ihn
aufräumen wollen.
Der erste Schritt zu mehr diesbezüglicher Disziplin ist es im Editor
oder in der IDE den Linter einzuschalten und auf schärfste Stufe zu
stellen und dann so lange am Code zu arbeiten bis alle Warnungen
verschwunden sind. Manches mag überpenibel erscheinen aber alles hat
einen tieferen Sinn den man irgendwann erkennen wird - spätestens dann
wenn man mal Quellcode von jemand anderem in die Finger bekommt der alle
gut gemeinten Empfehlungen in den Wind geschossen hat.
dux1 schrieb:> Joachim S. schrieb:>> Die Methode "vorwaerts" funktioniert nach einer etwas fragwürdigen>> Logik: Durch die verschachtelte Schleife kann man den Motor immer nur um>> ein Vielfaches der hartkodierten 8 Halbschritte bewegen; man kann also>> auch nur 1/8 aller möglichen Schritte anfahren>> Du hast in dieser Sache recht, aber wenn ich nur ein Vektor dieser> Sequenz ausführe bewegt sich der Motor nicht. Der brauch einmal den> kompletten Durchlauf. Oder die Bewegung ist so minimal, dass die mit dem> Auge nicht sichtbar ist.
Klar, wenn Du jeden Halbschritte ansteuern kannst, statt wie in Deiner
aktuellen Fassung immer ein Vielfaches aller acht Halbschritte, dann ist
jeder einzelne Schritt nur noch 1/8 so gross. Wenn Dir die Schritte
damit zu klein sind, dann übergebe der vorwaerts()-Funktion doch einfach
einen 8-mal so grossen Wert?
Aber falls Du dennoch dabei bleiben willst, immer ein Vielfaches aller
acht Halbschritte zu gehen, dann macht es allerdings wenig Sinn,
überhaupt Halbschritte zu gehen - dann kannst Du auch gleich
Vollschritte gehen, indem Du Seq einfach abänderst in:
1
Seq = [
2
[1,1,0,0],
3
[0,1,1,0],
4
[0,0,1,1],
5
[1,0,0,1],
6
]
oder
1
Seq = [
2
[1,0,0,0],
3
[0,1,0,0],
4
[0,0,1,0],
5
[0,0,0,1],
6
]
Die erste Version hat ein kräftigeres Drehmoment, benötigt aber auch
doppelt so viel Strom.