[{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/000/211/original/20230930_174520.jpg?1696352541","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n        \u003cp\u003eThe \u003ca href=\"https://www.adafruit.com/product/2935\" target=\"_blank\"\u003eAdafruit Controllable Four Outlet Power Relay Module\u003c/a\u003e is a very neat piece of hardware (if you live in a 120 volt AC country). It has a pair of contacts on the side that can take a wide range of voltages to switch electrical loads on and off. This is just what my wife wanted, a method to remotely control power outlets to some gear in her office.\u003c/p\u003e\n\u003cp\u003eBut how to switch it remotely. WiFi relies on connectivity that might get hacked over the internet in our view. Bluetooth seems more secure (maybe local hacking is possible, but our locality isn't a concern). I initially picked up an Adafruit Feather ESP32-S3. But CircuitPython Bluetooth doesn't work for UART/Serial profile. I want to, for proof of concept, use the \u003ca href=\"https://learn.adafruit.com/adafruit-circuit-playground-bluefruit/bluefruit-le-connect\" target=\"_blank\"\u003eAdafruit Bluefruit LE Connect application\u003c/a\u003e (available for iOS and Android) to send codes for on and off. That limits my choices to the Nordic nRF52840-based microcontroller boards.\u003c/p\u003e\n      \n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eParts\u003c/h2\u003e\n      \n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/2935","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/4333","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/4062","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/3448","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/1995","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eCircuit Playground Bluefruit Setup\u003c/h2\u003e\n\u003cp\u003eI had an early model with a firmware version less than 0.6.1. I needed to update that to load the latest versions of CircuitPython. I followed \u003ca href=\"https://learn.adafruit.com/adafruit-circuit-playground-bluefruit/update-bootloader\" target=\"_blank\"\u003ethis guide\u003c/a\u003e to get version 0.8.0.\u003c/p\u003e\n\u003cp\u003e\u003cspan\u003eI connected my CPB to my computer with a known good data+power \u003ca href=\"https://www.adafruit.com/product/592\" target=\"_blank\"\u003emicro B USB cable\u003c/a\u003e (Adafruit sells many different ones). Press the Reset button twice and the board shows up as a USB thumb drive. I copied a new firmware file in UF2 format to the \u003cstrong\u003eBOOT\u003c/strong\u003e drive and it rebooted (if it doesn't reboot, it's likely an incorrect firmware file). Checking the text file on the new drive (pressing Reset twice once more), the firmware version was updated.\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003eThen I loaded the latest version of CircuitPython via \u003ca href=\"https://learn.adafruit.com/adafruit-circuit-playground-bluefruit/circuitpython\" target=\"_blank\"\u003ethis guide\u003c/a\u003e. Great step-by-step guides. The board shows up now as a thumb drive called \u003cstrong\u003eCIRCUITPY\u003c/strong\u003e (no pressing Reset is needed).\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n        \u003ch2\u003eProject Wiring\u003c/h2\u003e\n\u003cp\u003eLuckily I had an \u003ca href=\"https://www.adafruit.com/product/4333\" target=\"_blank\"\u003eAdafruit Circuit Playground Bluefruit\u003c/a\u003e handy. The \u003ca href=\"https://www.adafruit.com/product/4062\" target=\"_blank\"\u003enRF52840 Feather\u003c/a\u003e would work the same and likely be the board used going forward.\u003c/p\u003e\n\u003cp\u003eRefer to the picture at the top of this guide.\u003c/p\u003e\n\u003cp\u003eI connected the Power Relay contacts to the Circuit Playground Bluefruit (CPB) via \u003ca href=\"https://www.adafruit.com/product/3448\" target=\"_blank\"\u003ebreadboard to alligator wires\u003c/a\u003e to the ground and TX connection (any digital or analog pin should work). I connected power via the Power Relay always on outlet to a \u003ca href=\"https://www.adafruit.com/product/1995\" target=\"_blank\"\u003e5 volt USB transformer\u003c/a\u003e to the CPB USB micro B connector.\u003c/p\u003e\n\u003cp\u003eBe sure the ground pin on the Bluefruit Express board is connected to the \"-\" pin on the Relay box and the \u003ccode\u003eboard.TX\u003c/code\u003e connection goes to the \"+\" Relay box connection.\u003c/p\u003e\n      ","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eCode\u003c/h2\u003e\n\u003cp\u003eI modified some example code on how to connect the nRF52840 board to the Connect app. In the \u003ca href=\"https://learn.adafruit.com/circuitpython-nrf52840/overview\" target=\"_blank\"\u003eGetting Started with CircuitPython and Bluetooth Low Energy guide\u003c/a\u003e, I modified the \u003ca href=\"https://learn.adafruit.com/circuitpython-nrf52840/button-press\" target=\"_blank\"\u003eButton Press\u003c/a\u003e example to also toggle the \u003ccode\u003ebutton.TX\u003c/code\u003e pin high when the up arrow is pressed, low when the down arrow is pressed.\u003c/p\u003e\n\u003cp\u003eI connected my CPB to my computer with a known good data+power micro B USB cable (Adafruit sells many different ones). I used the \u003ca href=\"https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor\" target=\"_blank\"\u003eMu editor\u003c/a\u003e to copy the example code and modify it to use digitalio for the pin toggling and neopixel to use two of the colorful RGB LEDs as status lights (one for Bluetooth connected, one for the switch state).\u003c/p\u003e\n\u003cp\u003eI needed to copy several libraries over to the \u003cstrong\u003e/lib\u003c/strong\u003e directory on the \u003cstrong\u003eCIRCUITPY\u003c/strong\u003e drive with File Explorer on my computer.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eneopixel\u003c/li\u003e\n\u003cli\u003eadafruit_ble\u003c/li\u003e\n\u003cli\u003eadafruit_bluefruit_connect\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe latest \u003ca href=\"https://circuitpython.org/libraries\" target=\"_blank\"\u003eLibrary Bundle\u003c/a\u003e is on the \u003ca href=\"https://circuitpython.org/\" target=\"_blank\"\u003ecircuitpython.org\u003c/a\u003e website.\u003c/p\u003e\n\u003cp\u003eNext I used Mu to save the code to a file named \u003cstrong\u003ecode.py\u003c/strong\u003e on the \u003cstrong\u003eCIRCUITPY\u003c/strong\u003e drive. \u003c/p\u003e\n\u003cp\u003eHere is the code:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"code","content":"# SPDX-FileCopyrightText: 2023 Anne Barela and Amy Lendian\n#\n# SPDX-License-Identifier: MIT\n\nimport board\nimport neopixel\nimport digitalio\nfrom adafruit_ble import BLERadio\nfrom adafruit_ble.advertising.standard import ProvideServicesAdvertisement\nfrom adafruit_ble.services.nordic import UARTService\n\nfrom adafruit_bluefruit_connect.packet import Packet\nfrom adafruit_bluefruit_connect.button_packet import ButtonPacket\n\nble = BLERadio()\nuart = UARTService()\nadvertisement = ProvideServicesAdvertisement(uart)\n\ncontact = digitalio.DigitalInOut(board.TX)\ncontact.direction = digitalio.Direction.OUTPUT\ncontact.value = False\n\npixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=0.2)\npixels[0] = (0, 0, 0)\npixels[9] = (0, 0, 0)\n\nwhile True:\n    ble.start_advertising(advertisement)\n    while not ble.connected:\n        pixels[9] = (0, 0, 0)\n        pass\n\n    # Now we're connected\n\n    while ble.connected:\n        pixels[9] = (0, 255, 0)\n        if uart.in_waiting:\n            packet = Packet.from_stream(uart)\n            if isinstance(packet, ButtonPacket):\n                if packet.pressed:\n                    if packet.button == ButtonPacket.BUTTON_1:\n                        # The 1 button was pressed.\n                        print(\"1 button pressed!\")\n                    elif packet.button == ButtonPacket.UP:\n                        # The UP button was pressed.\n                        print(\"UP button pressed!\")\n                        contact.value = True\n                        pixels[0] = (0, 0, 255)\n                    elif packet.button == ButtonPacket.DOWN:\n                        # The DOWN button was pressed\n                        print(\"DOWN button pressed!\")\n                        contact.value = False\n                        pixels [0] = (0, 0, 0)\n\n    # If we got here, we lost the connection. Go up to the top and start\n    # advertising again and waiting for a connection.","metadata":{"language":"python","linenums":false}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eUse\u003c/h2\u003e\n\u003cp\u003eI opened the Adafruit Bluefruit Connect LE app on my phone. I found the Circuit Playground Bluefruit advertising itself as \u003cstrong\u003eCIRCUITPY####\u003c/strong\u003e where #### is a random number. I connected to that. I then selected that I wanted to connect to the board using UART and Controller to get the control pad. Pressing the Up arrow turned the relay on and the down button turned it off. Success!\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eFinal Thoughts\u003c/h2\u003e\n\u003cp\u003eThis all may seem like a lot of work. But I know that to do the same thing coding in a lower level language would require digging into manuals that are hundreds of pages thick. And writing mobile apps is a whole world unto itself. Having a precoded app and some example code, I got this project working in part of an afternoon.\u003c/p\u003e\n\u003cp\u003eThe project demonstrates how Bluetooth commands can trigger a power relay safely, effectively and easily. A perfect start for my wife to further conceptualize her office project.\u003c/p\u003e\n\u003cp\u003eThe final project will likely have an nRF52840 board instead of a phone and consist of multiple power relay boxes. I cannot wait to see what she designs.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}}]