dann investier doch mal 5 EUR - wie willst du es sonst schnell mal testen? Solange die Funktion nicht geklärt ist, können wir uns hier die Finger wund schreiben... :-/
dann investier doch mal 5 EUR - wie willst du es sonst schnell mal testen? Solange die Funktion nicht geklärt ist, können wir uns hier die Finger wund schreiben... :-/
PWM ist ja nicht gleich HIGH-Pegel sondern was dazwischen weil sich dort HIGH und LOW schnell abwechseln und unterschiedliche Zeiten haben können. Mit einem Multimeter könntest Du allenfalls einen Zwischenwert erhalten, der eben nicht dem vollen HIGH-Pegel entspricht. Sonst müsstest Du einen Oszi.. dran hängen, um das Signal am Ausgang zu sehen.
MfG
So, fertig.
Hat noch einmal richtig Nerven gekostet, aber mit insgesamt etwa 10 Tagen Aufwand konnte ich nun alles lösen. Einzig, die Servos "zittern" immer noch, aber das schein wohl bauartbedingt zu sein. Auch mit dem Servotester zittern die Servos, und auch solche, die einfach nur rumliegen und nicht verbaut sind, zittern. Also alles im grünen Bereich.
Das Python-Programm habe ich noch einmal von vorne begonnen. Habe alle Funktionen, die ich im alten Programm in eigene Funktionsbausteine verpackt habe in eine Hauptschleife genommen. Dadurch gibt es kein Timeout an einer ungünstigen Stelle und der Code ist erst noch leichter verständlich - zumindest, wenn man das Programm und die Funktionen kennt.
Da mehrfach darauf hingewiesen wurde, dass Software-PWM nicht stabil ist habe ich einen PCA9685-Controller verbaut. Erst dachte ich, ich müsste mindestens zwei nehmen, da ich Servos (6.0V) und DC-Motoren (12V mit L298N) habe. Aber man kann ja auch einfach nur das PWM-Signal und Masse an den L298N anschliessen und die externe Stromversorgung ebenfalls direkt dranhängen statt über den PCA9685 zu gehen. Nachdem ich auch das begriffen hatte, wurde es immer einfacher. Es brauchte etwas Zeit zu verstehen, wieso der PCA9685 nicht einfach mit einem Signal von 0 bis 100 für Min/Max angesprochen werden kann sondern 0 bis 4095 verwendet, aber auch das ist schlussendlich nur noch Mathematik.
Die Servos haben mir noch etwas Kopfzerbrechen gemacht, genauer die Einschlagswinkel der Steuerachsen, da Achse 2 und 4 weniger stark einlenken müssen als Achse 1, und Achse 4 ja gegenlenkt und einen invertierten Winkel benötigt. Aber diese Rechnung musste eh angestellt werden.
Aufgebockt drehen die Räder, schlagen die Lenkungen ein, blinken die Blinker und schalten die Kameras. Ich bin zufrieden und sobald die Akkus wieder voll sind kommt die richtige Jungfernfahrt. Vielen Dank an alle Tippgeber im Forum!
Falls sich jemand für den Code interessiert, er ist unten angefügt. Nicht, dass man ihn so direkt nutzen könnte, aber vielleicht für den einen oder anderen Anfänger hilfreich.
Code:from __future__ import division
import Adafruit_PCA9685
import socket
import sys
import time
from decimal import Decimal
#define all variables
HOST = ''
TCP_PORT = 10001
intDivider = 4096
intDividerMax = 4095
#Define pins
pinCamera1 = 2
pinCamera2 = 3
pinBlinkerRight = 4
pinBlinkerLeft = 5
pinLightReverse = 6
pinLightForward = 7
pinServo1 = 8
pinServo2 = 9
pinServo3 = 10
pinMotorForward = 15
pinMotorReverse = 14
#Start of script
print "Initiating... waiting for connection"
sckSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sckSocket.bind((HOST, TCP_PORT))
sckSocket.listen(1)
intFrequenz = 50
intBlinkerLeft = 0
intBlinkerRight = 0
intBlinkerCounter = 0
#Connection loop
while True:
#Accept connection and create new socket 'sckConnection1'
try:
global intBlinkerLeft
global intBlinerRight
global intBlinkerCounter
sckConnection1, strClientAddress = sckSocket.accept()
print "Connection established"
print "Setting up PWM"
pwm = Adafruit_PCA9685.PCA9685(address=0x40)
pwm.set_pwm_freq(intFrequenz)
pwm.set_pwm(pinMotorForward, 0, 0)
pwm.set_pwm(pinMotorReverse, 0, 0)
pwm.set_pwm(pinBlinkerLeft, 0, 0)
pwm.set_pwm(pinBlinkerRight, 0, 0)
pwm.set_pwm(pinLightForward, 0, intDividerMax)
pwm.set_pwm(pinLightReverse, 0, 0)
pwm.set_pwm(pinCamera1, 0, 0)
pwm.set_pwm(pinCamera2, 0, 0)
#loop while connected
while True:
strData = ""
strData = sckConnection1.recv(1024)
intStringStart = 0
intStringEnd = 0
intStringLen = 0
intXaxis = 5000
intYaxis = 5000
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 = 0
intStringEnd = strData.find("X:")
if intStringEnd == 0:
intXaxis = intXaxis
else:
intStringStart = intStringEnd + 2
intStringEnd = strData.find(";", intStringStart)
intXaxis = int(strData[intStringStart:intStringEnd])
except:
intXaxis = intXaxis
#Extract Y axis
try:
intStringEnd = 0
intStringEnd = strData.find("Y:")
if intStringEnd == 0:
intYaxis = intYaxis
else:
intStringStart = intStringEnd + 2
intStringEnd = strData.find(";", intStringStart)
intYaxis = int(strData[intStringStart:intStringEnd])
except:
intYaxis = intYaxis
#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
#Set Speed (Y-axis)
#Value <= 4750 -> reverse
if intYaxis <= 4750:
intSpeed = int(round(intDividerMax - (intDividerMax / 4750 * intYaxis), 0))
pwm.set_pwm(pinMotorForward, 0, intSpeed)
pwm.set_pwm(pinMotorReverse, 0, 0)
#Value >= 5250 -> forward
elif intYaxis >= 5250:
intSpeed = int(round(intDividerMax / 4750 * (intYaxis - 5250), 0))
pwm.set_pwm(pinMotorForward, 0, 0)
pwm.set_pwm(pinMotorReverse, 0, intSpeed)
#Value > 4750 and < 5250 -> stop
else:
pwm.set_pwm(pinMotorForward, 0, 0)
pwm.set_pwm(pinMotorReverse, 0, 0)
#Set servo positions (X-axis)
#Value <= 4750 -> left
if intXaxis <= 4750:
fltWinkel1 = float( 90 - float( ( 4750 - intXaxis ) / 118.75 ) )
fltWinkel2 = float( fltWinkel1 * 0.8599 + 12.193 )
fltWinkel3 = float( fltWinkel1 * -0.2161 + 109.78 )
intServo1 = int( round( float( float( float( fltWinkel1 / 18 ) + 2 ) / 100 ) * 4096, 0 ) )
intServo2 = int( round( float( float( float( fltWinkel2 / 18 ) + 2 ) / 100 ) * 4096, 0 ) )
intServo3 = int( round( float( float( float( fltWinkel3 / 18 ) + 2 ) / 100 ) * 4096, 0 ) )
pwm.set_pwm(pinServo1, 0, intServo1)
pwm.set_pwm(pinServo2, 0, intServo2)
pwm.set_pwm(pinServo3, 0, intServo3)
#Value >= 5250 -> right
elif intXaxis >= 5250:
fltWinkel1 = float( 90 + float( ( intXaxis - 5250 ) / 118.75 ) )
fltWinkel2 = float( fltWinkel1 * 0.8599 + 12.193 )
fltWinkel3 = float( fltWinkel1 * -0.2161 + 109.78 )
intServo1 = int( round( float( float( float( fltWinkel1 / 18 ) + 2 ) / 100 ) * 4096, 0 ) )
intServo2 = int( round( float( float( float( fltWinkel2 / 18 ) + 2 ) / 100 ) * 4096, 0 ) )
intServo3 = int( round( float( float( float( fltWinkel3 / 18 ) + 2 ) / 100 ) * 4096, 0 ) )
pwm.set_pwm(pinServo1, 0, intServo1)
pwm.set_pwm(pinServo2, 0, intServo2)
pwm.set_pwm(pinServo3, 0, intServo3)
#Value > 4750 and < 5250 -> center
else:
intServo1 = int(intDividerMax / 2)
intServo2 = int(intDividerMax / 2)
intServo3 = int(intDividerMax / 2)
pwm.set_pwm(pinServo1, 0, intServo1)
pwm.set_pwm(pinServo2, 0, intServo2)
pwm.set_pwm(pinServo3, 0, intServo3)
#Blinker left
#Blink if Button BC (Button no. 3) is pressed or blink loop is still active
if intBlinkerLeft == 1:
if intBlinkerCounter < 20:
intBlinkerCounter = intBlinkerCounter + 1
if bool(int(round(intBlinkerCounter * 0.25 * 2, 2)) & 1) == True:
pwm.set_pwm(pinBlinkerLeft, 0, intDividerMax)
else:
pwm.set_pwm(pinBlinkerLeft, 0, 0)
else:
intBlinkerLeft = 0
pwm.set_pwm(pinBlinkerLeft, 0, 0)
elif intBC == 1:
pwm.set_pwm(pinBlinkerLeft, 0, intDividerMax)
intBlinkerLeft = 1
intBlinkerCounter = 0
#Blinker right
#Blink if Button BD (Button no. 4) is pressed or blink loop is still active
if intBlinkerRight == 1:
if intBlinkerCounter < 20:
intBlinkerCounter = intBlinkerCounter + 1
if bool(int(round(intBlinkerCounter * 0.25 * 2, 2)) & 1) == True:
pwm.set_pwm(pinBlinkerRight, 0, intDividerMax)
else:
pwm.set_pwm(pinBlinkerRight, 0, 0)
else:
intBlinkerRight = 0
pwm.set_pwm(pinBlinkerRight, 0, 0)
elif intBD == 1:
pwm.set_pwm(pinBlinkerRight, 0, intDividerMax)
intBlinkerRight = 1
intBlinkerCounter = 0
#Both blinkers (left and right)
#Blink if Button BB (Button no. 2) is pressed or blink loop is still active
if (intBlinkerRight == 1 and intBlinkerLeft == 1):
if intBlinkerCounter < 20:
intBlinkerCounter = intBlinkerCounter + 1
if bool(int(round(intBlinkerCounter * 0.25 * 2, 2)) & 1) == True:
pwm.set_pwm(pinBlinkerRight, 0, intDividerMax)
pwm.set_pwm(pinBlinkerLeft, 0, intDividerMax)
else:
pwm.set_pwm(pinBlinkerRight, 0, 0)
pwm.set_pwm(pinBlinkerLeft, 0, 0)
else:
intBlinkerRight = 0
pwm.set_pwm(pinBlinkerRight, 0, 0)
pwm.set_pwm(pinBlinkerLeft, 0, 0)
elif intBB == 1:
pwm.set_pwm(pinBlinkerRight, 0, intDividerMax)
pwm.set_pwm(pinBlinkerLeft, 0, intDividerMax)
intBlinkerRight = 1
intBlinkerLeft = 1
intBlinkerCounter = 0
#Set Camera view
#Turn on back camera if Button BE (Button no. 5) is pressed
if intBE == 1:
pwm.set_pwm(pinCamera1, 0, intDividerMax)
pwm.set_pwm(pinCamera2, 0, intDividerMax)
#Turn on front camera if Button BF (Button no. 6) is pressed
if intBF == 1:
pwm.set_pwm(pinCamera1, 0, 0)
pwm.set_pwm(pinCamera2, 0, 0)
#Break connection if Button BA (Button no. 1) is pressed and exit program
if intBA == 1:
print "Connection terminated"
print "Exiting script"
sys.exit(0)
break
time.sleep(0.25)
else:
print "Connection lost"
break
#Clean up after error or at termination
finally:
sckConnection1.close()
#End of script
print "Ending"
sys.exit(0)
Glückwunsch, dass du es hingekriegt hast, vor allem auch mit Python! 8)