Adafruit_Learning_System_Gu.../CLUE_BLE_Morse_Code/code.py
Carter Nelson 270354bfba
Merge pull request #2738 from mikeysklar/main
CLUE BLE Morse Code : scan_and_connect() changes
2024-03-04 11:49:55 -08:00

204 lines
5.5 KiB
Python
Executable file

# SPDX-FileCopyrightText: 2020 Carter Nelson for Adafruit Industries
#
# SPDX-License-Identifier: MIT
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 |---------------------------------------------------
# Set to either A or B. The other CLUE should be set to opposite mode.
BLE_MODE = "A"
# --| User Config |---------------------------------------------------
BLE_MODE = BLE_MODE.upper().strip()
if BLE_MODE not in ("A", "B"):
raise ValueError("BLE_MODE must be set to either A or B.")
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
if BLE_MODE == "A":
MY_NAME = "CENTRAL"
FRIENDS_NAME = "PERIPHERAL"
else:
MY_NAME = "PERIPHERAL"
FRIENDS_NAME = "CENTRAL"
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.root_group = 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 = (1.0, 0)
in_label.anchored_position = (235, 4)
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 = (1.0, 0)
out_label.anchored_position = (235, 180)
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 = (115, 212)
disp_group.append(edit_label)
def scan_and_connect():
"""
Handles initial connection between the two CLUES.
The CLUE set to BLE_MODE="A" will act as Central.
The CLUE set to BLE_MODE="B" will act as Peripheral.
Return is a UART object that can be used for read/write.
"""
print("Connecting...")
in_label.text = out_label.text = "Connecting..."
if MY_NAME == "CENTRAL":
keep_scanning = True
print("Scanning...")
while keep_scanning:
for adv in ble.start_scan():
if adv.complete_name == FRIENDS_NAME:
ble.stop_scan()
ble.connect(adv)
keep_scanning = False
print("Connected. Done scanning.")
return uart_service
else:
print("Advertising...")
ble.start_advertising(advertisement)
while not ble.connected:
if ble.connected:
break
print("Connected. Stop advertising.")
ble.stop_advertising()
print("Connecting to Central UART service.")
for connection in ble.connections:
if UARTService not in connection:
continue
return connection[UARTService]
return None
# --------------------------
# 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.")