【发布时间】:2021-05-13 10:00:00
【问题描述】:
我组装了一个 Kivy 应用程序,该应用程序从用户触摸中获取坐标并通过蓝牙将它们发送到 arduino
我正在按照以下链接中列出的如何在 android 上处理蓝牙的步骤进行操作: https://developer.android.com/guide/topics/connectivity/bluetooth#ManageAConnection
按下“连接蓝牙”按钮时会调用 Fct ConnectBluetooth()。这是我寻找 arduino HC-05 蓝牙接收器并设置套接字以及输入和输出流的地方。
然后我使用 fct SendCoordinates() 来使用输出流并通过蓝牙发送数据。但是,当调用此函数时,出现以下错误: error while sending bluetooth data on Android
我认为您传递给输出流的 write() 函数的参数必须是字节数组。我想它不是。有谁知道我必须通过什么?将字符串转换为字节数组时我做错了什么?("ByteString = bytes(StrPositionData,'utf-8')")
当我谈到这个主题时,如何使用 inPutStream 从我在 Android 上的 Kivy 读取蓝牙数据?该指南指出 read(byte[]) “应该在单独的线程中调用”,因为它会阻塞直到它接收到数据。如何在 python 中添加这个单独的线程?
代码如下:
main.py:
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.anchorlayout import AnchorLayout
#from subprocess import Popen,PIPE
from kivy.core.window import Window
from kivy.clock import Clock
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty, ObjectProperty
from kivy.uix.image import Image
from kivy.utils import get_color_from_hex
from kivy.graphics import Color, Rectangle
from kivy.lang import Builder
from kivy.base import runTouchApp
from kivy.core.text import LabelBase
from jnius import autoclass
UUID = autoclass('java.util.UUID')
LabelBase.register(name="Nobile",
fn_bolditalic="fonts/Nobile/Nobile-BoldItalic.ttf",
fn_regular="fonts/Nobile/Nobile-Regular.ttf")
class HomeScreen(Screen):
mvoltage = ObjectProperty(None)
print('Start')
port = "COM4"
BluetoothAdapter = autoclass('android.bluetooth.BluetoothAdapter')
#init input & output streams
SendSerialData = None
ReceiveSerialData = None
#flag to signal initialized bluetooth
BluetoothInit = 0
def __init__(self, **kwargs):
super(HomeScreen, self).__init__(**kwargs)
#Clock.schedule_interval(self.ReceiveSerialData, 2)
try:
print("Looking for Bluetooth On Windows")
#bluetooth_device = serial.Serial(self.port, 9600, timeout=1)
print("Connected to HC-05")
except Exception as e:
print("Looking for Bluetooth On Android")
def SendCoordinates(self, XCoordinate, YCoordinate):
#conver positionData to string
StrPositionData = str(XCoordinate)+','+' '+str(YCoordinate)
ByteString = bytes(StrPositionData,'utf-8')
self.SendSerialData.write('{}\n'.format(ByteString))
self.SendSerialData.flush()
def on_touch_down(self, touch):
if self.BluetoothInit == 1:
self.SendCoordinates(touch.sx, touch.sy)
return super(HomeScreen,self).on_touch_down(touch)
def on_touch_up(self,touch):
try:
self.bluetooth_device.write(b"STOP")
print('STOP'.encode())
except:
pass
def on_touch_move(self, touch):
pass
def ReceiveSerialData(self,dt):
Serial_Data=[124]
ReceivedBytes = 0
try:
Serial_Data = self.bluetooth_device.readline().decode()
except:
if self.BluetoothInit == 1:
ReceivedBytes = self.ReceiveSerialData.read(Serial_Data)
print(Serial_Data)
#Number = int(Serial_Data)
#if Number >= 10000:
#NR = Serial_Data[0:2]
#Decimals = Serial_Data[2:4]
#else:
#NR = Serial_Data[0]
#Decimals = Serial_Data[1:3]
#self.mvoltage.text = NR + '.' + Decimals + ' ' + 'Volts'
def ConnectBluetooth(self):
#try to connect on windows
try:
print("Connecting to Bluetooth" )
self.port = "COM4"
self.bluetooth_device = serial.Serial(self.port, 9600, timeout=1)
print("Connected to HC-05")
#windows failed, try connecting on Android
except Exception as e1:
paired_devices = self.BluetoothAdapter.getDefaultAdapter().getBondedDevices().toArray()
socket = None
for device in paired_devices:
if device.getName() == 'HC-05':
socket = device.createRfcommSocketToServiceRecord(
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
self.ReceiveSerialData = socket.getInputStream()
self.SendSerialData = socket.getOutputStream()
break
socket.connect()
#signal that bluetooth connection established
self.BluetoothInit = 1
except Exception as e2:
raise Exception('Cant Connect Bluetooth on Windows or Android')
class SecondScreen(Screen):
pass
class WindowManager(ScreenManager):
pass
kv=Builder.load_file('Crane.kv')
class MainApp(App):
def build(self):
return kv
if __name__ == "__main__":
TestApp = MainApp()
TestApp.run()
.kv 文件:
#:import utils kivy.utils
WindowManager:
HomeScreen:
SecondScreen:
<HomeScreen>:
name: "Crane App"
mvoltage:MotorVoltage
FloatLayout:
canvas.before:
Color:
rgb: utils.get_color_from_hex("#ffffff")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
canvas.before:
Color:
rgb: utils.get_color_from_hex("#ffffff")
Rectangle:
size: self.size
pos: self.pos
rows: 1
cols: 3
padding:10
FloatLayout:
GridLayout:
canvas.before:
Color:
rgb: utils.get_color_from_hex("#ffffff")
Rectangle:
size: self.size
pos: self.pos
rows: 2
cols: 1
spacing:5
padding:5
pos_hint:{"top": 1, "left": 1}
Image:
source: "icons/extend_boom.PNG"
allow_stretch: True
keep_ratio: False
Image:
source: "icons/lift_boom.PNG"
allow_stretch: True
keep_ratio: False
AnchorLayout:
id:Anchor_Left
pos_hint:{"left": 0.60, "top": 1}
size_hint: 1, 1
GridLayout:
id:LeftButtons
rows:2
Button:
id:extend_boom
background_color:(255,255,255,0)
Button:
id:lift_boom
background_color:(255,255,255,0)
GridLayout:
canvas.before:
Color:
rgb: utils.get_color_from_hex("#ffff00")
Rectangle:
size: self.size
pos: self.pos
rows: 5
cols: 1
padding:5
spacing:5
size_hint: .54, 1
Label:
text:"Motor Voltage"
color: 0,0,0,1
font_name:"Nobile"
bold:True
TextInput:
id:MotorVoltage
Label:
text:"Controller Voltage"
color: 0,0,0,1
font_name:"Nobile"
TextInput:
id: ControllerVoltage
Button:
id:connect_bluetooth
text:"Connect to Bluetooth"
background_color:(0,0,0,0.9)
on_press:
root.ConnectBluetooth()
FloatLayout:
GridLayout:
canvas.before:
Color:
rgb: utils.get_color_from_hex("#ffffff")
Rectangle:
size: self.size
pos: self.pos
rows: 2
cols: 1
spacing:5
padding:5
pos_hint:{"top": 1, "right": 1}
Image:
source: "icons/lift_hook.PNG"
allow_stretch: True
keep_ratio: False
Image:
source: "icons/rotate.PNG"
allow_stretch: True
keep_ratio: False
AnchorLayout:
id:Anchor_Right
pos_hint:{"right": 1, "top": 1}
size_hint: 1, 1
GridLayout:
id:LeftButtons
rows:2
Button:
id:lift_hook
background_color:(255,255,255,0)
Button:
id:rotate
background_color:(255,255,255,0)
<SecondScreen>:
name: "Passenger Contact Info"
Button:
text: "Go Back"
on_press:
app.root.current="Bus Map"
root.manager.transition.direction="left"
提前感谢您的帮助。
亚历克斯
【问题讨论】:
标签: python android python-3.x bluetooth kivy