Websocket - Befehle in eine Schleife

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
tenor
User
Beiträge: 24
Registriert: Samstag 2. Januar 2016, 19:32

Hallo,
ich habe micht etwas mit Websockets beschäftigt und der "Chat" zwischen Browser und Raspi steht schon mal :)

Code: Alles auswählen

import RPi.GPIO as GPIO
import tornado.ioloop
import tornado.web
import tornado.httpserver
import tornado.websocket
import time
import os
 
PIN_OUT_1 = 29
PIN_OUT_2 = 31
PIN_RECHTS = 28
PIN_LINKS = 30
 
GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN_OUT_1, GPIO.OUT)
GPIO.setup(PIN_OUT_2, GPIO.OUT)
GPIO.setup(PIN_RECHTS, GPIO.OUT)
GPIO.setup(PIN_LINKS, GPIO.OUT)

class WSHandler(tornado.websocket.WebSocketHandler):

  if drive == 1:
       print 'servo start'
       Servo.start(50)

  def check_origin(self, origin):
    return True

  def open(self):
    print 'New connection was opened'
    self.write_message("Welcome to my websocket!")
 
  def on_message(self, message):
    print 'Incoming message:', message
    self.write_message("You said: " + message)
   
    if  message == "fahren":
        GPIO.output(PIN_OUT_2, False)
        Servo = GPIO.PWM(PIN_OUT_1, 50)
        drive = 1

    if message == "halten":
        print 'Eingabe erkannt', message
        GPIO.output(PIN_OUT_2, False)
        Servo = GPIO.PWM(PIN_OUT_1, 50)
        drive = 2
        
  def on_close(self):
    print 'Connection was closed...'
    GPIO.cleanup()
 
application = tornado.web.Application([
  (r'/ws', WSHandler), ])
 
if __name__ == "__main__":
  http_server = tornado.httpserver.HTTPServer(application)
  http_server.listen(8888)
  tornado.ioloop.IOLoop.instance().start()
Ich habe hier offensichtlich noch ein paar defizite bzgl. des Handlers.
Sobald eine Nachricht eintrifft, wird mir das mit message übergeben und ich kann diese in IF statements verarbeiten.
Das Problem ist, wenn "fahren" kommt, arbeitet python den Code nur einmal schnell ab, so dass der PWM Befehl nicht weiter ausgeführt wird.
Dieser soll aber so lange ausgeführt werden, bis das halten Signal kommt.
Im HTML Skript wird das halten sofort gesendet, wenn ich den Knopf los lasse.

Mein Versuch Schleifen zu machen innerhalb der on_message Funktion, schlug fehl.
Mein nächste Versuch lag darin den PWM Befehl ausserhalb der on_message Funktion auszuführen, in der Hoffnung das der Code an der Stelle auch normal abgearbeitet wird.
Leider wird er dort nicht ausgeführt.

Was kann ich hier tun?

Ich dachte die Handler agieren hier wie Interrupts und das ansonsten das Python Programm normal weiter läuft.
Vielen Dank!
Gruß
Tenor
Zuletzt geändert von Anonymous am Mittwoch 13. Januar 2016, 19:36, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@tenor: Der Code dürfte gar nicht laufen weil der Name `drive` in Zeile 22 nicht definiert ist. Und in dem ``if``-Block wird der Name `Servo` verwendet der auch nicht definiert wäre.

`on_message()` wird von der `tornado`-Schleife aufgerufen die Du ganz am Ende startest. Wenn in der Funktion eine Schleife läuft kann solange Tornado nichts machen, denn das bekommt die Kontrolle ja erst wieder wenn `on_message()` zur Tornado-Hauptschleife zurückkehrt. Also vergiss das mit Interrupts, das ist ein ganz normales Programm das linear abgearbeitet wird.

`drive` und `Servo` (das eigentlich `servo` heissen sollte) müssten Attribute des Handler-Objekts sein, damit sie über Aufrufe hinweg weiterbestehen. Und das sollte auch die Lösung für das Weiterlaufen sein, denn wenn ich mich recht erinnere hört PWM auf wenn das PWM-Objekt zerstört wird. Das darf also nicht nur lokal in `on_message()` existieren.
tenor
User
Beiträge: 24
Registriert: Samstag 2. Januar 2016, 19:32

Danke Black Jack für die ausführlich Antwort!

Ausgeführt wird der Code, ich dachte mir wenn ich die drive variable erst in der if schleife auf 1 setze, wird der Servo ja vorher definiert.
Scheint der Compiler auch so gesehen zu haben, auch wenn das keine schöne Option ist.

Dem Handler-Objekt ein Attribut hinzufügen..
Hast du dafür ein Beispiel?
Wurde so etwas in einem anderen Projekt schon gemacht? Wahrscheinlich schon, aber ich suche schon die ganze Zeit nach einem Beispiel für diese Lösung.
BlackJack

@tenor: Der Code so wie er da steht läuft in Zeile 22 in einen `NameError` weil `drive` vorher nicht definiert wurde.

So ziemlich jedes Projekt, egal zu welchem Thema, das eigene Klassen definiert, sollte ein Beispiel sein wie man Attribute definiert. Ich denke nicht das man die Grundlagen von objektorientierte Programmierung durch kopieren von Beispielen lernen sollte. Das Du den Code in Zeile 22ff. auf Klassenebene geschrieben hast sieht schon verdächtig nach Programmieren durch raten aus. So funktioniert das nicht.
tenor
User
Beiträge: 24
Registriert: Samstag 2. Januar 2016, 19:32

In der Tat, ich tue mich sehr schwer mit objektorientierter Programmierung, das war schon in der Schule mit C++ der Fall.
Am liebsten habe ich bisher mit Basic und Pascal programmiert (ohne den OOP Ansazu).

Ich hatte gehofft das ich das hier Schrittweise erlernen könnte, dann muss ich weiter schauen.
Trotzdem Danke für deine Mühen!
Gruß
Tenor
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

tenor hat geschrieben:... if schleife ...
www.if-schleife.de
In specifications, Murphy's Law supersedes Ohm's.
Antworten