Forum Archive

Bluetooth UI button send commands

smiddleton

Hey guys,
I'm hoping you can help. I'm pretty stuck. I have created a UI that has a button on it. When I press the button I want it to send a character to my arduino device. The example below works perfect when I run it. The problem is, I can't figure out how to put this code, self.peripheral.write_characteristic_value(c, 'H', False), into the def button function I have so that it send the character when the button is pressed, instead of when it connects. Any help is very much appreciated. I have been stuck on this for about 2 days now. Thanks!

import cb

class MyCentralManagerDelegate (object):
    def __init__(self):
        self.peripheral = None

    def did_discover_peripheral(self, p):
        if p.name == 'HM-10-BLE' and not self.peripheral:
            print 'Discovered ' + p.name
            self.peripheral = p
            cb.connect_peripheral(self.peripheral)

    def did_connect_peripheral(self, p):
        print 'Connected Peripheral ' + p.name
        print 'Looking for Service FFE0'
        p.discover_services()

    def did_discover_services(self, p, error):
        for s in p.services:
            if s.uuid == 'FFE0':
                print 'Found Service ' + s.uuid
                print 'Looking for Characteristic FFE1'
                p.discover_characteristics(s)

    def did_discover_characteristics(self, s, error):
        for c in s.characteristics:
            if c.uuid == 'FFE1':
                print 'Found Characteristic ' + c.uuid
                print 'Writing H'
                self.peripheral.write_characteristic_value(c, 'H', False)



cb.set_central_delegate( MyCentralManagerDelegate() )
print 'Looking for HM-10-BLE module'
cb.scan_for_peripherals()

# Keep the connection alive until the 'Stop' button is pressed:
try:
    while True: pass
except KeyboardInterrupt:
    # Disconnect everything:
    cb.reset()
JonB

in the same way you store a refernce to the peripheral, store the characteristic, e.g. self.c=c. then you can call write_characteristic elsewhere .

You will want to also initialize and store a refernce to your delegate, so you can refer to it in your ui code. You could also make your delegate a subclass of ui.View, in which case everything you need is stored together, in self.

smiddleton

Thanks for your reply. I really appreciate your help. Would be able to write an example of what you have described? I'm still a little new to python. Thanks.

JonB

Slight modification to your code, but not tested.

import cb
import ui

class MyCentralManagerDelegateView (ui.Viee):
    def __init__(self):
        self.peripheral = None
        self.charactetistic= None
        self.b=ui.Button(title='button')
        self.add_subview(self.b)
        self.b.action=self.a
        self.frame=(0,0,320,570)
    def did_discover_peripheral(self, p):
        if p.name == 'HM-10-BLE' and not self.peripheral:
            print 'Discovered ' + p.name
            self.peripheral = p
            cb.connect_peripheral(self.peripheral)

    def did_connect_peripheral(self, p):
        print 'Connected Peripheral ' + p.name
        print 'Looking for Service FFE0'
        p.discover_services()

    def did_discover_services(self, p, error):
        for s in p.services:
            if s.uuid == 'FFE0':
                print 'Found Service ' + s.uuid
                print 'Looking for Characteristic FFE1'
                p.discover_characteristics(s)

    def did_discover_characteristics(self, s, error):
        for c in s.characteristics:
            if c.uuid == 'FFE1':
                print 'Found Characteristic ' + c.uuid
                self.characteristic=c
                print 'Writing H'

    def a(self,sender):
        c=self.characteristic
        self.peripheral.write_characteristic_value(c, 'H', False)

    def close(self):
        cb.reset()

v=MyCentralManagerDelegateView()
cb.set_central_delegate( v)
print 'Looking for HM-10-BLE module'
cb.scan_for_peripherals()
v.present('sheet')
smiddleton

Hi JonB,
Thanks for that. I have been trying to integrate it into my code, but not much luck. Here is what I have so far. Not sure why my button isn't sender he command yet. Also, my UI doesn't show up after it connects. Thanks for the help. I do appreciate forums like this, and the time guys like you put in to your answers.

import ui
import cb
import time
import struct
fwd = '1'#'<FW,-1>'

class BlunoBeetle (object):
    def __init__(self):
        self.peripheral = None
        self.charactetistic= None
        self.b=ui.Button(title='button')
        self.add_subview(self.b)
        self.b.action=self.a

    def did_discover_peripheral(self, p):
        if p.name and 'Bluno' in p.name and not self.peripheral:
            self.peripheral = p
            print('Connecting to Bluno...')
            cb.connect_peripheral(p)

    def did_connect_peripheral(self, p):
        print('Connected:', p.name)
        print('Discovering services...')
        p.discover_services()

    def did_fail_to_connect_peripheral(self, p, error):
        print('Failed to connect: %s' % (error,))

    def did_disconnect_peripheral(self, p, error):
        print('Disconnected, error: %s' % (error,))
        self.peripheral = None

    def did_discover_services(self, p, error):
        for s in p.services:
            if s.uuid == 'DFB0':
                print('Discovered Bluno service, discovering characteristitcs...')
                p.discover_characteristics(s)

    def did_discover_characteristics(self, s, error):
        print('Did discover characteristics...')
        for c in s.characteristics:
            if c.uuid == 'DFB1':
                print ('connected')
                self.peripheral.write_characteristic_value(c, fwd, False)


    #def did_update_value(self, c, error):
        #heart_rate = struct.unpack('<B', c.value[1])[0]
       # self.values.append(heart_rate)
       # print('Heart rate: %i' % heart_rate)

