【问题标题】:无法从 Android 上的 Kivy App 发送蓝牙
【发布时间】: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


    【解决方案1】:

    了解如何使用 Android API 发送和接收蓝牙数据。我正在为任何其他 Kivy 初学者发布代码:)

    from jnius import autoclass
    
    class AndroidBluetoothClass:
    
        def getAndroidBluetoothSocket(self,DeviceName):
            paired_devices = self.BluetoothAdapter.getDefaultAdapter().getBondedDevices().toArray()
            socket = None
            for device in paired_devices:
                if device.getName() == DeviceName:
                    socket = device.createRfcommSocketToServiceRecord(
                        self.UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
                    self.ReceiveData = self.BufferReader(self.InputStream(socket.getInputStream()))
                    self.SendData = socket.getOutputStream()
                    socket.connect()
                    self.ConnectionEstablished = True
                    print('Bluetooth Connection successful')
            return self.ConnectionEstablished
    
    
        def BluetoothSend(self, Message, *args):
            if self.ConnectionEstablished == True:
                self.SendData.write(Message)
            else:
                print('Bluetooth device not connected')
    
    
        def BluetoothReceive(self,*args):
            DataStream = ''
            if self.ConnectionEstablished == True:
                DataStream = str(self.ReceiveData.readline())
            return DataStream
    
    
        def __init__(self):
            self.BluetoothAdapter = autoclass('android.bluetooth.BluetoothAdapter')
            self.BluetoothDevice = autoclass('android.bluetooth.BluetoothDevice')
            self.BluetoothSocket = autoclass('android.bluetooth.BluetoothSocket')
            self.UUID = autoclass('java.util.UUID')
            self.BufferReader = autoclass('java.io.BufferedReader')
            self.InputStream = autoclass('java.io.InputStreamReader')
            self.ConnectionEstablished = False
    
    
        def __del__(self):
            print('class AndroidBluetooth destroyer')
    

    在你的项目中导入“AndroidBluetoothClass”,创建一个AndroidBluetooth = AndroidBluetoothClass()对象,使用类中的方法如下:

    • AndroidBluetooth.getAndroidBluetoothSocket('HC-05') 连接到 arduino HC-05 蓝牙
    • AndroidBluetooth.BluetoothSend(b'1'):参数必须是字节数组
    • SerialData=''/SerialData = AndroidBluetooth.BluetoothReceive()

    希望这对任何 Kivy 初学者有所帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-15
      • 2015-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多