2017-12-11 7 views
0

라즈베리 파이 3에서 실행되는 클라이언트 스크립트가 있습니다. 클라이언트가 서버에서 TRUE 또는 FALSE를 수신하고 있습니다. 그런 다음 디코딩 된 바이트와 유사한 객체를 수신하고이 정보를 사용하여 GUI에 이미지를 표시합니다.항상 socket.recv()를 평가하십시오.

GPIO 핀이 버튼 누름에서 TRUE가되는지 확인한 후 첫 번째 .recv()로 돌아갑니다.

"새 게임"이라는 메시지가 나타나면 클라이언트가 항상 확인하고, 그렇다면 첫 번째 .recv()로 이동하여 TRUE 또는 FALSE인지 확인합니다.

하지만 내 .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

을 비동기 I/O이며, 여러 가지 방법으로 처리 할 수 ​​있습니다. 가능한 해결책은'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()