PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Python über APC220 zu Romeo (Arduino kompatibles Board) --> Keine Kommunikation



Greensiver
28.10.2012, 15:31
Hi Liebe Comunity!

Ich hoffe ihr könnt mir helfen.;)

Schonmal vorab:
- Das ist mein erster Beitrag in einem Forum überhaupt.
- Ich hab schon ein wenig Kentnisse in Progressing aber nicht all zu weitreichend --> bin gern für neues offen ;)
- Mein erster Tag mit Python:-k
- Rechtschreibung ist nicht gerade meine Stärke
- Wenn ich etwas wichtiges nicht angegeben habe --> bitte zurechtweisen;)
- Bin mir nicht ganz sicher, ob ich das Thema richtig getroffen habe --> verschieben were ni schlecht^^
- Der APC is sicherlich NICHT kaputt ;)

Bauteile:
- Romeo-All in one Controller (Arduino Compatible Atmega 328 )
http://www.dfrobot.com/index.php?route=product/product&product_id=56#.UI1dXIZfEYQ
- APC220 Funkmodul http://www.dfrobot.com/index.php?route=product/product&filter_name=apc220&product_id=57#.UI1eBIZfEYQ
- Hama USB-Gamepad "Black Force" http://www.hama.de/portal/articleId*142503/action*2563

Ich tue mich gerade etwas in Python reinarbeiten. Deswegen hab ich mir gedacht nimmst dier erstmal nen Code, und schreibst den nach deinen Wünschen um.
Der Python Code funktioniert soweit. Er schickt, wenn ich meinen Ganepdhebel auf Ausgangsstellung stelle ein "s" an den Romeo (funktioniert genau so gut wie ein Arduino).
Danach sollte die Onboardlampe die ja an Pin 13 hängt angehen. Die Positionswerte des Hebels hab ich auf 255 geendert, habe dazu aber nochnichts für den Arduino geschrieben.
Sollte ja nur erstmal ein Funktionstest für Python sein.

Wo ich das ganze über USB-Kabel gemacht hatte, funktionierte es einmandfrei. --> DOCH als ich versuchte den APC220 als Verbindung zunehmen, machte der Arduino (Romeo) nichts mehr. Ich hatte schon einige Projekte mit Visualbasic, wo der APC prima gearbeitet hat.



- Der Original Code: von http://principialabs.com/joystick-control-of-a-servo/



#!/usr/bin/env python
#
# joystick-servo.py
#
# created 19 December 2007
# copyleft 2007 Brian D. Wendt
# http://principialabs.com/
#
# code adapted from:
# http://svn.lee.org/swarm/trunk/mothernode/python/multijoy.py
#
# NOTE: This script requires the following Python modules:
# pyserial - http://pyserial.sourceforge.net/
# pygame - http://www.pygame.org/
# Win32 users may also need:
# pywin32 - http://sourceforge.net/projects/pywin32/
#

import serial
import pygame

# allow multiple joysticks
joy = []

# Arduino USB port address (try "COM5" on Win32)
usbport = "/dev/ttyUSB0"

# define usb serial connection to Arduino
ser = serial.Serial(usbport, 9600)

# handle joystick event
def handleJoyEvent(e):
if e.type == pygame.JOYAXISMOTION:
axis = "unknown"
if (e.dict['axis'] == 0):
axis = "X"

if (e.dict['axis'] == 1):
axis = "Y"

if (e.dict['axis'] == 2):
axis = "Throttle"

if (e.dict['axis'] == 3):
axis = "Z"

if (axis != "unknown"):
str = "Axis: %s; Value: %f" % (axis, e.dict['value'])
# uncomment to debug
#output(str, e.dict['joy'])

# Arduino joystick-servo hack
if (axis == "X"):
pos = e.dict['value']
# convert joystick position to servo increment, 0-180
move = round(pos * 90, 0)
if (move < 0):
servo = int(90 - abs(move))
else:
servo = int(move + 90)
# convert position to ASCII character
servoPosition = chr(servo)
# and send to Arduino over serial connection
ser.write(servoPosition)
# uncomment to debug
#print servo, servoPosition

