bluefruitspi_ruggedechotest.py
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 21 def init_bluefruit(): 22 # Initialize the device and perform a factory reset 23 print("Initializing the Bluefruit LE SPI Friend module") 24 bluefruit.init() 25 bluefruit.command_check_OK(b"AT+FACTORYRESET", delay=1) 26 # Print the response to 'ATI' (info request) as a string 27 print(str(bluefruit.command_check_OK(b"ATI"), "utf-8")) 28 # Change advertised name 29 bluefruit.command_check_OK(b"AT+GAPDEVNAME=" + ADVERT_NAME) 30 31 32 def wait_for_connection(): 33 print("Waiting for a connection to Bluefruit LE Connect ...") 34 # Wait for a connection ... 35 dotcount = 0 36 while not bluefruit.connected: 37 print(".", end="") 38 dotcount = (dotcount + 1) % 80 39 if dotcount == 79: 40 print("") 41 time.sleep(0.5) 42 43 44 # This code will check the connection but only query the module if it has been 45 # at least 'n_sec' seconds. Otherwise it 'caches' the response, to keep from 46 # hogging the Bluefruit connection with constant queries 47 connection_timestamp = None 48 is_connected = None 49 50 51 def check_connection(n_sec): 52 # pylint: disable=global-statement 53 global connection_timestamp, is_connected 54 if (not connection_timestamp) or (time.monotonic() - connection_timestamp > n_sec): 55 connection_timestamp = time.monotonic() 56 is_connected = bluefruit.connected 57 return is_connected 58 59 60 # Unlike most circuitpython code, this runs in two loops 61 # one outer loop manages reconnecting bluetooth if we lose connection 62 # then one inner loop for doing what we want when connected! 63 while True: 64 # Initialize the module 65 try: # Wireless connections can have corrupt data or other runtime failures 66 # This try block will reset the module if that happens 67 init_bluefruit() 68 wait_for_connection() 69 print("\n *Connected!*") 70 71 # Once connected, check for incoming BLE UART data 72 while check_connection(3): # Check our connection status every 3 seconds 73 # OK we're still connected, see if we have any data waiting 74 resp = bluefruit.uart_rx() 75 if not resp: 76 continue # nothin' 77 print("Read %d bytes: %s" % (len(resp), resp)) 78 # Now write it! 79 print("Writing reverse...") 80 send = [] 81 for i in range(len(resp), 0, -1): 82 send.append(resp[i - 1]) 83 print(bytes(send)) 84 bluefruit.uart_tx(bytes(send)) 85 print("Connection lost.") 86 87 except RuntimeError as e: 88 print(e) # Print what happened 89 continue # retry!