Probelm Mit GPIO in kombination Mit Meim Python Programm

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Nitram1
User
Beiträge: 4
Registriert: Donnerstag 9. November 2023, 09:23

Guten Tag erst einmal.

ich Entschuldige mich im Voraus Für Rechtschreibfehler (Tut mir leid)

Info1: Mein Project ist im grunde ziemlich "simpel". mit python Servomotoren (6 stück) steuern um eine schöne kleine bewegung mit einem Roboterarm zu machen

Info2: ich habe bilder mit einem/ von einem Oscilloscope [weiß nicht wie ich sie hier teilen kann durch das Linux System und weil ich auf einem Raspberry pi arbeite (Bilder sind auf dem Raspberry Pi und auf meinm Handy)]

Info3: die bilder sind ziemlich größ 700x1000 pixel

Folgendes Problem stellt sich mir in den weg: wenn ich das Programm (siehe weiter unten) Starte (zum testen weiß nämlich nicht ob es Funktionirt so wie ich es braue) Läuft es eigentlich ganz gut also der duty cycle kommt usw wenn ich dan das program mit "KeyboardInterrupt" (strg c) Stoppe kappt der Raspberry pi die verbindung nicht sonndern sendet weiter signale/impulse

Falls mir jemand erklären kann wie ich die bilder hier her bekomme wäre ich sehr dankbar und es erklärt sich bbesser mit den bildern

Code: Alles auswählen

import RPi.GPIO as GPIO
import time

servoPIN1 = 26
servoPIN2 = 16
servoPIN3 = 27
servoPIN4 = 17
servoPIN5 = 24
servoPIN6 = 23

GPIO.setmode(GPIO.BCM)
GPIO.setup(servoPIN1, GPIO.OUT)

GPIO.setup(servoPIN2, GPIO.OUT)

GPIO.setup(servoPIN3, GPIO.OUT)

GPIO.setup(servoPIN4, GPIO.OUT)

GPIO.setup(servoPIN5, GPIO.OUT)

GPIO.setup(servoPIN6, GPIO.OUT)

a = GPIO.PWM(servoPIN1, 50) # GPIO 17 als PWM mit 50Hz
a.start(7.5) # Initialisierung

b = GPIO.PWM(servoPIN2, 50) # GPIO 17 als PWM mit 50Hz
b.start(7.5) # Initialisierung

c = GPIO.PWM(servoPIN3, 50) # GPIO 17 als PWM mit 50Hz
c.start(7.5) # Initialisierung

D = GPIO.PWM(servoPIN4, 50) # GPIO 17 als PWM mit 50Hz
D.start(7.5) # Initialisierung

e = GPIO.PWM(servoPIN5, 50) # GPIO 17 als PWM mit 50Hz
e.start(7.5) # Initialisierung  

f = GPIO.PWM(servoPIN6, 50) # GPIO 17 als PWM mit 50Hz
f.start(7.5) # Initialisierung

def berechne_duty_cycle(winkel):
    return (winkel / 180) * (180 - 90) + 2.5		#  berechnet den duty cycle 

try:
    while True:
        servo_positions = [
            [90, 90, 90, 90, 90, 90],		
            #  Die winkel zu denen sich dier servos bewegen solle 
            #[45, 60, 90, 81,"skip","skip"],
            #[60, 81, 45, 90,"skip","skip"],
            #[81, 45, 60, 90,"skip","skip"]
        ]

        for position in servo_positions:
            for winkel in position:
                duty_cycle = berechne_duty_cycle(winkel)
                if winkel != "skip":
                    duty_cycle = berechne_duty_cycle(winkel)
               
                a.ChangeDutyCycle(duty_cycle)
                time.sleep(0.1)

                b.ChangeDutyCycle(duty_cycle)
                time.sleep(0.1)

                c.ChangeDutyCycle(duty_cycle)
                time.sleep(0.1)

                D.ChangeDutyCycle(duty_cycle)
                time.sleep(0.1)

                e.ChangeDutyCycle(duty_cycle)
                time.sleep(0.1)

                f.ChangeDutyCycle(duty_cycle)
                time.sleep(0.1)

            time.sleep(1)  # Warte 1 Sekunde am Ende jeder Iteration

    


