Quantcast
Viewing all articles
Browse latest Browse all 1234

Python • Kivy, Bleak and async troubles

I am trying to code a remote control with a single button to send the word "toggle" over BLE. I would like to stick to Kivy as the final destination would be porting it to Android with buildozer.

I have been staring for days now to have Kivy and Bleak work together as it should, and I am struggling to make all the async/coroutines and such stuff work right. I have never worked with async too much as you could suspect. The following code works (the first command is sent because I start with flag=True in __init__, (which I should't do in the final version of course), but disconnects every time from the receiving device (a Pico toggling a led for now) and then connects again when the button is clicked, which makes for a very long response time.

When I change things, the GUI just doesn't respond because the BLE loop never exits, and only the first command is sent and received by the Pico. So I just want to have the connection alive while the program is running, and send the data whenever the button is pressed.

Also, I am aware that there is still no error catching, like when the device is not found etc, but I would like to have the basics running first. I am pretty sure that the receiving end (Pico) works correctly. All the messages of connected/disconnected and message are correctly received, and it also works with the Serial Bluetooth app on my phone. Please let me know if you need the code also (I am trying to find the link again...).

Code:

import asyncioimport bleakfrom kivy.app import Appfrom time import sleepfrom kivy.uix.label import Labelfrom kivy.uix.boxlayout import BoxLayoutfrom kivy.uix.button import Buttonfrom kivy.logger import Loggerimport logginglogging.Logger.manager.root = LoggerUART_SERVICE_UUID = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"UART_RX_CHAR_UUID = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"UART_TX_CHAR_UUID = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"remote_device = '28:CD:C1:04:FA:7B'data = b'toggle\r\n'class ExampleApp(App):    def __init__(self):        super().__init__()        self.label = None        self.running = True        self.flag = True        self.device = bleak.BleakClient(remote_device)    def send_command(self, button):        print("Button pushed")        self.flag = True            def on_stop(self):        #self.running = False            pass    def build(self):        self.boxlayout = BoxLayout(orientation= 'vertical')        self.button = Button(text = 'Toggle', font_size="36dp")        self.button.bind(on_press = self.send_command)        self.boxlayout.add_widget(self.button)        self.label = Label(font_size="10sp", text=str(self.flag))        self.boxlayout.add_widget(self.label)        return self.boxlayout    async def example(self):            while True:                async with self.device as client:                    if self.flag:                                             print("Connected...", client)                                                                nus = client.services.get_service(UART_SERVICE_UUID)                        rx_char = nus.get_characteristic(UART_RX_CHAR_UUID)                        await client.write_gatt_char(rx_char, data, response=False)                        print("sent:", data)                        self.flag = False                    else:                        print("waiting for button press...")                        sleep(1)                     async def main(app):    await asyncio.gather(app.async_run("asyncio"), app.example())if __name__ == "__main__":    Logger.setLevel(logging.DEBUG)    # app running on one thread with two async coroutines    app = ExampleApp()    asyncio.run(main(app))
If I change "async def example(self) to the following, only the first message is sent, but with a click of the button only "Button pressed" is printed in the console, but no message is sent to the device (flag should be True again), and nothing is printed in the console, while I would expect either "message sent" or "device disconnected".

Code:

    async def example(self):            while True:                    client = self.device                    await client.connect()                    ...

I have also tried to make "def send_command" async, and used "await" and repeating the entire code to connect and send, but console says that the function was never awaited, so nothing is done.

A Bleak with Kivy example can be found here: https://github.com/hbldh/bleak/blob/dev ... vy/main.py, on which my code is based.

So I am pretty much stuck here Image may be NSFW.
Clik here to view.
:-(


Thanks for any help putting me on track.

Statistics: Posted by kheylen25 — Sat Jan 06, 2024 11:28 am



Viewing all articles
Browse latest Browse all 1234

Trending Articles