2017-12-11 4 views
0

私はRaspberry Pi 3で実行中のクライアントスクリプトを持っています。クライアントはTRUEかFALSEのいずれかをサーバから受信しています。その後、デコードするバイト状のオブジェクトを受け取り、この情報を使用してGUIに画像を表示します。常にsocket.recv()を評価してください

ボタンを押してGPIOピンがTRUEになるかどうかをチェックし、最初の.recv()に戻ります。

「新しいゲーム」というメッセージが表示された場合は常にクライアントにチェックを行い、そうであればTRUEまたはFALSEの最初の.recv()に移動します。

しかし、私の.recv()関数ブロックは私がそこに詰まっている間は何もできません。

GPIOの状態がTRUEに変わったかどうかを確認しながら情報を受け取ることができるかどうかを確認する方法を教えてください。

コードは次のようになります。

#imports needed 
import socket 
import RPi.GPIO as GPIO 
import time 
import tkinter as tk 
import pygame 

#Setup of GPIO pin for buttons used as bumpers 
GPIO.setmode(GPIO.BOARD) 
GPIO.setup(36, GPIO.IN, pull_up_down=GPIO.PUD_UP) #Pin 36 = GPIO16 


#Setup of root window for the GUI and the different images 
root = tk.Tk() 
root.attributes('-fullscreen',True) 

image6 = tk.PhotoImage(file="/home/pi/Desktop/wav/wrong.gif") 
wronglabel = tk.Label(image=image6) 

image5 = tk.PhotoImage(file="/home/pi/Desktop/wav/correct.gif") 
correctlabel = tk.Label(image=image5) 

image4 = tk.PhotoImage(file="/home/pi/Desktop/wav/questionmark.gif") 
questionlabel = tk.Label(image=image4) 

pygame.init() 

#Setup of the different sounds to use in the project 
correctsound = pygame.mixer.Sound('/home/pi/Desktop/wav/correct.wav') 
wrongsound = pygame.mixer.Sound('/home/pi/Desktop/wav/wrong.wav') 

HOST = '192.168.1.34' # The remote host, 
PORT = 50007    # The same port as used by the server 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
try: 
    s.connect((HOST, PORT)) 

except: 
    print("FAILED. Sleep briefly & try again") 
    time.sleep(10) 
    continue 

questionlabel.pack() 
root.update() 
while True: 
    data = s.recv(1024) 
    if data == b'True': 
     print('I am the true cone') 
     state = True   
    if data == b'False': 
     print('I am the false cone') 
     state = False 


    byte_string = s.recv(1024) 
    path = '/home/pi/Desktop/wav/%s.gif' % byte_string.decode() 
    questionlabel.pack_forget() 

    image1 = tk.PhotoImage(file=path) #x should change accordingly to the received message 
    Thelabel = tk.Label(image=image1) 
    Thelabel.pack() 
    root.update() 

    i=0 
    while i==0: 
     if GPIO.input(36) == True: 
      if state == True: 
       Thelabel.pack_forget() 
       correctlabel.pack() 
       root.update() 
       correctsound.play() 
       s.sendall(b'True Hit') 
       time.sleep(5) 
       correctlabel.pack_forget() 
       questionlabel.pack() 
       root.update() 

      if state == False: 
       Thelabel.pack_forget() 
       wronglabel.pack() 
       root.update() 
       wrongsound.play() 
       time.sleep(5) 
       wronglabel.pack_forget() 
       questionlabel.pack() 
       root.update() 
      i=1 
+1

を非同期入出力、それを処理する方法はたくさんあります。可能な解決策は、 'select.poll'の使用、スレッドの使用、または' asynchio'モジュール(他の中でも!)を調べることです。 'Rpi.GPIO'は非同期コールバックベースの割り込みメカニズムも実装しています。これにより、' recv'へのブロッキングコールをしながら解決策を実装することができます。たぶん、さまざまなオプションを調べるのに時間がかかるかもしれません。 – larsks

+0

ここでは多くのことが間違っているので、どこから開始するのか分からない:/いずれにせよ、あなたのクライアント/サーバをチェックする別のスレッドが必要です – dgan

+0

@dgan変更や批判の提案は自由についてきます。正しいメッセージを受け取ったときにこのスレッドをもう一度起動させるよりも、 –

答えて

0

まあ、それは、あなたがここにしようとしたかを理解することは非常に難しいあなたが唯一のグローバル変数、不可欠コードスタイルを持っており、すべてがインターリーブされて...私が得るのに苦労していますまさにあなたが必要とするものです。私のコードは、あなたの問題を解決することを見込みはありません