elif e.type == pygame.JOYBUTTONDOWN:
str = "Button: %d" % (e.dict['button'])
# uncomment to debug
#output(str, e.dict['joy'])
# Button 0 (trigger) to quit
if (e.dict['button'] == 0):
print "Bye!\n"
ser.close()
quit()
else:
pass

# print the joystick position
def output(line, stick):
print "Joystick: %d; %s" % (stick, line)

# wait for joystick input
def joystickControl():
while True:
e = pygame.event.wait()
if (e.type == pygame.JOYAXISMOTION or e.type == pygame.JOYBUTTONDOWN):
handleJoyEvent(e)

# main method
def main():
# initialize pygame
pygame.joystick.init()
pygame.display.init()
if not pygame.joystick.get_count():
print "\nPlease connect a joystick and run again.\n"
quit()
print "\n%d joystick(s) detected." % pygame.joystick.get_count()
for i in range(pygame.joystick.get_count()):
myjoy = pygame.joystick.Joystick(i)
myjoy.init()
joy.append(myjoy)
print "Joystick %d: " % (i) + joy[i].get_name()
print "Depress trigger (button 0) to quit.\n"

# run joystick listener loop
joystickControl()

# allow use as a module or standalone script
if __name__ == "__main__":
main()


- meine Version: (mit Python 2.6)



import serial
import pygame

joy = []


usbport = "COM1"

ser = serial.Serial(usbport, 9600)


def handleJoyEvent(e):
if e.type == pygame.JOYAXISMOTION:
axis = "unknown"
if (e.dict['axis'] == 0):
axis = "X"

if (e.dict['axis'] == 1):
axis = "Y"

if (e.dict['axis'] == 2):
axis = "Throttle"

if (e.dict['axis'] == 3):
axis = "Z"

if (axis != "unknown"):
str = "Axis: %s; Value: %f" % (axis, e.dict['value'])
# uncomment to debug
#output(str, e.dict['joy'])

# Arduino joystick-servo hack
if (axis == "X"):
pos = e.dict['value']
# convert joystick position to servo increment, 0-180
move = round(pos * 255, 0)
if (move < 0):
servo = int(-1 - move)

if (move == 0):

s = ("s")
servo =(s)

else:
servo = int(move)

ser.write(servo)
print (servo)


elif e.type == pygame.JOYBUTTONDOWN:
str = "Button: %d" % (e.dict['button'])
if (e.dict['button'] == 0):
print "Tschau!\n"
ser.close()
quit()
else:
pass

def output(line, stick):
print "Joystick: %d; %s" % (stick, line)

def joystickControl():
while True:
e = pygame.event.wait()
if (e.type == pygame.JOYAXISMOTION or e.type == pygame.JOYBUTTONDOWN):
handleJoyEvent(e)

def main():
pygame.joystick.init()
pygame.display.init()
if not pygame.joystick.get_count():
print "\nBitte Joystick anschliesen und Programm neustarten\n"
quit()
print "\n%d joystick(s) erkannt" % pygame.joystick.get_count()
for i in range(pygame.joystick.get_count()):
myjoy = pygame.joystick.Joystick(i)
myjoy.init()
joy.append(myjoy)
print "Joystick %d: " % (i) + joy[i].get_name()
print "Zum beenden Gamepadbutton 1 betätigen.\n"

joystickControl()

if __name__ == "__main__":
main()



- zum Schluss noch der Arduino Sketch



const int ledPin = 13;
int incomingByte;

void setup() {

Serial.begin(9600);

pinMode(ledPin, OUTPUT);
}

void loop() {

if (Serial.available() > 0) {

incomingByte = Serial.read();

if (incomingByte == 's') {
digitalWrite(ledPin, HIGH);
}

if (incomingByte == 'L') {
digitalWrite(ledPin, LOW);
}
}
}


