- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 6 von 6

Thema: Python - Motor dreht aber Geschwindigkeit lässt sich über PWM nicht ändern

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    07.09.2017
    Beiträge
    52

    Python - Motor dreht aber Geschwindigkeit lässt sich über PWM nicht ändern

    Anzeige

    E-Bike
    Hallo zusammen

    Ich habe folgende Anordnung:
    Computer A mit eingabegeräten und Computer B (Raspberry Pi) für die Motorensteuerung meines Modelllasters.
    Computer A schickt an B einen Wert zwischen 0 und 10'000 für die Richtungs- und Geschwindigkeitsangabe.
    Das funktioniert.
    Ist der Wert zwischen 0 und 4750, dreht der Motor vorwärts, ist der Wert grösser als 5250, dreht er rückwärts. Die 10% Spatzung habe ich mir für kleinste, ungewollte Bewegungen am Joystick gelassen, wird vielleicht kleiner.
    Das funktioniert.
    An einem freien Pin ist eine Kontroll-LED angebracht, damit ich sehen kann, ob der Motor ein Signal bekommt, falls er stottert.
    Das funktioniert.

    Was nicht funktioniert ist die Änderung der Geschwindigkeit und dass die LED ihre Helligkeit an die Signalgeschwindigkeit des Motors anpasst.
    Unten im Code ist das Modul Umstellen(intSpeed), durch das die Richtgung geregelt wird und wodurch das PWM-Signal erhöht oder gesenkt werden soll.
    Hat jemand einen Tipp, woran es liegen könnte, dass der Motor nicht schneller oder langsamer dreht?

    Was ich schon getestet habe: Die Verkabelung passt. Die Pins habe ich mit einem ähnlichen Code (war meine Vorlage) bereits angesteuert und wenn ich darüber die Drehzahl ändere, dreht der Motor schneller oder langsamer.

    Code:
    import sys
    import time
    import socket
    import RPi.GPIO as gpio
    
    
    #define all variables
    HOST = ''
    TCP_PORT = 10001
    intStringStart = 0
    intStringEnd = 0
    intStringLen = 0
    intXaxis = 0
    intYaxis = 0
    intBA = 0
    intBB = 0
    intBC = 0
    intBD = 0
    intBE = 0
    intBF = 0
    intBG = 0
    intBH = 0
    intBI = 0
    intBJ = 0
    intBK = 0
    intBL = 0
    intDirection = 0
    fltCycle = 100
    gpio.setmode(gpio.BCM)
    gpio.setup(18, gpio.OUT)
    gpio.setup(23, gpio.OUT)
    gpio.setup(24, gpio.OUT)
    pwm = gpio.PWM(23, 100)
    pwmLED = gpio.PWM(18, 100)
    
    
    #************************************************************************************************
    #Ein
    def Ein():
    	print "Ein"
    	pwm.start(0)
    	pwmLED.start(0)
    	
    	gpio.output(18, False)
    	gpio.output(23, False)
    	gpio.output(24, False)
    
    
    #************************************************************************************************
    def Pruefer():
        print "Pruefer called " + str(intYaxis)
    
    #************************************************************************************************
    def Beender():
        print "Shutting down GPIO"
        Aus()
        print "Closing socket"
        connection.close()
        print "Shutting down"	
        
    #************************************************************************************************
    def Umstellen(intSpeed):
    	if intSpeed < 4750:
    		fltCycle = float(intSpeed / 50) 
    		gpio.output(18, True)
    		gpio.output(23, True)
    		gpio.output(24, False)
    		pwm.ChangeDutyCycle(fltCycle)
    		pwmLED.ChangeDutyCycle(fltCycle)
    		print str(fltCycle)
    		
    	elif intSpeed > 5250:
    		fltCycle = float((intSpeed / 50) - 100)
    		gpio.output(18, True) 
    		gpio.output(23, False)
    		gpio.output(24, True)
    		pwm.ChangeDutyCycle(fltCycle)
    		pwmLED.ChangeDutyCycle(fltCycle)
    		
    	else:
    		gpio.output(18, False)
    		gpio.output(23, False)
    		gpio.output(24, False)
    		pwm.stop()
    		pwmLED.stop()
    	
    	
    #************************************************************************************************
    #Aus
    def Aus():
    	print "Aus"
    	gpio.output(18, False)
    	gpio.output(23, False)
    	gpio.output(24, False)
    	pwm.stop()
    	pwmLED.stop()
    	gpio.cleanup()
    
    
    #************************************************************************************************
    
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((HOST, TCP_PORT))
    sock.listen(1)
    
    Ein()
    
    while True:
    	#Accept the connection and create new socket connection1
    	try:
    		connection, strClientAddress = sock.accept()
    		boConnected = True
    		
    		#loop while connected
    		while True:
    			strData = connection.recv(100)
    			intStringStart = 0
    			intStringEnd = 0
    			intStringLen = 0
    			intXaxis = 0
    			intYaxis = 0
    			intBA = 0
    			intBB = 0
    			intBC = 0
    			intBD = 0
    			intBE = 0
    			intBF = 0
    			intBG = 0
    			intBH = 0
    			intBI = 0
    			intBJ = 0
    			intBK = 0
    			intBL = 0
    			
    #Check if strData <> null, else break loop
    			if strData:
    
    #Extract X axis				
    				try:
    					intStringEnd = strData.find("X:")
    					intStringStart = intStringEnd + 2
    					intStringEnd = strData.find(";", intStringStart)
    					intXaxis = int(strData[intStringStart:intStringEnd])
    				except:
    					intXaxis = 0
    #Extract Y axis				
    				try:
    					intStringEnd = strData.find("Y:")
    					intStringStart = intStringEnd + 2
    					intStringEnd = strData.find(";", intStringStart)
    					intYaxis = int(strData[intStringStart:intStringEnd])
    				except:
    					intYaxis = 0
    #Extract Button A
    				try:
    					intStringEnd = strData.find("BA:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBA = int(strData[intStringStart:intStringEnd])
    				except:
    					intBA = 0
    #Extract Button B				
    				try:
    					intStringEnd = strData.find("BB:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBB = int(strData[intStringStart:intStringEnd])
    				except:
    					intBB = 0
    #Extract Button C				
    				try:
    					intStringEnd = strData.find("BC:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBC = int(strData[intStringStart:intStringEnd])
    				except:
    					intBC = 0
    #Extract Button D
    				try:
    					intStringEnd = strData.find("BD:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBD = int(strData[intStringStart:intStringEnd])
    				except:
    					intBD = 0
    #Extract Button E				
    				try:
    					intStringEnd = strData.find("BE:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBE = int(strData[intStringStart:intStringEnd])
    				except:
    					intBE = 0
    #Extract Button F				
    				try:
    					intStringEnd = strData.find("BF:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBF = int(strData[intStringStart:intStringEnd])
    				except:
    					intBF = 0
    #Extract Button G
    				try:
    					intStringEnd = strData.find("BG:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBG = int(strData[intStringStart:intStringEnd])
    				except:
    					intBG = 0
    #Extract Button H				
    				try:
    					intStringEnd = strData.find("BH:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBH = int(strData[intStringStart:intStringEnd])
    				except:
    					intBH = 0
    #Extract Button I				
    				try:
    					intStringEnd = strData.find("BI:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBI = int(strData[intStringStart:intStringEnd])
    				except:
    					intBI = 0
    #Extract Button J
    				try:
    					intStringEnd = strData.find("BJ:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBJ = int(strData[intStringStart:intStringEnd])
    				except:
    					intBJ = 0
    #Extract Button K				
    				try:
    					intStringEnd = strData.find("BK:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBK = int(strData[intStringStart:intStringEnd])
    				except:
    					intBK = 0
    #Extract Button L				
    				try:
    					intStringEnd = strData.find("BL:")
    					intStringStart = intStringEnd + 3
    					intStringEnd = strData.find(";", intStringStart)
    					intBL = int(strData[intStringStart:intStringEnd])
    				except:
    					intBL = 0
    
    				Umstellen(intYaxis)
    
    #close connection if Button BF (6) is pressed
    				if intBF == 1:
    					Beender()
    					sys.exit(0)
    
    
    				
    			else:
    				print "Connection lost"
    				break
    		
    	#Clean up after error or at termination
    	finally:
    		connection.close()

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    03.04.2013
    Beiträge
    526
    Hast du den Ausgang zum Motor mit einem Voltmeter mal überprüft?
    Ich kenn mich mit Python nicht aus, aber müsste da nicht eine Schleife im Programm sein?
    Was für einen Motor-Treiber / Shield benutzt du, was für einen Motor und wie sieht die ganze Schaltung aus?
    Bilder, Bilder, Bilder!

    Was mir noch auffällt: Bei 1 dreht der Motor langsam vorwärts, bei 4749 dreht er volle Möhre vorwärts. Von 4750 bis 5250 steht er. Bei 5251 dreht der ganz langsam rückwärts und bei 10000 voll rückwärts. Ist das so gewollt? Vor allem der Sprung von voll vorwärts auf Stillstand?

    Schon mal getestet, fltcycle direkt Werte zuzuweisen und geschaut, ob sich dann die Geschwindigkeit wie gewünscht verhält?

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    07.09.2017
    Beiträge
    52
    Hallo hbquax

    Zwischenzeitlich ist eine Nacht vergangen und ich konnte noch einiges testen - habe aber die Geduld nicht mehr gefunden, das in Worte zu fassen und zu aktualisieren.
    Wie ich nach einigen Stunden Schlaf festgestellt habe, ist meine Berechnung oben nicht ganz korrekt. Eigentlich soll die Berechnung eine Parabel beschreiben. Das Eingabegerät ist ja, wie oben beschrieben, ein Joystick. Ganz vorne übergibt er den Wert 0, ganz hinten 10'000. Die Berechnung soll ergeben, dass beim Wert 0 der Motor voll dreht, in der Mitte steht und ganz hinten voll in die andere Richtung dreht. Ich habe mir einen Spielraum von 5% in jede Richtung gegeben, um kleinste Bewegungen am Joystick zu ignorieren. Excel sei Dank habe ich nun die richtige Formel zur Berechnung der Werte.

    Der Motor hängt über einen L298N am Raspberry und die Stromversorgung funktioniert, sonst hätte ich es nicht mit anderen Programmen testen können.

    Wie von dir vorgeschlagen habe ich bereits versucht, direkt Werte einzugeben und zu schauen, was der Motor macht. Habe über eine Schlaufe einen Zähler von 0 bis 200 hochzählen lassen und das mit 50 multipliziert. Ohne Änderungen am Modul Umstellen(intSpeed) dreht der Motor und ändert Richtung und Geschwindigkeit. Das Modul funktioniert also grundsätzlich, abgesehen von meinem Rechenfehler.

    Mittlerweile habe ich eine andere Vermutung. Computer A schickt ca. alle 25 Millisekunden ein Signal. Ich schätze mal, dass der RPi damit etwas überfordert ist und die Signale gar nicht so schnell umstellen kann, bzw. das PWM-Signal sofort nach der Änderung wieder eine andere Änderung macht und alles etwas überfordert ist. Ich werde heute Abend eine kurze Verzögerung von 0.03 Sekunden einbauen. Vielleicht hilft das. ich war schon einmal an dem Punkt, aber dann hat der RPi alle Eingaben komplett ignoriert.

    Falls das noch nichtgs gebracht hat, stelle ich gerne noch Bilder der Schaltung zur Verfügung.

    Gruss
    Chris

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    07.09.2017
    Beiträge
    52
    So, nun bin ich wieder drei Stunden älter, frustrierter und kein bisschen weiter.
    Ich habe die Berechnung korrigiert und mein Testcode funktioniert. Die gleiche Berechnung ist auch im Originalcode eingebaut und es funktioniert nicht. Motor dreht, Richtung stimmt, Geschwindigkeit nicht.
    Es wird zwar der richtige Originalwert und der richtige Wert für die PWM-Einstellung ausgegeben, aber es wird nichts umgestellt.

    Ich habe versucht, an mehreren Stellen time.sleep einzubauen. Einerseits im Modul Umstellen, andererseits direkt im Modul, in dem die Daten empfangen und das Modul Umstellen aufgerufen wird. 20, 30, 100, 250 oder 500 Millisekunden haben nichts geholfen. Insbesondere beim Unterbruch im Empfangsmodul brachte unangenehme Effekte, dass zwischenzeitlich empfangenen Werte mit Verzögerung ausgeführt wurden und der Motor wild herumgesprungen ist. Also wieder raus mit den ganzen Unterbrüchen, 250 Millisekunden habe ich jeweils nach den Richtungswechseln gelassen.

    Wenn es am Empfänger nicht funktioniert, dann vielleicht am Sender. Also habe ich am Sender die Sendefrequenz verändert. Statt alle 50 Millisekunden wird jetzt alle 500 Millisekunden ein neues Signal geschickt. Ohne Änderung am Resultat.

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied Avatar von RoboTrader
    Registriert seit
    08.11.2017
    Beiträge
    125
    Blog-Einträge
    1
    Da in Python die Tabulator-Einrückungen eine große Rolle spielen, würde ich die Kommentare "# ..." auch mit einrücken, also bspw. "#Extract Button L" direkt unter "intBK = 0" und nicht an den Zeilenanfang. Ich glaube, so etwas hat bei mir auch mal ein Programm "misteriös" verändert.

    Vielleicht kann ich damit helfen!
    Sonst weiter viel Erfolg.

    Ein schönes Wochenende!
    -30Y: Basic@Schneider_CPC, Kosmos-Baukästen • -20Y: Mindstorms RCX 1.5, Visual Basic, Pascal, php • NOW: Python3, Arduino MEGA, Raspberry Pi 3, NiboBurger, LEGO Boost/Mindstorms

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    07.09.2017
    Beiträge
    52
    Ich habe nun noch einiges am Code zu optimieren versucht. Beispielsweise habe ich Print-Befehle zwischen die ganzen ChangeDutyCycle-Befehle gesetzt. Ich bekomme die Prints ausgegeben, ohne dass sich die Geschwindigkeit ändert. Habe dann noch einmal mit den Pausen auf Seiten des Senders und des Empfängers gespielt. Ausser, dass sich Verzögerungen beim Programmablauf ergeben haben und nicht mehr alle Befehle ausgeführt werden, haben sich keine Änderungen ergeben.
    Nun, fürs Erste muss das reichen. Der Motor dreht und sobald ich ihn das erste Mal in den LKW einbaue, werde ich mich wieder darum kümmern. Daher würde ich den Thread als ungelöst schliessen...
    Allerdings darf ich auch was positives vermelden. Ich habe zusätzlichen Code eingebaut um einen Servo für die Lenkung zu steuern. Das funktioniert. Ebenfalls über PWM, im gleichen Programm, über den gleichen RPi, lediglich von einer anderen Stromquelle gefüttert... Nun, man weiss nicht wieso, aber es funktioniert wie erwartet.

Ähnliche Themen

  1. Motorproblem: Motor dreht sich nicht
    Von gandalfsz im Forum Asuro
    Antworten: 41
    Letzter Beitrag: 27.03.2007, 15:24
  2. Motor wird angesteuert aber dreht sich nicht
    Von outdoorgamer im Forum Asuro
    Antworten: 8
    Letzter Beitrag: 27.08.2006, 13:06
  3. Antworten: 10
    Letzter Beitrag: 25.05.2006, 17:17
  4. Baud Rate lässt sich nicht ändern!
    Von chfj82 im Forum Controller- und Roboterboards von Conrad.de
    Antworten: 5
    Letzter Beitrag: 18.05.2006, 09:06
  5. Antworten: 5
    Letzter Beitrag: 02.11.2005, 14:21

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests