code.py
  1  # SPDX-FileCopyrightText: 2018 John Edgar Park for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  # RGB Color Picker demo - wire up RGB LEDs and set their color
  6  # using Adafruit Bluefruit Connect App on your phone
  7  # runs on Feather M0 Bluefruit LE running the Feather M0 Adalogger build
  8  # of CircuitPython with Prop-Maker Wing and 3W RGB LED
  9  
 10  import time
 11  import random
 12  import board
 13  import busio
 14  import pwmio
 15  from digitalio import DigitalInOut, Direction
 16  from adafruit_bluefruitspi import BluefruitSPI
 17  import adafruit_lis3dh
 18  
 19  ADVERT_NAME = b'BlinkaNeoLamp'
 20  
 21  # RGB LED on D11, 12, 13, we're using a Prop Maker wing
 22  red_led = pwmio.PWMOut(board.D11, frequency=50000, duty_cycle=0)
 23  green_led = pwmio.PWMOut(board.D12, frequency=50000, duty_cycle=0)
 24  blue_led = pwmio.PWMOut(board.D13, frequency=50000, duty_cycle=0)
 25  # Prop maker wing has a power pin for the LED!
 26  power_pin = DigitalInOut(board.D10)
 27  power_pin.direction = Direction.OUTPUT
 28  power_pin.value = True
 29  
 30  spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
 31  cs = DigitalInOut(board.D8)
 32  irq = DigitalInOut(board.D7)
 33  rst = DigitalInOut(board.D4)
 34  bluefruit = BluefruitSPI(spi_bus, cs, irq, rst, debug=False)
 35  
 36  i2c = busio.I2C(board.SCL, board.SDA)
 37  lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c)
 38  
 39  def init_bluefruit():
 40      # Initialize the device and perform a factory reset
 41      print("Initializing the Bluefruit LE SPI Friend module")
 42      bluefruit.init()
 43      bluefruit.command_check_OK(b'AT+FACTORYRESET', delay=1)
 44      # Print the response to 'ATI' (info request) as a string
 45      print(str(bluefruit.command_check_OK(b'ATI'), 'utf-8'))
 46      # Change advertised name
 47      bluefruit.command_check_OK(b'AT+GAPDEVNAME='+ADVERT_NAME)
 48  
 49  def wait_for_connection():
 50      print("Waiting for a connection to Bluefruit LE Connect ...")
 51      # Wait for a connection ...
 52      dotcount = 0
 53      while not bluefruit.connected:
 54          print(".", end="")
 55          dotcount = (dotcount + 1) % 80
 56          if dotcount == 79:
 57              print("")
 58          time.sleep(0.5)
 59  
 60  # This code will check the connection but only query the module if it has been
 61  # at least 'n_sec' seconds. Otherwise it 'caches' the response, to keep from
 62  # hogging the Bluefruit connection with constant queries
 63  connection_timestamp = None
 64  is_connected = None
 65  def check_connection(n_sec):
 66      # pylint: disable=global-statement
 67      global connection_timestamp, is_connected
 68      if (not connection_timestamp) or (time.monotonic() - connection_timestamp > n_sec):
 69          connection_timestamp = time.monotonic()
 70          is_connected = bluefruit.connected
 71      return is_connected
 72  
 73  # Unlike most circuitpython code, this runs in two loops
 74  # one outer loop manages reconnecting bluetooth if we lose connection
 75  # then one inner loop for doing what we want when connected!
 76  while True:
 77      # Initialize the module
 78      init_bluefruit()
 79      try:        # Wireless connections can have corrupt data or other runtime failures
 80                  # This try block will reset the module if that happens
 81          while True:
 82              # Once connected, check for incoming BLE UART data
 83              if check_connection(3):  # Check our connection status every 3 seconds
 84                  # OK we're still connected, see if we have any data waiting
 85                  resp = bluefruit.read_packet()
 86                  if not resp:
 87                      continue  # nothin'
 88                  print("Read packet", resp)
 89                  # Look for a 'C'olor packet
 90                  if resp[0] != 'C':
 91                      continue
 92                  # Set the LEDs to the three bytes in the packet
 93                  red_led.duty_cycle = int(resp[1]/255 * 65535)
 94                  green_led.duty_cycle = int(resp[2]/255 * 65535)
 95                  blue_led.duty_cycle = int(resp[3]/255 * 65535)
 96              else:  # Not connected
 97                  # print(lis3dh.acceleration)
 98                  if lis3dh.acceleration.y < -5:
 99                      print("Tilted")
100                      red_led.duty_cycle = random.randint(0, 65535)
101                      green_led.duty_cycle = random.randint(0, 65535)
102                      blue_led.duty_cycle = random.randint(0, 65535)
103                      time.sleep(0.25)
104  
105      except RuntimeError as e:
106          print(e)  # Print what happened
107          continue  # retry!