PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : python code beenden/abbrechen und die GPIO's in einen neutralen zustand versetzen



inka
14.10.2021, 17:45
hallo allerseits.

ich taste mich zur zeit ganz langsam an den zero und python ran. Mein momentanes wissen reicht dazu folgenden code halbwegs zu verstehen, ihn über vnc und geany zu starten (das fliegermodell) und zu beenden (der rote punkt).


# https://cdn.shopify.com/s/files/1/0176/3274/files/MotoZero_User_Guide_1.2.pdf

from RPLCD.i2c import CharLCD

from gpiozero import Motor, OutputDevice
from time import sleep
from gpiozero import Button

lcd = CharLCD('PCF8574', 0x3f)

pin_a_HL = Button(19,pull_up=True) # Rotary encoder pin A connected to GPIO19
pin_b_HL = Button(26,pull_up=True) # Rotary encoder pin B connected to GPIO26

def pin_a_HL_rising(): # Pin A event handler
if pin_b_HL.is_pressed: print("-1") # pin A rising while A is active is a clockwise turn

def pin_b_HL_rising(): # Pin B event handler
if pin_a_HL.is_pressed: print("1") # pin B rising while A is active is a clockwise turn

#pin_a_HL.when_pressed = pin_a_HL_rising # Register the event handler for pin A
#pin_b_HL.when_pressed = pin_b_HL_rising # Register the event handler for pin B



motor_VL = Motor(24, 27)
motor_VL_enable = OutputDevice(5, initial_value=1)
motor_VR = Motor(6, 22)
motor_VR_enable = OutputDevice(17, initial_value=1)
motor_HR = Motor(23, 16)
motor_HR_enable = OutputDevice(12, initial_value=1)
motor_HL = Motor(13, 18)
motor_HL_enable = OutputDevice(25, initial_value=1)



def vorwaerts():
lcd.clear()
motor_VL.forward(0.5)
motor_VR.forward(0.5)
motor_HR.forward(0.5)
motor_HL.forward(0.5)
lcd.write_string('vorwaerts')
pin_a_HL.when_pressed = pin_a_HL_rising
pin_b_HL.when_pressed = pin_b_HL_rising
sleep(2)

def rueckwaerts():
lcd.clear()
motor_VL.backward(0.5)
motor_VR.backward(0.5)
motor_HR.backward(0.5)
motor_HL.backward(0.5)
lcd.write_string('rueckwaerts')
sleep(2)


def drehe_links():
lcd.clear()
motor_VL.backward(0.5)
motor_VR.forward(0.5)
motor_HR.forward(0.5)
motor_HL.backward(0.5)
lcd.write_string('drehe links')
sleep(2)

def drehe_rechts():
lcd.clear()
motor_VL.forward(0.5)
motor_VR.backward(0.5)
motor_HR.backward(0.5)
motor_HL.forward(0.5)
lcd.write_string('drehe rechts')
sleep(2)

def schiebe_links():
lcd.clear()
motor_VL.backward(0.5)
motor_VR.forward(0.5)
motor_HR.backward(0.5)
motor_HL.forward(0.5)
lcd.write_string('schiebe links')
sleep(2)

def schiebe_rechts():
lcd.clear()
motor_VL.forward(0.5)
motor_VR.backward(0.5)
motor_HR.forward(0.5)
motor_HL.backward(0.5)
lcd.write_string('schiebe rechts')
sleep(2)

def ende():
lcd.clear()
lcd.write_string('stop')
sleep(2)
lcd.clear()

while True:
vorwaerts()

rueckwaerts()

drehe_links()

drehe_rechts()

schiebe_links()

schiebe_rechts()

ende()


beim beenden des codes drehen sich manchmal zwei, manchmal aber auch drei oder eines der vier räder einfach weiter. Wie verhindere ich das ohne den zero ab- und wieder anzuschalten? Das booten ist sehr lästig...

Rabenauge
14.10.2021, 18:16
Hm, ich sehe da nix, was die Motoren stoppen könnte.
Du solltest das Drehen der Motoren sauber beenden...beispielsweise, indem du die Drehzahlen auf 0 setzt.