------------------------------------------------------------------------

Ich bin eig nur auf Python umgestiegen, weil ich nirgens anders mein Gamepad eingebunden gekriegt hab. Bitte beachten, dass bei Python die Module Pygame und Pyserial installiert sein müssen.
Bis jetzt sind es eig nur Testprogramme um zu sehen ob ne Lampe angeht, wenn der Steuerknüppel auf Ausgangsstellung geht. hat ja auch bestens mit Kabel funktioniert...aber mit diesem APC220 nicht. Das Projekt soll mal Später ein Über Gamepad funkgesteuertes Auto mit allem Pipapo werden.

Keine Ahnung ob ich schon alles gesagt habe...ich werd diesen Artickel bestimmt noch einige male Editieren müssen :p


_____________________
Gruß Green

m.a.r.v.i.n
30.10.2012, 10:55
Stimmt der Com Port in deinem Python Script? COM1 ist normalerweise vom Mainboard belegt. Im Windows Geräte Manager sieht man die COM Port Nummern, wie sie vom Betriebssystem vergeben werden.

Greensiver
30.10.2012, 22:39
Erstmal Danke für die Antwort! :)


COM1 ist normalerweise vom Mainboard belegt.

Interresannt.
Ich hab den Comport von dem USB-UART Wandler auf COM1 geendert, weil der APC sonst überhaut nicht gearbeitet hatte. (Frag mich nich Warum:confused:)
Wenn ich den COM1 anspreche leuchtet auch die Lampe am Umwandler. Meines Wissens war der COM1 vor der änderrung noch nicht vergeben.
Ich habe den Port je nach Verwendung immer geändert. (Kabel COM3 | APC/Umwandler COM1)
Ich hatte schon einiege Versuche mit VB.net gemacht. Da hatt das über COM1 bestens geklappt.

Nur nebenbei: PC: Toshiba Satellite Pro

An den COM dürftes eher nicht liegen.

23587

m.a.r.v.i.n
31.10.2012, 08:45
Gut, bei meinen PCs ist COM1 immer belegt, aber dann scheint die PC Seite ja ok zu sein. Das wäre ja auch zu einfach gewesen.

Wie sieht es auf RoMeo Seite aus. Leuchtet da auch die Betriebs LED? Ist der Wireless Select Jumper gesetzt?
Ich nehme auch an, du hast beide Module mit dem RF-Magic Tool richtig konfiguriert.

Greensiver
31.10.2012, 09:18
Hm.
Was fürne Betriebs-LED der APC besitzt keine, und der Romeo leuchtet immer sobalt der Strom hat. (Die ist nur am USB-UART Wandler)
Was ist ein Wireless Select Jumper???
für die Configuration gibs nen Screenshot.
23589
Ich denke das der Hase nicht Hardwaremäsig im Pfeffer liegt. Wenn ich ein "s" über die Arduino Entwicklungsumgebung an COM1 sende get ja die PIN13 LED an. Und beim großen "L" wieder aus.

Mir ist gerade was aufgefallen:
in dem Originalcode ist eine Zeile: servoPosition = chr(servo)
die habe Ich einfach rasgenommen, weil wen ich mir das über Print ausgeben lassen wollte stand da nur irgentein Kauderwelsch. Also hab ich die Werte direkt über ser.write geschickt. --> ging ja au über USB
Was macht dieses "chr" eigentlich?

Ich hab nämle Bemerkt das ich in den VB.net Code sowas ähnliches stehen habe:
SerialPort1.Write(ChrW(10))
Ich kann dadrüber (zumindest meine ich das) keine Buchstaben schicken, was ich aber machen wollte.

Sooo ich hoffe das hat uns eiin wenig weitergebracht :)

_____________________
Gruß Green


EDIT: Achso chr hat was mit ASCII zutun.
hab jetzt mal



if (move == 0):

s = ("s")
servo =(s)


IN


if (move == 0):

servo = chr(115)