except KeyboardInterrupt:
  a.stop()
  b.stop()
  c.stop()
  D.stop()
  e.stop()
  f.stop()
  GPIO.cleanup() 
  
danke im voraus
L.G.
LRS und Totmüde = Beste Kombination
Benutzeravatar
__blackjack__
User
Beiträge: 13117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Nitram1: Anmerkungen zum Quelltext: ``as`` beim Importieren ist zum umbenennen gedacht, `GPIO` wird aber gar nicht umbenannt.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

Namen sollten keine kryptischen Abkürzungen enthalten oder gar nur daraus bestehen. Der Name soll dem Leser vermitteln was der Wert dahinter im Programm bedeutet, nicht zum rätseln zwingen.

Man nummeriert keine Namen. Dazu zählt auch einfach fortlaufende Buchstaben zu verwenden. Dann will man sich entweder bessere Namen überlegen, oder gar keine Einzelnamen/-werte verwenden, sondern eine Datenstruktur. Oft eine Liste.

Wenn man Code kopiert und immer leicht anpasst, macht man etwas falsch. Dafür sind Schleifen und/oder Funktionen da.

Der `cleanup()`-Aufruf gehört in einen ``finally``-Zweig, der sollte *immer* ausgeführt werden. Auch wenn der ``try``-Block durch etwas anderes als Strg+C verlassen wurde.

In einer Liste Zahlen und Zeichenketten mischen ist nicht schön. Statt "skip" würde sich hier `None` als Wert für „kein Winkel“ anbieten.

Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel auch was in der Dokumentation von Python und den verwendeten Bibliotheken steht.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import time

from RPi import GPIO

SERVO_PINS = [26, 16, 27, 17, 24, 23]


def berechne_duty_cycle(winkel):
    return (winkel / 180) * (180 - 90) + 2.5


def main():
    try:
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(SERVO_PINS, GPIO.OUT)
        servos = [GPIO.PWM(pin, 50) for pin in SERVO_PINS]
        for servo in servos:
            servo.start(7.5)

        while True:
            for schritt in [
                [90, 90, 90, 90, 90, 90],
                # [45, 60, 90, 81, None, None],
                # [60, 81, 45, 90, None, None],
                # [81, 45, 60, 90, None, None],
            ]:
                for winkel in schritt:
                    duty_cycle = berechne_duty_cycle(winkel)
                    if winkel is not None:
                        duty_cycle = berechne_duty_cycle(winkel)

                    for servo in servos:
                        servo.ChangeDutyCycle(duty_cycle)
                        time.sleep(0.1)

                time.sleep(1)

    except KeyboardInterrupt:
        pass
    finally:
        GPIO.cleanup()


if __name__ == "__main__":
    main()
Wenn `cleanup()` aufgerufen wird, dann sollten die Pins eigentlich alle wieder in den Ursprungszustand versetzt werden.

Das Programm hat noch diverse Logikprobleme die jetzt noch nicht auffallen weil alle Servos den gleichen Wert bekommen und noch kein "skip"/None verarbeitet wird.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Nitram1
User
Beiträge: 4
Registriert: Donnerstag 9. November 2023, 09:23

@__blackjack__ : alles klar danke. wie genau kann ich die Logikprobleme enfernen oder soweit umgehen das ich den code bis zu 1000 servo befehlen weiter benutzen kann?

hab den code von dir duch meinen erstezt funktionirt bis zum selben punkt wie meiner das ursprüngliche problem bleibt trozdem. ich würde raten das es nicht am code liegt irre mich warscheinlich aber.
aber trozdem danke
LRS und Totmüde = Beste Kombination
Antworten