Due to high demand expect some shipping delays at this time, orders may not ship for 1-2 business days.
0

CircuitPython BLE Morse Code Chat Example
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

CircuitPython BLE Morse Code Chat Example

by adafruitguy on Fri Apr 03, 2020 1:40 am

I have two Adafruit CLUE's, and I am attempting to use the CircuitPython BLE Morse Code Chat https://learn.adafruit.com/circuitpython-ble-wireless-morse-code-chat example.

I have installed "Adafruit CircuitPython 5.1.0 on 2020-04-02; Adafruit CLUE nRF52840 Express with nRF52840" on each, as well as the libraries called in the code example, and all supporting libraries that also arise as missing when the CLUE tries to execute the code.py example from the Learning Guide.

I have configured the first CLUE with:

Code: Select all | TOGGLE FULL SIZE
#--| User Config |---------------------------------------------------
MY_NAME = "ME"
FRIENDS_NAME = "FRIEND"
#--| User Config |---------------------------------------------------


And, the second CLUE with:

Code: Select all | TOGGLE FULL SIZE
#--| User Config |---------------------------------------------------
MY_NAME = "FRIEND"
FRIENDS_NAME = "ME"
#--| User Config |---------------------------------------------------


I have also tried using different names ie: "ONE" and "TWO"

When running both, I only get to the "Scanning" step, and they never find or connect to each other...

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Advertising.
Waiting.
Scanning.

I have also tried with CircuitPython 5.0.

Complete code example from Clue 1:

Code: Select all | TOGGLE FULL SIZE
import time
import displayio
import terminalio
from adafruit_clue import clue
from adafruit_display_text import label
import adafruit_imageload
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService

#--| User Config |---------------------------------------------------
MY_NAME = "ME"
FRIENDS_NAME = "FRIEND"
#--| User Config |---------------------------------------------------

WAIT_FOR_DOUBLE = 0.05
DEBOUNCE = 0.25

# Define Morse Code dictionary
morse_code = {
    ".-"   : "A", "-..." : "B", "-.-." : "C", "-.."  : "D", "."    : "E",
    "..-." : "F", "--."  : "G", "...." : "H", ".."   : "I", ".---" : "J",
    "-.-"  : "K", ".-.." : "L", "--"   : "M", "-."   : "N", "---"  : "O",
    ".--." : "P", "--.-" : "Q", ".-."  : "R", "..."  : "S", "-"    : "T",
    "..-"  : "U", "...-" : "V", ".--"  : "W", "-..-" : "X", "-.--" : "Y",
    "--.." : "Z",
}

# BLE Radio Stuff
ble = BLERadio()
uart_service = UARTService()
advertisement = ProvideServicesAdvertisement(uart_service)
ble._adapter.name = MY_NAME #pylint: disable=protected-access

# Display Stuff
display = clue.display
disp_group = displayio.Group()
display.show(disp_group)

# Background BMP with the Morse Code cheat sheet
bmp, pal = adafruit_imageload.load("morse_bg.bmp",
                                   bitmap=displayio.Bitmap,
                                   palette=displayio.Palette)
disp_group.append(displayio.TileGrid(bmp, pixel_shader=pal))

# Incoming messages show up here
in_label = label.Label(terminalio.FONT, text='A'*18, scale=2,
                       color=0x000000)
in_label.anchor_point = (0.5, 0)
in_label.anchored_position = (65, 12)
disp_group.append(in_label)

# Outging messages show up here
out_label = label.Label(terminalio.FONT, text='B'*18, scale=2,
                        color=0x000000)
out_label.anchor_point = (0.5, 0)
out_label.anchored_position = (65, 190)
disp_group.append(out_label)

# Morse Code entry happens here
edit_label = label.Label(terminalio.FONT, text='....', scale=2,
                         color=0x000000)
edit_label.anchor_point = (0.5, 0)
edit_label.anchored_position = (105, 222)
disp_group.append(edit_label)

def scan_and_connect():
    '''
    Advertise self while scanning for friend. If friend is found, can
    connect by pressing A+B buttons. If friend connects first, then
    just stop.

    Return is a UART object that can be used for read/write.
    '''

    print("Advertising.")
    central = False
    ble.start_advertising(advertisement)

    print("Waiting.")
    friend = None
    while not ble.connected:

        if friend is None:
            print("Scanning.")
            in_label.text = out_label.text = "Scanning..."
            for adv in ble.start_scan():
                if ble.connected:
                    # Friend connected with us, we're done
                    ble.stop_scan()
                    break
                if adv.complete_name == FRIENDS_NAME:
                    # Found friend, can stop scanning
                    ble.stop_scan()
                    friend = adv
                    print("Found", friend.complete_name)
                    in_label.text = "Found {}".format(friend.complete_name)
                    out_label.text = "A+B to connect"
                    break
        else:
            if clue.button_a and clue.button_b:
                # Connect to friend
                print("Connecting to", friend.complete_name)
                ble.connect(friend)
                central = True

    # We're now connected, one way or the other
    print("Stopping advertising.")
    ble.stop_advertising()

    # Return a UART object to use
    if central:
        print("Central - using my UART service.")
        return uart_service
    else:
        print("Peripheral - connecting to their UART service.")
        for connection in ble.connections:
            if UARTService not in connection:
                continue
            return connection[UARTService]