すぐに、私はそれはあなたがあなたの問題解決するために掘る場所を理解するのに役立つことを願っています:あなたがについて尋ねている

# imports needed 
import socket 
import RPi.GPIO as GPIO 
import time 
from threading import Thread 

try: 
    from Tkinter import * 
except ImportError: 
    from tkinter import * 

import pygame 

# Setup of GPIO pin for buttons used as bumpers 
GPIO.setmode(GPIO.BOARD) 
GPIO.setup(36, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Pin 36 = GPIO16 


class MyTk(): 
"""All tkinter stuff goes here""" 

    def __init__(self, pygame_app): 
     self.root = Tk() 
     self.pygame_app = pygame_app 
     self.pygame_app.init() 
     self.root.attributes('-fullscreen', True) 

     image6 = PhotoImage(file="/home/pi/Desktop/wav/wrong.gif") 
     self.wronglabel = Label(image=image6, master=self.root) # ? unused 

     image5 = PhotoImage(file="/home/pi/Desktop/wav/correct.gif") 
     self.correctlabel = Label(image=image5, master=self.root) # ? unused 

     image4 = PhotoImage(file="/home/pi/Desktop/wav/questionmark.gif") 
     self.questionlabel = Label(image=image4, master=self.root) 

     self.questionlabel.pack() 
     self.root.update() 

    def update_for_right(self): 
     correctsound = self.pygame_app.mixer.Sound('/home/pi/Desktop/wav/correct.wav') 
     self._forget_TheLabel() 
     correctsound.play() 
     time.sleep(5) 
     self._forget_correct() 

    def _set_TheLabel(self, path): 
     image1 = PhotoImage(file=path) # x should change accordingly to the received message 
     self.Thelabel = Label(image=image1, master=self.root) 
     self.Thelabel.pack() 
     self.root.update() 

    def update_for_wrong(self): 
     # Setup of the different sounds to use in the project 
     wrongsound = self.pygame_app.mixer.Sound('/home/pi/Desktop/wav/wrong.wav') 
     wrongsound.play() 
     time.sleep(5) 
     self._forget_wrong() 

    def _forget_wrong(self): 
    """you should not call underscored methods from outside of this class""" 
     self.wronglabel.forget() 
     self.root.update() 

    def _forget_correct(self): 
     self.correctlabel.pack_forget() 
     self.questionlabel.pack() 
     self.root.update() 

    def _forget_TheLabel(self): 
     self.Thelabel.pack_forget() 
     self.root.update() 

    def _forget_question_label(self): 
     self.questionlabel.pack_forget() 
     self.root.update() 


class MySocket(): 
"""All socket stuff goes here""" 
    def __init__(self, tkinter_app, host='192.168.1.34', port=5007): 
    """This class needs a dependency(tkinter), so pass it as constructor argument, and use it later""" 

     self.host = host 
     self.port = port 
     self.tkinter_app = tkinter_app 

    def try_connect(self): 
     self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     while 1: 
      try: 
       self.s.connect((self.host, self.port)) 
       return 
      except: 
       print("FAILED. Sleep briefly & try again") 
       time.sleep(10) 

    def listen(self): 
     """This blocks execution until something is received""" 
     while True: 
      data = self.s.recv(1024) 
      if data == b'True': 
       byte_string = self.s.recv(1024) # antoher signal is sent? 
       print('I am the true cone') 
       state = True 
       self.do_stuff(state, data) 
      else: 
       # this is useles... 
       print('I am the false cone') 
       state = False 

    def do_stuff(self, state, data): 
     path = '/home/pi/Desktop/wav/%s.gif' % data.decode() 
     self.tkinter_app._set_TheLabel(path) 
     if GPIO.input(36) == True: 
      if state: 
       self.s.sendall(b'True Hit') 
       self.tkinter_app.update_for_right() 

      else: 
       self.s.sendall(b'False Hit') # ? 
       self.tkinter_app.update_for_wrong() 

     return 


if __name__ == '__main__': 
    mytk = MyTk(pygame) 
    mysk = MySocket(mytk) 
    mysk.try_connect() 
    # this call blocks; so you need at least another thread to run your Tkinter 
    th = Thread(target=mytk.root.mainloop) # launch tkinter GUI 
    th.start() 
    # this block the main thread 
    mysk.listen() 
関連する問題