mngr = BlunoBeetle()
cb.set_central_delegate(mngr)
print('Scanning for peripherals...')
cb.scan_for_peripherals()

try:
    while True: pass
except KeyboardInterrupt:
    cb.reset()

def forward_button (sender):
    fwd = '<FW,-1>'
    entername1()

def entername1():
    label1 = v['label1']
    label1.text = 'going forward'   

v = ui.load_view('Ui Test')
v.present('sheet')




JonB

@smiddleton In my example, the button action was set to the a() method. In your case, you would set self.b.action= forward_button

Phuket2

@smiddleton, one change you could make, to make things more explicit is to pass an action param to your BlunoBeetle class like below. It's not the whole story, but I think its a step in the right direction.

class BlunoBeetle (object):
    def __init__(self, action):
       ...
       self.b.action = action

def my_action(sender):
    print(sender)

mngr = BlunoBeetle(my_action)

JonB

@Phuket2 Also, really those two methods should just be part of the blunobeetleview class, which avoids having to use globals.

Phuket2

@JonB , yeah i realise that. Like you, I was trying to filter how much to say while still being helpful. It's tricky :)

smiddleton

Thanks guys. Everything your saying is helpful! I appreciate you taking the time to try and teach me how to do it.

smiddleton

...I'm still stuck...

JonB

Did you try the code I posted?
Post a gist of where you are at, and we can work from there...

smiddleton

Hi Jon B,
Thanks for the reply. Yes, I still didn't get that working either. Maybe I need to change the name of the button in my.ui...

JonB

Post what you are trying... What errors are you getting.

smiddleton

It says "object hs no attribute," referencing the button. I created a separate UI and I am trying to work that in too. The error only happens after I press the word that says "button", after it appears on the screen.

JonB

Look, we can't help you unless you post the code you are using, along with a full traceback (print traceback).

JonB

Btw, in the last code you posted, you don't present your ui until after you press the X... So that may be party of your issue!

smiddleton

Hi, sorry about that. Here is a screen shot. Not a lot of time to post code with my kiddos running around so I grab a few minutes here and there when I can.

Print trace back line 38.
def a(self,sender): c=self.characteristic
Error says,
Traceback (most recent call last):
File "/private/var/mobile/Containers/Shared/AppGroup/DEE1AA35-7934-4C6D-85F7-C62F8C4760BD/Pythonista3/Documents/ui test.py", line 38, in a
c=self.characteristic
AttributeError: 'MyCentralManagerDelegateView' object has no attribute 'characteristic'
Traceback (most recent call last):
File "/private/var/mobile/Containers/Shared/AppGroup/DEE1AA35-7934-4C6D-85F7-C62F8C4760BD/Pythonista3/Documents/ui test.py", line 38, in a
c=self.characteristic
AttributeError: 'MyCentralManagerDelegateView' object has no attribute 'characteristic'

JonB

you need to make sure you have

self.characteristic=c

in did_discover_characteristic.

smiddleton

Hmm...I checked and it does say that. What isn't working?

JonB

Open the code. Press the share button, then choose share to gist. Then paste the link back here.

smiddleton

This is the entire code. Thanks for the help.
```
import cb
import ui

class MyCentralManagerDelegateView (ui.View):
def init(self):
self.peripheral = None
self.charactetistic= None
self.b=ui.Button(title='button')
self.add_subview(self.b)
self.b.action=self.a
self.frame=(0,0,320,570)
def did_discover_peripheral(self, p):
if p.name == 'Bluno' and not self.peripheral:
print ('Discovered ')+ p.name
self.peripheral = p
cb.connect_peripheral(self.peripheral)

def did_connect_peripheral(self, p):
    print ('Connected Peripheral ') + p.name
    print ('Looking for Service FFE0')
    p.discover_services()

def did_discover_services(self, p, error):
    for s in p.services:
        if s.uuid == 'DFB0':
            print ('Found Service ') + s.uuid
            print ('Looking for Characteristic FFE1')
            p.discover_characteristics(s)

def did_discover_characteristics(self, s, error):
    for c in s.characteristics:
        if c.uuid == 'DFB1':
            print ('Found Characteristic') + c.uuid
            self.characteristic=c
            print ('Writing H')

def a(self,sender):
    c=self.characteristic
    self.peripheral.write_characteristic_value(c, 'H', False)

def close(self):
    cb.reset()

v=MyCentralManagerDelegateView()
cb.set_central_delegate( v)
print ('Looking for HM-10-BLE module')
cb.scan_for_peripherals()
v.present('sheet')```

LoriNagle

Hello....Do you get the "080" troubleshoot print in UART when you press the catch? Just to check that catch interferes with function true to form.

In the event that this works, can you simply compress your venture into one record and post it here so I will investigate. Or on the other hand in the event that you would prefer not to post it in open gathering, at that point you can present a private help ticket and connect the code.