私は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プログラムによるものであった問題を解決しているようです同時に砂を受け取って砂にする。
エラーメッセージは、エラーがスクリプトではなくホストにあることを示します。エラーが発生したときにロボットが起動しているか、またはランダムに接続が失われていないことを確認しましたか? – spicypumpkin
何らかの理由でタイムアウト、ノイズが多すぎる、片方のパケットが正しく受信されなかったなどの理由でBT接続が切断され、クローズドソケットから読み取ろうとしています。 –
@ Posh_Pumpkinロボットはまだ実行中です。 – Voly