Using a Pycom Development Board to Communicate via Bluetooth with my iPhone

I wanted to communicate between my iPhone and my LoPy4 using bluetooth, which I was able to do successfully, so I decided to document the process in a couple of posts. This is the first post and it documents the Pycom development board side of the project. The second post documents the iOS app development part. So – let’s get started!

The goal of this project is to be able to control the built-in LED on the Pycom board with my iPhone over bluetooth. The iPhone app will have 3 sliders which will allow us to control the red, green and blue colour settings of the LED. To allow this to happen we are going to setup the Pycom board with a single bluetooth service that has three characteristics, which are the red, green and blue colour settings, under it.

Open up Atom (or your favourite editor) and let’s get started!

Create a new project directory, add the project folder in Atom and create main.py in that folder. Open up the main.py for editing and we can begin!

Let’s start with importing the modules we are going to need:

from network import Bluetooth
import pycom
import binascii

The bluetooth module is pretty self-explanatory given the subject of the article. The pycom module will be used to manipulate the LED on the Pycom board itself. Finally the binascii module is used in doing some conversions for the data, coming in through bluetooth, to a format that we are going to need it in.

Now let’s add in some functions that we will populate fully later:

def conn_cb (bt_o):
    # The bluetooth connection callback handler

def red_cb_handler(chr, data):
    # The Red colour callback handler

def green_cb_handler(chr, data):
    # The Green colour callback handler

def blue_cb_handler(chr, data):
    # The Blue colour callback handler

def setled():
    # Used to set the LED colour

We then need to disable the default heartbeat behaviour of the built-in LED so we can instead use it for our own purposes.

pycom.heartbeat(False)

Next we add the code setting up bluetooth along with it’s service and the three characteristics we are going to use. (one for each colour – red, green and blue)

# Setup bluetooth
bluetooth = Bluetooth()
bluetooth.set_advertisement(name='CassarTech', service_uuid=b'1234567890123456') #-3837-363534333231')
bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb)
bluetooth.advertise(True)

# Setup the bluetooth service 
srv1 = bluetooth.service(uuid=b'1234567890123456', isprimary=True,nbr_chars=3) 

# Setup the 3 characteristics under the service
redchr = srv1.characteristic(uuid=b'ab34567890123456', value=0)
red_cb = redchr.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=red_cb_handler)

greenchr = srv1.characteristic(uuid=b'bb34567890123456', value=0)
green_cb = greenchr.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=green_cb_handler)

bluechr = srv1.characteristic(uuid=b'cb34567890123456', value=0)
blue_cb = bluechr.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=blue_cb_handler)

We begin by starting up bluetooth and advertising the Pycom device with the name CassarTech and the service UUID of our LED service. We then setup the callback handler function that gets invoked when a bluetooth client connects or disconnects from the device.

Next we define the bluetooth service with it’s UUID. The nbr_chars parameter defines how many characteristics will be associated with this particular service.

After that we setup the 3 characteristics with their UUID’s and initial values. We then setup the callback handler functions for each of these characteristics which gets called when the attached bluetooth client tries to read or write the value of each characteristic.

Now let’s go back and populate the various callback handler functions:

def conn_cb (bt_o):
    # The bluetooth connection callback handler
    events = bt_o.events()
    if  events & Bluetooth.CLIENT_CONNECTED:
        print("Client connected")
    elif events & Bluetooth.CLIENT_DISCONNECTED:
        print("Client disconnected")

def red_cb_handler(chr, data):
    # The Red colour callback handler
    # The data is a tuple containing the triggering event and the value if the event is a WRITE event.

    print("Handler1 running")
    events, value = data
    if  events & Bluetooth.CHAR_WRITE_EVENT:
        print("Red Write request with value = {}".format(value))
        setled()
    else:
        print('Read request on red')
        return(int(binascii.hexlify(chr.value()), 16))

def green_cb_handler(chr, data):
    # The Green colour callback handler
    events, value = data
    if  events & Bluetooth.CHAR_WRITE_EVENT:
        print("Green Write request with value = {}".format(value))
        setled()
    else: #Bluetooth.CHAR_READ_EVENT
        print('Read request on green')
        return(int(binascii.hexlify(chr.value()), 16))

def blue_cb_handler(chr, data):
    # The Blue colour callback handler
    events, value = data
    if  events & Bluetooth.CHAR_WRITE_EVENT:
        print("Blue Write request with value = {}".format(value))
        setled()
    else: #Bluetooth.CHAR_READ_EVENT
        print('Read request on blue')
        return(int(binascii.hexlify(chr.value()), 16))

The conn_cb function lets us know, by printing to the console, when a client connects or disconnects from the Pycom device.

The three other callback handler functions all do essentially the same thing but each for a different of the three colours. Let’s walk through what each function does.

The data variable being passed into the function is a tuple containing the triggering event and the value if the event is a WRITE event. We first determine if it’s a write event or a read event.
If it’s a write event it logs the value of the write to the console and then calls the setled() function which uses the new value of the colour to adjust the LED’s colour.
If it’s a read event then it notifies us of that fact on the console and returns the current value of that characteristic, after some conversion. The conversion turns it into an integer value which is what we’ll want in the iOS app. (It’s a value between 0 and 255 with 0 having that colour off and 255 having that colour at full brightness)

Now finally we have the setled() function:

def setled():
    # Used to set the LED colour
    red = int(binascii.hexlify(redchr.value()), 16)
    green = int(binascii.hexlify(greenchr.value()), 16)
    blue = int(binascii.hexlify(bluechr.value()), 16)

    led = (red * 16**4) + (green * 16**2) + blue
    print(led)
    pycom.rgbled(led)

The function first gets each of the characteristics values, converting them into an integer, and assigning them to the appropriate variable name.

The pycom.rgbled() function expects the colour in the form of a hex colour value (#RRGGBB) and the calculation for the led variable get the colours into their correct places. It multiplies the red value by 16^4, which moves it over by four places, multiplies green by 16^2 which moves it over by 2 places and leaves blue as it is.

So that’s everything we need on the Pycom device for our bluetooth LED colour changing setup. Feel free to upload it to your Pycom device and verify there are no errors.

The next article will go through the setup of the iOS app in Xcode. Please stay tuned!

You may also like...

Popular Posts

Leave a Reply