3

そこで、cherrypy と pyserial を使用して、Arduino Uno とやり取りするための Web インターフェイスをコーディングしました。それはかなり完全です。私が見逃していて、1日かけて理解しようとしてきた唯一のことは、Arduinoから送信されたデータを継続的に読み取り、html内のメッセージを含むdivを自動的に表示することですコード。コンソールに表示できますが、実際のhtmlを返すことができません。実際、return を使用することはできません。print を使用する必要がありますが、コンソールではなく html ページのデータが必要なため、これは便利ではありません。これを行うために多くの方法を試しました。

これが私のコードです。かなり単純です。定数関数は、Arduino から送信されるデータを読み取り続け、コンソールに送信します。ライブアップデートのように、htmlコードに送信したい。どうすればいいですか?

# -*- coding: Utf-8 -*-

import cherrypy, arduino, time, threading

ser=arduino.Serial('COM4', 9600)

def constant():
    while True:
        m=''
        print('running')
    while True:
        print('sub_running')
        byte=(ser.read().encode('Utf-8'))
        if byte=='*':
            break
        m=m+byte
        time.sleep(1)
    print(m)
    time.sleep(1)

class website(object):
    def index(self):
        return '''
            <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script><script src="annexes/functions.js"></script>
            <link rel=stylesheet type=text/css media=screen href="/annexes/design.css">
            <form action="command" method="POST">
            <input type="submit" name="command" value="Turn the LED on" text="hey"/>
            <input type="submit" name="command" value="Turn the LED off"/>
            </form>
        '''    
    index.exposed=True

    def command(self, command):
        m=''
        if command=='Turn the LED on':
            ser.write('1')
        if command=='Turn the LED off':
            ser.write('0')
        self.index
    command.exposed=True

_thread = threading.Thread(target=constant)
_thread.setDaemon(True)
_thread.start()

cherrypy.quickstart(website(), config='config.conf')
4

1 に答える 1

0

やりたいことを実行するには、次の 2 つのオプションがあります。

  • 生成された Web ページを表示するたびに動的データを印刷し、クライアント側でメタ リフレッシュ (または JavaScript リフレッシュ) を追加するか、
  • 新しいデータが入るたびに更新されるロング ポーリング ルートを作成します (このを参照してください) 。

しかし、あなたの質問の核心は、スレッド関数から Web サイト クラスに値を送信する方法に関連していると思います。を使用する必要がありますQueue.Queue: この例は、cherrypy を使用してロング ポーリング リクエストを作成する方法を示しています。

次の例では、cherrypy と long-polling を理解するための良い読み物である、このサイトjsonyieldで利用可能なデコレータを見逃すでしょう。

# -*- coding: utf-8 -*-

import cherrypy, arduino, time, threading
import Queue

def serialWatcher(ser, queue):
    while True:
        m=''
        print('running')
    while True:
        print('sub_running')
        byte=(ser.read().encode('Utf-8'))
        if byte=='*':
            break
        m=m+byte
        time.sleep(1)
    queue.put(m)
    time.sleep(1)

class website(object):
    def __init__(self, ser, queue):
        self.serial = ser
        self.queue = queue

    # it's often better to use decorators when you can
    @cherrypy.expose
    def index(self):
        return '''
            <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script><script src="annexes/functions.js"></script>
            <link rel=stylesheet type=text/css media=screen href="/annexes/design.css">
            <form action="command" method="POST">
            <input type="submit" name="command" value="Turn the LED on" text="hey"/>
            <input type="submit" name="command" value="Turn the LED off"/>
            </form>
        '''

    @cherrypy.expose
    def command(self, command):
        m=''
        if command=='Turn the LED on':
            self.serial.write('1')
        if command=='Turn the LED off':
            self.serial.write('0')
        return self.index() # I assume that's what you wanted to write

    @cherrypy.expose
    @json_yield
    def get_arduino_results(self):
        """you can get the result of this long polling request using a JS AJAX query"""
        while True:
            while not self.queue.empty():
                yield self.queue.get()


# always use the following, so you can also use the module you're writing as imports
# in other modules
if __name__ == "__main__":
    q = Queue.Queue()
    # Never use global variables, always pass them as parameters
    ser = arduino.Serial('COM4', 9600) 

    _thread = threading.Thread(target=serialWatcher, args=(ser, q))
    _thread.setDaemon(True)
    _thread.start()

    cherrypy.quickstart(website(ser, q), config='config.conf')

but the same principle would work for a standard page, something like:

    @cherrypy.expose
    get_arduino_results(self):
        out = "<ul>"
        while not self.queue.empty():
            out += "<li>" + self.queue.get() + "</li>"
        return out + "</ul>

a を使用する全体的な考え方はQueue、arduino ウォッチング スレッドとチェリーピー スレッドの間で情報を交換する際に、スレッド化の問題が発生するリスクがないということです。Queue はスレッド セーフであり、読み取り/書き込みを同期するため、順序どおりに、一度に 1 つのスレッドになります。

HTH

于 2013-06-19T13:05:52.720 に答える