geändert.
Gibt mir jetzt immernoch ein "s" als Print aus...der RoMeo sagt über Funk aber immer nochnichts :(

m.a.r.v.i.n
31.10.2012, 11:45
Hm.
Was ist ein Wireless Select Jumper???

Der Jumper auf dem RoMeo board, der das APC Modul aktiviert. RTFM (http://www.dfrobot.com/wiki/index.php?title=DFRduino_Romeo-All_in_one_Controller_%28SKU:DFR0004%29).

Bei Python/VB kann ich dir nicht weiterhelfen. Nicht meine Welt.

Greensiver
31.10.2012, 19:14
Lustig, ich find son Jumper garni bei mir. EGAL. Der APC arbeitet ja, wenn der Befehle vom Seriellen Monitor bekommt. Is nur komisch das das dort funktioniert und über Python nicht.



Bei Python/VB kann ich dir nicht weiterhelfen. Nicht meine Welt.

Aber in Progressing?:roll:

Hab jetzt den Code von dem RoMeo so geändert:



int LED=13;
int input=0;


void setup()
{
Serial.begin(9600);
pinMode(LED,OUTPUT);
}


void loop()
{

input=Serial.read();

switch(input)
{
case 115: //ASCII kleines "s"
digitalWrite(LED,HIGH);
break;

case 76: //ASCII großes "L"
digitalWrite(LED,LOW);
break;
}


}


Es funzt bestens über APC und VB aber mit Python immerr nochnicht.
Es müsste höchstwarscheinlich an Python liegen. Irgentwie versteh ich ni was da der Fehler noch sein könnte....

Nochmal in kurtz:


- VB.net + Kabel = Funktioniert
- VB.net + APC220 = Funktioniert
- Python + Kabel = Funktioniert
- Python + APC220 = Funktioniert NICHT


- - - Aktualisiert - - -

Oje das wird immer verwirender.
Hab jetzt Python auf 3.2.3rc2 Geupdated.

Script siet jetzt so aus:




import serial
import pygame

joy = []


usbport = "COM3"

ser = serial.Serial(usbport, 9600)


def handleJoyEvent(e):
if e.type == pygame.JOYAXISMOTION:
axis = "unknown"
if (e.dict['axis'] == 0):
axis = "X"

if (e.dict['axis'] == 1):
axis = "Y"

if (e.dict['axis'] == 2):
axis = "Throttle"

if (e.dict['axis'] == 3):
axis = "Z"

if (axis != "unknown"):
str = "Axis: %s; Value: %f" % (axis, e.dict['value'])
# uncomment to debug
#output(str, e.dict['joy'])

# Arduino joystick-servo hack
if (axis == "X"):
pos = e.dict['value']
# convert joystick position to servo increment, 0-180
move = round(pos * 255, 0)
if (move < 0):
servo = int(-1 - move)

if (move == 0):

servo = chr(115)

else:
servo = int(move)

ser.write(servo)
print (servo)


elif e.type == pygame.JOYBUTTONDOWN:
str = "Button: %d" % (e.dict['button'])
if (e.dict['button'] == 0):
print ("Tschau!\n")
ser.close()
quit()
else:
pass

def output(line, stick):
print ("Joystick: %d; %s" % (stick, line))

def joystickControl():
while True:
e = pygame.event.wait()
if (e.type == pygame.JOYAXISMOTION or e.type == pygame.JOYBUTTONDOWN):
handleJoyEvent(e)

def main():
pygame.joystick.init()
pygame.display.init()
if not pygame.joystick.get_count():
print ("\nBitte Joystick anschliesen und Programm neustarten\n")
quit()
print ("\n%d joystick(s) erkannt" % pygame.joystick.get_count())
for i in range(pygame.joystick.get_count()):
myjoy = pygame.joystick.Joystick(i)
myjoy.init()
joy.append(myjoy)
print ("Joystick %d: " % (i) + joy[i].get_name())
print ("Zum beenden Gamepadbutton 1 betätigen.\n")

joystickControl()

if __name__ == "__main__":
main()


Bei Scriptstart sieht noch alles Normal aus:
23593
Wenn ich den Knüppel nach Links drehe kommt der Fehler:
23594
Dreh ich den Knüppel nun nach Rechts kommt dann das hier:
23595

m.a.r.v.i.n
31.10.2012, 19:28
Es müsste höchstwarscheinlich an Python liegen.
Sehe ich inzwischen auch so. Könnte es vielleicht an einer unterschiedlichen Initialisierung der Steuerleitungen (RTS,DTR) zwischen Python und VB liegen. Das APC Modul hat ja diesen EN Eingang. Der wird sicher über eine Steuerleitung geschaltet.

Zu den Fehlermeldungen fällt mir leider nichts ein.

Greensiver
31.10.2012, 19:50
Könnte es vielleicht an einer unterschiedlichen Initialisierung der Steuerleitungen (RTS,DTR) zwischen Python und VB liegen.
Ein hoch auf die Fachsprache!
Ich verstehe leider nur Bahnhof!


Das APC Modul hat ja diesen EN Eingang.
Den hat es! | Am USB-UART Wandler heißt der allerdings RTS / und am RoMeo DTR --> gibt es da nen Unterschied?


Der wird sicher über eine Steuerleitung geschaltet.
¿Ehm bitte was?
Der APC steckt auf beiden Seiten einfach in einen vorgesehenen Sockel, könnte dan aber natürlich auch Verkabelt anschliesen.

_______________
Danke das du dier wegen mir nen Kopf machst m.a.r.v.i.n^^

m.a.r.v.i.n
31.10.2012, 20:40
Ok, dann setze doch einfach mal RTS in deinem Python script auf 1. Auf RoMeo Seite hängt der EN pin laut Schaltplan an Reset.


ser = serial.Serial(usbport, 9600)
ser.setRTS(1)

Greensiver
31.10.2012, 21:29
ser = serial.Serial(usbport, 9600)
ser.setRTS(1)
WOW Danke
Mit RTS(1) hatte es zwar nicht funktioniert!
Aber ich hab das einfach mal in RTS(0) geändert....und siehe.....da es FUNKTIONIERT!:D

Hm nur noch einwas...wie kann man am Recousenschonendsten die Motoren mit PWM und richtung ansteuern...hab zwar schon ne Idee, aber nen Fachmann zu hören ist vorher immer noch am besten^^

Und zu den Errors....hab einfach wieder das Alte Python genommen....und schon get wieder alles Normal^^

Was macht dieses ser.setRTS(1) eig genau?
Ich were NIE auf sowas gekommen!

OK...der Thread wird erstmal als Erledigt Makiert!


Danke Danke Danke!!! m.a.r.v.i.n

m.a.r.v.i.n
31.10.2012, 22:23
Super, freut mich das es nun klappt.
RTS, CTS, DTR, DSR sind Steuerleitungen (Pins) der RS232 Schnittstelle (http://de.wikipedia.org/wiki/RS-232). Diese werden normalerweise als Hardware Handshake benutzt, man kann sie aber auch als gewöhnliche IO Pins verwenden um Pegel zu schalten oder abzufragen. RTS und DTR sind Ausgänge, CTS und DSR sind Eingänge.

setRTS(0) wäre meine nächste Idee gewesen. Mit setRTS wird der RTS Pin vom USB UART Modul auf HIGH bzw LOW Pegel gesetzt. Daran hängt der EN Pin vom APC220 Modul. Scheinbar setzt VB.NET den RTS Pin auf 0 beim Öffnen der Schnittstelle und Python auf 1.


wie kann man am Recousenschonendsten die Motoren mit PWM und richtung ansteuern.
Was meinst du mit Ressourcen schonend?
Unter Arduino nimmt man für PWM einfach analogWrite(Pin, 0..255), für die Richtung digitalWrite(Pin, 0..1).