#--------------------------
# The main application loop
#--------------------------
while True:

    # Establish initial connection
    uart = scan_and_connect()

    print("Connected.")

    code = ''
    in_label.text = out_label.text = ' '*18
    edit_label.text = ' '*4
    done = False

    # Run the chat while connected
    while ble.connected:

        # Check for incoming message
        incoming_bytes = uart.in_waiting
        if incoming_bytes:
            bytes_in = uart.read(incoming_bytes)
            print("Received: ", bytes_in)
            in_label.text = in_label.text[incoming_bytes:] + bytes_in.decode()

        # DOT (or done)
        if clue.button_a:
            start = time.monotonic()
            while time.monotonic() - start < WAIT_FOR_DOUBLE:
                if clue.button_b:
                    done = True
            if not done and len(code) < 4:
                print('.', end='')
                code += '.'
                edit_label.text = "{:4s}".format(code)
                time.sleep(DEBOUNCE)

        # DASH (or done)
        if clue.button_b:
            start = time.monotonic()
            while time.monotonic() - start < WAIT_FOR_DOUBLE:
                if clue.button_a:
                    done = True
            if not done and len(code) < 4:
                print('-', end='')
                code += '-'
                edit_label.text = "{:4s}".format(code)
                time.sleep(DEBOUNCE)

        # Turn Morse Code into letter and send
        if done:
            letter = morse_code.get(code, ' ')
            print(' >', letter)
            out_label.text = out_label.text[1:] + letter
            uart.write(str.encode(letter))
            code = ''
            edit_label.text = ' '*4
            done = False
            time.sleep(DEBOUNCE)

    print("Disconnected.")


Complete code example from Clue 2:

Code: Select all | TOGGLE FULL SIZE
import time
import displayio
import terminalio
from adafruit_clue import clue
from adafruit_display_text import label
import adafruit_imageload
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService

#--| User Config |---------------------------------------------------
MY_NAME = "FRIEND"
FRIENDS_NAME = "ME"
#--| User Config |---------------------------------------------------

WAIT_FOR_DOUBLE = 0.05
DEBOUNCE = 0.25

# Define Morse Code dictionary
morse_code = {
    ".-"   : "A", "-..." : "B", "-.-." : "C", "-.."  : "D", "."    : "E",
    "..-." : "F", "--."  : "G", "...." : "H", ".."   : "I", ".---" : "J",
    "-.-"  : "K", ".-.." : "L", "--"   : "M", "-."   : "N", "---"  : "O",
    ".--." : "P", "--.-" : "Q", ".-."  : "R", "..."  : "S", "-"    : "T",
    "..-"  : "U", "...-" : "V", ".--"  : "W", "-..-" : "X", "-.--" : "Y",
    "--.." : "Z",
}

# BLE Radio Stuff
ble = BLERadio()
uart_service = UARTService()
advertisement = ProvideServicesAdvertisement(uart_service)
ble._adapter.name = MY_NAME #pylint: disable=protected-access

# Display Stuff
display = clue.display
disp_group = displayio.Group()
display.show(disp_group)

# Background BMP with the Morse Code cheat sheet
bmp, pal = adafruit_imageload.load("morse_bg.bmp",
                                   bitmap=displayio.Bitmap,
                                   palette=displayio.Palette)
disp_group.append(displayio.TileGrid(bmp, pixel_shader=pal))

# Incoming messages show up here
in_label = label.Label(terminalio.FONT, text='A'*18, scale=2,
                       color=0x000000)
in_label.anchor_point = (0.5, 0)
in_label.anchored_position = (65, 12)
disp_group.append(in_label)

# Outging messages show up here
out_label = label.Label(terminalio.FONT, text='B'*18, scale=2,
                        color=0x000000)
out_label.anchor_point = (0.5, 0)
out_label.anchored_position = (65, 190)
disp_group.append(out_label)

# Morse Code entry happens here
edit_label = label.Label(terminalio.FONT, text='....', scale=2,
                         color=0x000000)
edit_label.anchor_point = (0.5, 0)
edit_label.anchored_position = (105, 222)
disp_group.append(edit_label)

