Skip to content

Files

Latest commit

Taha Dhiaeddine AmdouniTaha Dhiaeddine Amdouni
Taha Dhiaeddine Amdouni
and
Taha Dhiaeddine Amdouni
Aug 27, 2017
4cd010f · Aug 27, 2017

History

History

BubblePy_Demo_Blinkt_BLE

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Aug 27, 2017
Aug 27, 2017
Aug 27, 2017
Aug 27, 2017
Aug 27, 2017

BubblePy Blinkt BLE + Web Bluetooth Demo

This is a BubblePy demo of controlling a Pimoroni Blinkt via BluetoothLE on an Arduino Primo.

The Python code demonstrates BubblePy's MicroPython versions of gpiozero and bluezero and can run on many different kinds of Bluetooth LE enabled devices (more details below).

Of note, the code will run pretty much as-is on an Arduino Primo, a micro:bit, a RaspberryPi and others.

The User Interface runs in a browser using the Web Bluetooth JavaScript API. Web Blutooth is used for discovering and connecting to Bluetooth LE devices from within a browser, e.g. a native app or plugin on Desktop or Mobile is not required.

User Interface

You can open the Web Bluetooth demo here.

Note: Please check your platform and browser are supported here.

Here's the browser UI:

LED Picker

Here's the Blinkt on the Arduino Primo:

Arduino Primo

There is also a colour wheel to pick your own colours: Colour Picker

Wiring Setup

To connect the Blinkt to the Primo please see the image below and note the following in the diagram:

  • Blue goes to Arduino 5v
  • White goes to Arduino GND

Blinkt Wiring

Firmware Image

A firmware image is available in Intel hex format here

This firmware has been tested successfully on the following OS'es, hardware and Chrome Browser combinations:

  • Android 6.0.1 (Nexus 7 Tablet): Chrome Version 52.0.2743.98
  • macOS Sierra (Mac Book Pro 2015): 53.0.2785.143 (64-bit) (note: requires WebBluetooth flag enabled first)
  • Chromebook (Toshiba Chromebook 2): ChromeOS 53.0.2785.103 (64-bit) (note: requires WebBluetooth flag enabled first)
  • Windows: not supported

Python Code

The Python code below runs via BubblePy on these devices:

  • Arduino Primo
  • BBC micro:bit
  • Raspberry Pi
  • Other Nordic Semiconductor nRF51 and nRF52 devices, e.g. RuuviTag, Red Bear Labs Nano

*The DAT and CLK pins may need changing for some hardware platforms.

The Blinkt portion of the code below is a gpiozero version of the original Blinkt library found here. A native MicroPython 'blinkt' module is also available, therefore the demonstrative code below would be much smaller in practice.

from gpiozero import OutputDevice
from bluezero import peripheral

#############
# Blinkt part

# (for demonstration purposes, there's a MicroPython 'blinkt' module available to import)

DAT = 23
CLK = 24
NUM_PIXELS = 8
BRIGHTNESS = 7

dat = OutputDevice(DAT)
clk = OutputDevice(CLK)

pixels = [[0,0,0,BRIGHTNESS]] * 8


def set_brightness(brightness):
    for x in range(NUM_PIXELS):
        pixels[x][3] = int(31 * brightness) & 0b11111

def clear():
    for x in range(NUM_PIXELS):
        pixels[x][0:3] = [0,0,0]

def write_byte(byte):
    for x in range(8):
        bit = (byte & (1 << (7-x))) > 0
        if bit:
            dat.on()
        else:
            dat.off()
        clk.on()
        clk.off()

def show():
    for x in range(4):
        write_byte(0)

    for pixel in pixels:
        r, g, b, brightness = pixel
        write_byte(0b11100000 | brightness)
        write_byte(b)
        write_byte(g)
        write_byte(r)

    write_byte(0xff)

def set_pixel(x, r, g, b, brightness=None):
    if brightness is None:
        brightness = pixels[x][3]
    else:
        brightness = int(31 * brightness) & 0b11111
    pixels[x] = [int(r) & 0xff,int(g) & 0xff,int(b) & 0xff,brightness]


def set_all(r,g,b):
    for x in range(8):
        set_pixel(x,r,g,b)

###################
# Bluetooth LE part

# These are Bluetooth LE unique identifiers that are also used by a commercial LED display.

# 128-Bit UUID's here, but 16 bit UUID's would work too, e.g. 0xFFF0 and 0xFFF3 in this case
SERVICE_UUID =  '0000fff0-0000-1000-8000-00805f9b34fb'
CHAR_UUID =    '0000fff3-0000-1000-8000-00805f9b34fb'


# Command constants, received when the WebBluetooth client writes to the BluetoothLE GATT characteristic 

CMD_CLEAR_PIXELS=0x0601
CMD_SET_PIXEL=0x0702

# Callback that is invoked when a Central device passes data to the 'write' characteristic (CHAR_UUID)
def ble_write_callback(bytes):
    if len(bytes)>2:
        cmd = (bytes[0]<<8) + (bytes[1] & 0xff)

        if cmd == CMD_SET_PIXEL:
            if len(bytes) >=7 :
                set_pixel(bytes[3]-1, bytes[4], bytes[5], bytes[6] )
        elif cmd == CMD_CLEAR_PIXELS:
            if len(bytes) >=5:
                set_all(bytes[2], bytes[3], bytes[4] )
    show()


service = peripheral.Service(SERVICE_UUID, True)
char = peripheral.Characteristic(CHAR_UUID, ['write'], 0)

char.add_write_event(ble_write_callback)
service.add_characteristic(char)

peripheral.add_service(service)
peripheral.start()