inka
14.10.2021, 19:02
esi ist doch folgendes:

wenn ich die "python loop" so gestalte:


#while True:
vorwaerts()

rueckwaerts()

drehe_links()

drehe_rechts()

schiebe_links()

schiebe_rechts()

ende()

läuft das ganze exakt 1x durch und die räder bleiben stehen. Egal ob im ersten oder zweiten fall (die loop), das drücken des roten punktes bei geany ist ja wohl sowas wie "CTRL C" und damit wird der code nicht sauber beendet, sondern irgendwo abgebrochen und die räder drehen weiter...

kannn ich das verhindern?

Rabenauge
14.10.2021, 22:33
Ja.
Indem du das Programm eben sauber beendest. Normalerweise ruft man Python-Programme ja nicht aus der IDE auf, du brauchst also sowieso irgendeine Abbruch-Möglichkeit?

Ich würde mir zumindest sowas wie nen Stop-Button anbauen, und wenn der auslöst, werden die Motoren kontrolliert gestoppt.

inka
15.10.2021, 11:56
ist das so, dass ich also immer - egal was für ein pythoncode auf dem raspi gestartet wird - irgendwas als stopvorrichtung (welches im code abgefragt wird) brauche, weil es beim raspi keine möglichkeit gibt einen laufenden code zu beenden ausser den stecker zu ziehen?

Rabenauge
15.10.2021, 18:52
Das ist doch auf dem PC mit jedem Programm so.
Die haben alle eine Möglichkeit, sie zu beenden (und wenn nicht, dann gibts dafür nen guten Grund, nämlich den, dass sie gar nicht beendet werden sollen).

Auch bei Arduino ist das grundsätzlich nicht anders- die Programme laufen entweder ewig, oder bis durch irgendeine Bedingung abgebrochen wird.
Zum testen könntest du einfach ne Zeitschleife einbauen, dass nach ner Minute Schluss ist oder so.
Wenn du ein Arduino-Programm einfach abbrichst (was allerdings kaum möglich sein dürfte, weil der bei allem und jedem nen Reset macht), dann bleiben die Pins auch in dem Zustand, den sie eben hatten, es sei denn, du sorgst dafür, dass sie das eben nicht tun.

inka
16.10.2021, 09:16
Du hast ja soo recht! Ich habs irgendwie immer noch nicht realisiert, dass ich mit dem zero einen PC im roboter hab. Auch weil der grössenunterschied zu einem ESP32 ja nicht soo gross ist. Und auch mit dem reset bei jedem abbruch beim ESP. Muss umdenken, vielleicht nehm ich doch was anderes zu der motorsteuerung statt dem zero...

Rabenauge
16.10.2021, 11:04
Warum denn?
Du musst doch nur eine Lösung finden, die Sache kontrolliert zu stoppen.
Hauptschalter wäre das simpelste-aber auch nicht besonders clever, da der Zero lieber runtergefahren werden möchte (tut der SD-Karte definitiv besser).
Entweder du baust nen Button an, der die Motoren stoppt, wann immer du willst, oder aber ne Zeitschleife.
Früher oder später brauchst du sowas ja ohnehin, schliesslich soll das Ding nicht endlos rumfahren, bis es an Strommangel verhungert.

Was auch geht ist ein Schalter, der einfach die Stromzufuhr zu den Motortreibern unterbricht. Das hat den Vorteil, dass man aufm Tisch auch mal coden kann, ohne dass das Ding dauernd unten liegt.

Ich sitze grade (so nebenbei) an ner Erweiterung für meinen Freddie II, der auch mal nen Zero als Master kriegen soll.
Einfach ums mal auszuprobieren (und weil Freddie sowieso drauf ausgelegt ist, mit verschiedener Hardware bestückt zu werden), und weil grade ein Zero hier nutzlos rumliegt. Hab mal wieder Lust, ein bisschen mit Python zu spielen, wenn die Flieger-Saison dann ganz vorbei ist hier oben.
Der wird allerdings die Motortreiber nicht direkt ansteuern, das macht der Fahrwerks-Rechner (ein Arduino Nano).