def scan_and_connect():
    '''
    Advertise self while scanning for friend. If friend is found, can
    connect by pressing A+B buttons. If friend connects first, then
    just stop.

    Return is a UART object that can be used for read/write.
    '''

    print("Advertising.")
    central = False
    ble.start_advertising(advertisement)

    print("Waiting.")
    friend = None
    while not ble.connected:

        if friend is None:
            print("Scanning.")
            in_label.text = out_label.text = "Scanning..."
            for adv in ble.start_scan():
                if ble.connected:
                    # Friend connected with us, we're done
                    ble.stop_scan()
                    break
                if adv.complete_name == FRIENDS_NAME:
                    # Found friend, can stop scanning
                    ble.stop_scan()
                    friend = adv
                    print("Found", friend.complete_name)
                    in_label.text = "Found {}".format(friend.complete_name)
                    out_label.text = "A+B to connect"
                    break
        else:
            if clue.button_a and clue.button_b:
                # Connect to friend
                print("Connecting to", friend.complete_name)
                ble.connect(friend)
                central = True

    # We're now connected, one way or the other
    print("Stopping advertising.")
    ble.stop_advertising()

    # Return a UART object to use
    if central:
        print("Central - using my UART service.")
        return uart_service
    else:
        print("Peripheral - connecting to their UART service.")
        for connection in ble.connections:
            if UARTService not in connection:
                continue
            return connection[UARTService]

#--------------------------
# The main application loop
#--------------------------
while True:

    # Establish initial connection
    uart = scan_and_connect()

    print("Connected.")

    code = ''
    in_label.text = out_label.text = ' '*18
    edit_label.text = ' '*4
    done = False

    # Run the chat while connected
    while ble.connected:

        # Check for incoming message
        incoming_bytes = uart.in_waiting
        if incoming_bytes:
            bytes_in = uart.read(incoming_bytes)
            print("Received: ", bytes_in)
            in_label.text = in_label.text[incoming_bytes:] + bytes_in.decode()

        # DOT (or done)
        if clue.button_a:
            start = time.monotonic()
            while time.monotonic() - start < WAIT_FOR_DOUBLE:
                if clue.button_b:
                    done = True
            if not done and len(code) < 4:
                print('.', end='')
                code += '.'
                edit_label.text = "{:4s}".format(code)
                time.sleep(DEBOUNCE)

        # DASH (or done)
        if clue.button_b:
            start = time.monotonic()
            while time.monotonic() - start < WAIT_FOR_DOUBLE:
                if clue.button_a:
                    done = True
            if not done and len(code) < 4:
                print('-', end='')
                code += '-'
                edit_label.text = "{:4s}".format(code)
                time.sleep(DEBOUNCE)

        # Turn Morse Code into letter and send
        if done:
            letter = morse_code.get(code, ' ')
            print(' >', letter)
            out_label.text = out_label.text[1:] + letter
            uart.write(str.encode(letter))
            code = ''
            edit_label.text = ' '*4
            done = False
            time.sleep(DEBOUNCE)

    print("Disconnected.")


Suggestions on what I might be missing or doing wrong?
Attachments
GotNoClue.png
Here is a photo of my two CLUEs
GotNoClue.png (583.94 KiB) Viewed 149 times

adafruitguy
 
Posts: 143
Joined: Sat Jun 07, 2014 7:52 am

Re: CircuitPython BLE Morse Code Chat Example

by adafruit_support_carter on Fri Apr 03, 2020 1:45 pm

Hey, sorry about this. We've recreated the issue. It is related to this:
https://github.com/adafruit/Adafruit_Ci ... /issues/75

We'll fix that and get back to you once we have an update.

adafruit_support_carter
 
Posts: 21865
Joined: Tue Nov 29, 2016 2:45 pm

Re: CircuitPython BLE Morse Code Chat Example

by adafruit_support_carter on Fri Apr 03, 2020 3:32 pm

OK, should be fixed if you update to the latest library release:
https://github.com/adafruit/Adafruit_Ci ... /tag/6.1.1
You can either grab it from that release page or wait until tomorrow and it will be in the bundle.

adafruit_support_carter
 
Posts: 21865
Joined: Tue Nov 29, 2016 2:45 pm

Re: CircuitPython BLE Morse Code Chat Example

by adafruitguy on Fri Apr 03, 2020 6:00 pm

The fix worked flawlessly, thank you!
Attachments
AdafruitRocks.png
AdafruitRocks.png (589.62 KiB) Viewed 138 times

adafruitguy
 
Posts: 143
Joined: Sat Jun 07, 2014 7:52 am

Re: CircuitPython BLE Morse Code Chat Example

by adafruit_support_carter on Fri Apr 03, 2020 6:23 pm

Awesome! Glad that fixed it. Thanks for letting us know. Have fun!

adafruit_support_carter
 
Posts: 21865
Joined: Tue Nov 29, 2016 2:45 pm

Please be positive and constructive with your questions and comments.