RC-Car mittels Smartphone steuern

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Uuuuund schon wieder keine Code-Tags. Kann man so nix mit anfagen, weil Einrueckungen in Python nunmal wichtig sind.
Crisou
User
Beiträge: 23
Registriert: Samstag 20. Oktober 2018, 18:09

import socket
import Servo

Servo.setup()

def listen():
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
connection.bind(('IP_ADRESSE' Port))
connection.listen(10)
while True:
current_connection, address = connection.accept()
while True:
data = current_connection.recv(2048)
if not data:
break
if data == winkel:
Servo.ServoUp
if data == winkel:
Servo.ServoDown

if __name__== "__main__":
try:
listen()
except KeyboardInterrupt:
pass
Crisou
User
Beiträge: 23
Registriert: Samstag 20. Oktober 2018, 18:09

ja sorry ist mir schon klar. sobald ich abschicke ist die einrückung wieder weg
Crisou
User
Beiträge: 23
Registriert: Samstag 20. Oktober 2018, 18:09

Servo Skript

Code: Alles auswählen

import Rpi.GPIO as GPIO

def setup():
	GPIO.setmode(GPIO.BCM)
	GPIO.setwarnigs(False)
	GPIO.setup(18, GPIO.OUT)
	servo = GPIO.PWM(18, 50)
	servo.start(7.5)
	servo.ChangeDutyCycle(2.5)

def ServoUp(winkel):
	if winkel <= 45:
		pwm = winkel/18 + 2.5
		servo.ChangeDutyCycle(pwm)
def ServoDown(winkel):
	if winkel >= 45
		pwm = winkel/18 - 2.5
		servo.ChangeDutyCycle(pwm)

def close():
	servo.stop()
if __name__=='__main__':
	setup()[/code
Crisou
User
Beiträge: 23
Registriert: Samstag 20. Oktober 2018, 18:09

Server Script

Code: Alles auswählen

import socket
import Servo

Servo.setup()

def listen():
	connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	conection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
	connection.bind(('IP_ADRESSE' Port))
	connection.listen(10)
	while True:
		current_connection, address = connection.accept()
		while True:
			data = current_connection.recv(2048)
			if not data:
				break
			if data == winkel:
				Servo.ServoUp
			if data == winkel:
				Servo.ServoDown

if __name__== "__main__":
	try:
		listen()
	except KeyboardInterrupt:
		pass
Crisou
User
Beiträge: 23
Registriert: Samstag 20. Oktober 2018, 18:09

@deets

und was ist deine meinung dazu?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da du ja zum inzwischen 5ten oder so mal konsequent nicht mitteilst, welche Werte du vom Server enthaelst, kann man da auch nur mit den Achseln zucken.

Das du zweimal die gleiche Bedingung hast (data == winkel) fuehrt natuerlich dazu, dass du jeweils ServoUp und ServoDown aufrufen wuerdest. Wenn du sie denn aufrufen wuerdest. Was du nicht tust. Du uebergibst ihnen auch kein Argument. Und wenn der Winkel 45 waere , wuerden auch beide Funktionen etwas machen, und zu jeweils unterschiedlichen Ergebnissen kommen.
Wenn ich da jeweils 45 Grad als gewuenschten Winkel angebe, dann kommen da einmal 5% DC raus (stimmt), und einmal 0% (stimmt offensichtlich nicht). Es ist auch ueberfluessig, zwei Funktionen zu haben. Das ist wie schon gesagt eine einfache Geradengleichung aus der 9ten Klasse.

Wenn der Winkel von -45 bis +45 grad EINGABE geht (ob das so ist - keine Ahnung. Du lieferst ja nicht wirklich belastbare Aussagen zu solchen Dingen), und man von einem Servo-Winkel von 180 Grad ausgeht, von dem du dann nur 90 Grad nutzen willst, dann ist die Formel fuer den Duty-Cyle in ms ein simples:

1.5ms + (winkel / 180 * 2ms)

Denn der Mittelpunkt liegt bei 1.5 ms, und die vollen 180 Grad spannen 2ms. Kann man also nachrechnen:

Code: Alles auswählen

>>> winkel = -45
>>> 1.5 + (winkel / 180.0 * 2)
1.0
>>> winkel = 45
>>> 1.5 + (winkel / 180.0 * 2)
2.0
>>> winkel = 0
>>> 1.5 + (winkel / 180.0 * 2)
1.5
Weil das aber in ms und nicht in Prozent ist, wie die API des sehr schlechten RPI.GPIO PWM das verlangt, muss man das Ergebnis noch mal 5 nehmen.

Code: Alles auswählen

duty_cycle = (1.5 + (winkel / 180.0 * 2)) * 5
So. Aber fuer mich ist hier EOD. Jedes einezelne Fitzelchen Information hier aus der Nase pulen zu muessen ist mir zu muehsam. Und da du recht offensichtlich wirklich so gut wie gar kein Python beherrschst, musst du dir das entweder erstmal raufschaffen, oder jemanden finden, der das fuer dich macht. Vor Ort. Mit Zugriff auf all die Informationen und die Hardware etc.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Crisou: Die Socket-Kommunikation ist auch kaputt. `recv(n)` bedeutet das da irgendetwas zwischen 1 und n Bytes aus dem TCP-Datenstrom geliefert werden kann. Und wenn m Bytes auf der anderen Seite gesendet wurden, heisst das nicht das die auch beim `recv()` bei einem Aufruf geliefert werden müssen. Das kann (lokal) ziemlich oft zufällig der Fall sein, weshalb es immer wieder diese dusseligen, kaputten Beispiele im Netz gibt bei dem das genau so gemacht wird wie Du das da machst, aber so funktioniert TCP nun mal nicht. Das ist ein Datenstrom und keine abgeschlossenen Nachrichten. Wenn man abgeschlossene, getrennte Nachrichten übertragen möchte, dann muss man da ein Protokoll für verwenden und immer solange lesen bis man garantiert mindestens eine komplette Nachricht empfangen hat, bevor man die verarbeitet. Da muss man selbst Code für schreiben, oder besser ein vorhandenes Protokoll verwenden.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

GPIO-Warnungen sind dazu da, sie abzustellen, nicht dass man sie ignoriert. Da fehlt ein cleanup. Eingerückt wird mit 4 Leerzeichen nicht mit Tabs. Dass `listen` kaputt ist, hat ja __blackjack__ nun auch geschrieben, schau Dir mal socket.makefile an. Außerdem ist `winkel` nicht definiert und Funktionen werden nicht aufgerufen.
Antworten