2017-02-21 21 views
0

私はBT経由でEV3ロボット(レゴのロボット)と通信する小さなPythonプログラムを手に入れました。プログラムはEV3に1/2または3の数字を送り、ロボットはあらかじめ定義された移動を行い、移動が完了し、次のコマンドの準備ができたことを示す「A」を戻します。socket.recv(Python)のエラー

システムは素晴らしいですが、しばらくの間、このエラーメッセージでpythonアプリケーションがクラッシュします。 'ホストマシンのソフトウェアによって確立された接続が中断されました。これは、btListener()スレッド内で呼び出されるsocket.recvに由来します。

関連のpythonパーツ:

import bluetooth 
    from gmail import * 
    import re 
    from gtts import gTTS 
    from time import sleep 
    import pygame 
    import serial 
    import thread 
    import os 
    import ftplib 
    from StringIO import StringIO 
    from blynkapi import Blynk 

    def a(): #Send 'a' to 'Status' mailbox 
     print "Send a to robot" 
     for i in commandA: 
      client_sock.send(chr(i)) 
     sleep(1) 

    def b(): # Send 'b' to 'Status' mailbox 


    def c():  # Send 'c' to 'Status' mailbox 


    def clear(): # Send clear array to 'Status' mailbox 
     for i in clearArray: 
      client_sock.send(chr(i)) 

    def btListener(): 
     # Listen for end of run reply from the EV3 
     global ev3Flag, listenFlag 
     while True: 
      if listenFlag and (not ev3Flag): 
        try: 
         data = client_sock.recv(1024)  #Check if EV3 is ready for new command 
         if data[-2] == 'A': 
          ev3Flag = True 
          print "Received 'Ready' from EV3 " 
          sleep(1) 
        except Exception as e: 
         print(e) 
         print "Failed to read data from socket" 


    def queueHandler(): 
     # Read next command from QueueArray, call sendFunc and clear the queue 
     global ev3Flag, listenFlag, queueArray 
     while True: 
      if len(queueArray) > 0 and ev3Flag: 
       sendFunc(queueArray[0]) 
       queueArray.pop(0) 


    def sendFunc(cmd): 
     #Send the next command on QueueArray to the EV3 
     global ev3Flag, listenFlag 
     if cmd == 1: 
      try: 
       ev3Flag = False 
       listenFlag = False 
       a() 
       listenFlag = True 
       sleep(3)     
       clear()     # clear the EV3 btsocket with a default message 
      except Exception as e: 
       print "Error on sendFunc cmd = 1" 
       print(e) 

     elif cmd == 2: 
      try: 
      except Exception as e: 

     elif cmd == 3: 
      try: 
      except Exception as e: 


    if __name__ == "__main__": 
     # Blynk setup 
     blynk = Blynk(auth_token) 
     switch1 = Blynk(auth_token, pin = "V0") 
     switch2 = Blynk(auth_token, pin = "V1") 
     switch3 = Blynk(auth_token, pin = "V2") 
     print "Blynk connected" 

     queueArray = [] # Queue array to hold incoming commands 
     listenFlag = True # Listen to message from EV3 
     ev3Flag = True # EV3 ready for new command flag 

     # BT CONNECTION WITH EV3 # 
     print "Searching for BT connections: " 

     nearby_devices = bluetooth.discover_devices() 

     for bdaddr in nearby_devices: 
      print bdaddr + " - " + bluetooth.lookup_name(bdaddr) 
      if target_name == bluetooth.lookup_name(bdaddr): 
       target_address = bdaddr 
       break 

     server_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM) 

     port = 1 
     server_sock.bind(("", port)) 
     server_sock.listen(1) 

     client_sock, address = server_sock.accept() 
     print "Accepted connection from ", address 

     if target_address is not None: 
      print "found target bluetooth device with address ", target_address 
     else: 
      print "could not find target bluetooth device nearby" 
     # END BT CONNECTION WITH EV3 # 

     try: 
      thread.start_new_thread(queueHandler,()) 
     except Exception as e: print(e) 

     try: 
       thread.start_new_thread(btListener,()) 
     except Exception as e: print(e) 


    while True: 
     res1 = switch1.get_val() 
     res2 = switch2.get_val() 
     res3 = switch3.get_val() 

     if (int)(res1[0]) == 1: 
      print "Add 1 to queue" 
      queueArray.append(1) 

     if (int)(res2[0]) == 1: 
      print "Add 2 to queue" 
      queueArray.append(2) 

     if (int)(res3[0]) == 1: 
      print "Add 3 to queue" 
      queueArray.append(3) 

編集1:

私はもう少しそれをテストし、プログラムがデータをrecvを、データに同じを送信しようとするとクラッシュが発生しているようです時間。 (clear()またはa()/ b()/ c()関数を介して)、それは状況になる可能性がありますか? 私はソケットに慣れていないので、ソケットの動作を制限するフラグを作成することが最初の解決策です。それが起こらないように、より良い/賢明な方法がありますか?

編集2:

私は(クリアするために私のコールの後にsendFunc内部の「listenFlag = TRUE」の行を()に移動)し、おそらくしようとPythonプログラムによるものであった問題を解決しているようです同時に砂を受け取って砂にする。

+0

エラーメッセージは、エラーがスクリプトではなくホストにあることを示します。エラーが発生したときにロボットが起動しているか、またはランダムに接続が失われていないことを確認しましたか? – spicypumpkin

+0

何らかの理由でタイムアウト、ノイズが多すぎる、片方のパケットが正しく受信されなかったなどの理由でBT接続が切断され、クローズドソケットから読み取ろうとしています。 –

+0

@ Posh_Pumpkinロボットはまだ実行中です。 – Voly

答えて

0

私はclear()の呼び出しの後にsendFunc()内の 'listenFlag = True'行を移動しました。これはおそらくpythonプログラムが受信して同時に砂を使用しようとしたために起こった問題を解決するようです。