|
| 1 | +# A more 'rugged' echo test for the Feather M0 Bluefruit |
| 2 | +# Sets the name, then echo's all RX'd data with a reversed packet |
| 3 | +# we wrap the loop in a try/except block and have multiple loops |
| 4 | +# and functions to keep our connection up and running no matter what |
| 5 | + |
| 6 | +import time |
| 7 | +import busio |
| 8 | +import board |
| 9 | +from digitalio import DigitalInOut |
| 10 | +from adafruit_bluefruitspi import BluefruitSPI |
| 11 | + |
| 12 | +ADVERT_NAME = b'BlinkaBLE' |
| 13 | + |
| 14 | +spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) |
| 15 | +cs = DigitalInOut(board.D8) |
| 16 | +irq = DigitalInOut(board.D7) |
| 17 | +rst = DigitalInOut(board.D4) |
| 18 | +bluefruit = BluefruitSPI(spi_bus, cs, irq, rst, debug=False) |
| 19 | + |
| 20 | +def init_bluefruit(): |
| 21 | + # Initialize the device and perform a factory reset |
| 22 | + print("Initializing the Bluefruit LE SPI Friend module") |
| 23 | + bluefruit.init() |
| 24 | + bluefruit.command_check_OK(b'AT+FACTORYRESET', delay=1) |
| 25 | + # Print the response to 'ATI' (info request) as a string |
| 26 | + print(str(bluefruit.command_check_OK(b'ATI'), 'utf-8')) |
| 27 | + # Change advertised name |
| 28 | + bluefruit.command_check_OK(b'AT+GAPDEVNAME='+ADVERT_NAME) |
| 29 | + |
| 30 | +def wait_for_connection(): |
| 31 | + print("Waiting for a connection to Bluefruit LE Connect ...") |
| 32 | + # Wait for a connection ... |
| 33 | + dotcount = 0 |
| 34 | + while not bluefruit.connected: |
| 35 | + print(".", end="") |
| 36 | + dotcount = (dotcount + 1) % 80 |
| 37 | + if dotcount == 79: |
| 38 | + print("") |
| 39 | + time.sleep(0.5) |
| 40 | + |
| 41 | +# This code will check the connection but only query the module if it has been |
| 42 | +# at least 'n_sec' seconds. Otherwise it 'caches' the response, to keep from |
| 43 | +# hogging the Bluefruit connection with constant queries |
| 44 | +connect_check_timestamp = None |
| 45 | +is_connected = None |
| 46 | +def check_connection(n_sec): |
| 47 | + if (not connect_check_timestamp) or (time.monotonic() - connection_timestamp > n_sec): |
| 48 | + connection_timestamp = time.monotonic() |
| 49 | + is_connected = bluefruit.connected |
| 50 | + return is_connected |
| 51 | + |
| 52 | +# Unlike most circuitpython code, this runs in two loops |
| 53 | +# one outer loop manages reconnecting bluetooth if we lose connection |
| 54 | +# then one inner loop for doing what we want when connected! |
| 55 | +while True: |
| 56 | + # Initialize the module |
| 57 | + try: # Wireless connections can have corrupt data or other runtime failures |
| 58 | + # This try block will reset the module if that happens |
| 59 | + init_bluefruit() |
| 60 | + wait_for_connection() |
| 61 | + print("\n *Connected!*") |
| 62 | + |
| 63 | + # Once connected, check for incoming BLE UART data |
| 64 | + while check_connection(3): # Check our connection status every 3 seconds |
| 65 | + # OK we're still connected, see if we have any data waiting |
| 66 | + resp = bluefruit.uart_rx() |
| 67 | + if not resp: |
| 68 | + continue # nothin' |
| 69 | + print("Read %d bytes: %s" % (len(resp), resp)) |
| 70 | + # Now write it! |
| 71 | + print("Writing reverse...") |
| 72 | + send = [] |
| 73 | + for i in range(len(resp), 0, -1): |
| 74 | + send.append(resp[i-1]) |
| 75 | + print(bytes(send)) |
| 76 | + bluefruit.uart_tx(bytes(send)) |
| 77 | + print("Connection lost.") |
| 78 | + |
| 79 | + except RuntimeError as e: |
| 80 | + print(e) # Print what happened |
| 81 | + continue # retry! |
0 commit comments