Python Serial Problem

  • Hallo liebe Community,

    habe ein Problem mit meinem Raspi + Arduino Uno, die über USB Serial kommunizieren.

    Wenn ich das ganz mit Sudo python joy.py ausführe und den linken Joystick des PS3 Controller bewege dann blinkt(leuchtet)die RX LED am Arduino.

    Aber der Arduino schaltet nicht meine Lampe(Später soll es mal ein Motor werden).

    Allerdings wenn ich den Arduino Sketch über die IDE Serial Monitor, teste funktioniert alles.

    Könnt ihr mir helfen?


    #!/usr/bin/env python

    import os, sys, pygame
    from pygame import locals
    import time
    import RPi.GPIO as GPIO
    import serial
    ser = serial.Serial(
    port='/dev/ttyACM0',\
    baudrate = 115200,\
    stopbits=serial.STOPBITS_ONE,\
    bytesize=serial.EIGHTBITS,\
    timeout=2,)


    os.environ["SDL_VIDEODRIVER"] = "dummy"
    pygame.init()

    pygame.joystick.init() # main joystick device system


    try:
    j = pygame.joystick.Joystick(0) # create a joystick instance
    j.init() # init instance
    print 'Enabled joystick: ' + j.get_name()
    except pygame.error:
    print 'no joystick found.'


    while 1:
    for e in pygame.event.get(): # iterate over event stack
    if e.type == pygame.locals.JOYAXISMOTION: # Read Analog Joystick Axis
    x1 , y1 = j.get_axis(0), j.get_axis(1) # Left Stick
    y2 , x2 = j.get_axis(2), j.get_axis(3) # Right Stick

    print x1
    print y1
    print x2
    print y2

    if y1 < 0.01 :
    print ' nullstellung'
    ser.write("500")

    if y1 > 0.10 and y1 < 0.20:
    print 'Left Joystick 1 backwards 10'
    ser.write("550")

    if y1 > 0.21 and y1 < 0.3 :
    print 'Left Joystick 1 backwards 20'
    ser.write("600")
    )

    if y1 > 0.31 and y1 < 0.40 :
    print 'Left Joystick 1 backwards 30'
    ser.write("650")

    if y1 > 0.41 and y1 < 0.50 :
    print 'Left Joystick 1 backwards 40'
    ser.write("700")

    if y1 > 0.51 and y1 < 0.60 :
    print 'Left Joystick 1 backwards 50'
    ser.write("750")

    if y1 > 0.61 and y1 < 0.70 :
    print 'Left Joystick 1 backwards 60'
    ser.write("800")

    if y1 > 0.71 and y1 < 0.80 :
    print 'Left Joystick 1 backwards 70'
    ser.write("850".encode())


    if y1 > 0.81 and y1 < 0.90 :
    print 'Left Joystick 1 backwards 80'
    ser.write("900")
    ser.flush

    if y1 > 0.91 and y1 < 0.99999999999999999999999 :
    print 'Left Joystick 1 backwards 100'
    ser.write("950")


               
        
    time.sleep(stepDelay)

  • Bitte benutze die code-tags, und wenn man ein Problem hat, welches sich auf zwei Programme verteilt - PI/Python, Arduino/C - dann sollte man die auch beide zeigen, denn der Sender kann so korrekt sein wie er will, wenn der Empfaenger es nicht ist.

    Das eingestreute ".encode()" bei Rueckwaertsfahrt ist bestimmt auch nicht richtig so. "ser.flush" bewirkt auch mal gerade gar nix - du rufst die Methode naemlich nicht auf. Dazu braucht es Klammern dahinter.

    Was ich allerdings vermute, ist ein sehr simples Problem: dir fehlt ein Newline am Ende deiner Uebertragung - die wirst du im Terminal-Programm erzeugen, weil du ja irgendwann auf Enter/Return haust, um deine Eingabe abzuschliessen.

    Um das Problem also zu loesen, wuerde ich eine kleine Funktion empfehlen, welche das simple Protokoll, dass du momentan hast (Nummer verschicken) kapselt:

    Code
    def send_command(command):
            ser.write("%i\n" % command)
    
    
    send_command(600) # ACHTUNG, EIN INTEGER - KEIN STRING
  • Das Komma nach timeout=2 ist zu viel. Es folgt kein Argument mehr also bedarf es hier kein , mehr.

    Es könnte u.U. auch helfen "timeout" auf 1 zu stellen, das ist nämlich keine Zeitangabe. 2 bewirkt "block read" und 1 bewirkt "non-block read"

    Füg aber auch mal noch das mit ein: parity=serial.PARITY_NONE


    if y1 > 0.21 and y1 < 0.3 :
    print 'Left Joystick 1 backwards 20'
    ser.write("600")
    )

    Was soll die allein stehende ) bewirken?


    if y1 > 0.71 and y1 < 0.80 :
    print 'Left Joystick 1 backwards 70'
    ser.write("850".encode())

    Das ist die falsche Anwendung von .encode()
    Was willst du damit bezwecken?


    if y1 > 0.81 and y1 < 0.90 :
    print 'Left Joystick 1 backwards 80'
    ser.write("900")
    ser.flush

    ser.flush ist ebenfalls die falsche Anwendung, wenn dann muss es ser.flush() lauten, eben der Aufruf einer Funktion.

  • Das Komma nach timeout=2 ist zu viel. Es folgt kein Argument mehr also bedarf es hier kein , mehr.

    Beduerfen nicht, falsch ist es trotzdem nicht, und ich benutze es sehr gerne, weil praktisch.

    Code
    funktions_aufruf(
         eine,
         liste,
         argumente,
         die,
         ich,
         beliebig,
         verschieben,
         kann,
    )

    Diese trailing-Kommas sind ein sehr praktisches Feature von Python, weil man so Argumentlisten fuer Funktionsaufrufe und Datenstrukturliterale flexibler hin und her kopieren kann. Einer der Gruende dafuer, warum das GYP-Projekt (build-system von Google Chrome) Python-Syntax statt "normalem" JSON verwendet.

  • Reinkopieren, aufrufen. Wirklich nicht mehr. Und das wirst du schon selbst hinbekommen.

  • Hallo hab etwas umgestellt und der Python Textausschnitt sieht so aus:


    Code
    arduino.write(struct.pack('>b',b2))


    und mein Arduino Sketch sieht so aus:


    Allerdings glimmt meine Lampe (läuft noch über ein BTS7960 keine Angst) beim losslassen des Joystick noch ganz leicht sowie der Joystick regelt komisch.


    Könnt ihr mir weiterhelfen?

  • Nur eine Zeile Python-Code? Ist das dein Ernst?

    Und ich sehe schon einen dicken Fehler - a2 = a1*2,55 macht *NICHT* was du glaubst, was es tut. Fliesskommazahlen werden in C mit Punkt separiert, und du hast stattdessen also den Faktor 2, und ein Komma, und dann eine voellig unbenutzte 55. Bei meinem Compiler gibt das eine Warnung "expression result unused".

    Ob das deine Probleme erklaert - kA.

  • Hallo liebes Community,

    habe noch etwas am Sketch geschraubt:

    Python:

    ARDUINO:


    Allerdings hab ich den Linken Joystick soweit gebracht,

    dass ich mit den Achsenbewegungen des Controller eine Lampe die an einem BTS7960 hängt ,

    leuchten lassen kann.(siehe Details unten)


    Allerdings leuchtet die Lampe nur richtig in 2 der 4 Achsenbewegungen.

    In den andern 2 Achsen Pulst sie sehr arg. :wallbash: :wallbash:


    Woran könnte das liegen?

    Vielen Dank schon mal in vorraus:)

  • Die Funktion senden sollte die Parameter a1, a2 als Argumente bekommen, nicht einfach globale Variablen verwenden.

    Was in dem Arduino-Sketch schon mal *GANZ* boese ist: du hast ein Array incoming mit zwei Bytes darin. Und dann liest du VIER bytes darein, wobei du froehlich die Arraygrenzen ueberschreitest und mit voellig unbekannter Wirkung in Speicher reinschreibst, den du nicht angefordert hast. Das muss repariert werden.

    Ausserdem ist diese Erwartung - 4 Bytes - ja auch Unsinn, wenn du vom Host immer nur 2 Bytes schickst pro Abfrage-Schleife.

    Und ansonsten ist mir das alles zu verfummelt. Bitte benenn deine Variablen und Konstanten ordentlich, damit man weiss, was die tun soll. Beschreib, was deine Steuerung eigentlich machen soll - PWM & Richtung, oder unterschiedliche PWMs oder was genau soll da eigentlich bei rumkommen.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!