Overview
Bring your RS232 gear into modern times by adding BLE support. In this project, you'll use an ESP32-S3 Feather running CircuitPython to connect to the Adafruit Bluefruit Connect app over BLE. The control pad in the app will send commands over UART to the RS232 breakout, letting you wirelessly control your RS232 device.
The NeoPixel on the Feather lets you know the BLE connection status with the app. It will be red when disconnected and blue when connected.
RS232 Device
This projects demos interfacing with an HDMI switcher (linked below). However, you can change the code to work with other RS232 devices.
Page last edited September 10, 2024
Text editor powered by tinymce.
Circuit Diagram
The RS232 breakout connects to the Feather ESP32-S3 with four pins:
- Breakout VIN to Feather 3V (red wire)
- Breakout GND to Feather GND (black wire)
- Breakout RX to Feather RX (green wire)
- Breakout TX to Feather TX (blue wire)
Page last edited September 10, 2024
Text editor powered by tinymce.
3D Printing
The controller may be assembled with 3D printed parts, described below. The enclosure has three parts: a lid, a box and a NeoPixel diffuser.
The STL files can be downloaded directly here or from Printables.
The box has mounting holes for the Feather and RS232 breakout. It also has cutouts for the DE-9 connector and USB port.
Page last edited September 10, 2024
Text editor powered by tinymce.
Install CircuitPython
CircuitPython is a derivative of MicroPython designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the CIRCUITPY drive to iterate.
CircuitPython Quickstart
Follow this step-by-step to quickly get CircuitPython running on your board.
Below are links to CircuitPython for the Feather ESP32-S3 8MB No PSRAM and the Feather ESP32-S3 4MB Flash 2MB PSRAM. Be sure to choose the one that matches your board.
Click the link above to download the latest CircuitPython UF2 file.
Save it wherever is convenient for you.
Plug your board into your computer, using a known-good data-sync cable, directly, or via an adapter if needed.
Double-click the reset button (highlighted in red above), and you will see the RGB status LED(s) turn green (highlighted in green above). If you see red, try another port, or if you're using an adapter or hub, try without the hub, or different adapter or hub.
For this board, tap reset and wait for the LED to turn purple, and as soon as it turns purple, tap reset again. The second tap needs to happen while the LED is still purple.
If you do not see the LED turning purple, you will need to reinstall the UF2 bootloader. See the Factory Reset page in this guide for details.
If double-clicking doesn't work the first time, try again. Sometimes it can take a few tries to get the rhythm right!
A lot of people end up using charge-only USB cables and it is very frustrating! Make sure you have a USB cable you know is good for data sync.
You will see a new disk drive appear called FTHRS3BOOT.
Drag the adafruit_circuitpython_etc.uf2 file to FTHRS3BOOT.
Page last edited September 10, 2024
Text editor powered by tinymce.
Code the Controller
Once you've finished setting up your Feather ESP32-S3 with CircuitPython, you can access the code and necessary libraries by downloading the Project Bundle.
To do this, click on the Download Project Bundle button in the window below. It will download to your computer as a zipped folder.
# SPDX-FileCopyrightText: 2024 Liz Clark for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import board
import busio
from adafruit_bluefruit_connect.packet import Packet
from adafruit_bluefruit_connect.button_packet import ButtonPacket
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
import neopixel
# baud rate for your device
baud = 38400
# commands for your device
commands = ["AVI=1", "AVI=2", "AVI=3", "AVI=4"]
# Initialize UART for the RS232
uart = busio.UART(board.TX, board.RX, baudrate=baud)
# onboard neopixel
pixels = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.5, auto_write=True)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
# BLE setup
ble = BLERadio()
ble_uart = UARTService()
advertisement = ProvideServicesAdvertisement(ble_uart)
advertising = False
print("advertising..")
while True:
if not ble.connected and not advertising:
# not connected in the app yet
pixels.fill(RED)
ble.start_advertising(advertisement)
advertising = True
while ble.connected:
pixels.fill(BLUE)
# after connected via app
advertising = False
if ble_uart.in_waiting:
# waiting for input from app
packet = Packet.from_stream(ble_uart)
if isinstance(packet, ButtonPacket):
# if buttons in the app are pressed
if packet.pressed:
if packet.button == ButtonPacket.BUTTON_1:
uart.write((commands[0] + "\r\n").encode('ascii'))
if packet.button == ButtonPacket.BUTTON_2:
uart.write((commands[1] + "\r\n").encode('ascii'))
if packet.button == ButtonPacket.BUTTON_3:
uart.write((commands[2] + "\r\n").encode('ascii'))
if packet.button == ButtonPacket.BUTTON_4:
uart.write((commands[3] + "\r\n").encode('ascii'))
# empty buffer to collect the incoming data
response_buffer = bytearray()
# check for data
time.sleep(1)
while uart.in_waiting:
data = uart.read(uart.in_waiting)
if data:
response_buffer.extend(data)
# decode and print
if response_buffer:
print(response_buffer.decode('ascii'), end='')
print()
Upload the Code and Libraries to the Feather ESP32-S3
After downloading the Project Bundle, plug your Feather ESP32-S3 into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called CIRCUITPY. Unzip the folder and copy the following items to the Feather ESP32-S3's CIRCUITPY drive.
- lib folder
- code.py
Your Feather ESP32-S3 CIRCUITPY drive should look like this after copying the lib folder and the code.py file.
How the CircuitPython Code Works
At the top of the code, you can edit the baud rate and the commands that you want to send to your RS232 device. Then, UART is instantiated with the TX and RX pins.
# baud rate for your device baud = 38400 # commands for your device commands = ["AVI=1", "AVI=2", "AVI=3", "AVI=4"] # Initialize UART for the RS232 uart = busio.UART(board.TX, board.RX, baudrate=baud)
# onboard neopixel pixels = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.5, auto_write=True) RED = (255, 0, 0) BLUE = (0, 0, 255)
# BLE setup
ble = BLERadio()
ble_uart = UARTService()
advertisement = ProvideServicesAdvertisement(ble_uart)
advertising = False
print("advertising..")
The Loop
In the loop, if the BLE connection is disconnected, then the NeoPixel is red and BLE starts advertising for a connection.
if not ble.connected and not advertising:
# not connected in the app yet
pixels.fill(RED)
ble.start_advertising(advertisement)
advertising = True
Once a connection is established, the board starts listening for incoming BLE UART commands. These are sent from the buttons in the Bluefruit connect app. Buttons 1 through 4 switch between the four commands in the commands array. These commands are sent over UART to the RS232 breakout.
while ble.connected:
pixels.fill(BLUE)
# after connected via app
advertising = False
if ble_uart.in_waiting:
# waiting for input from app
packet = Packet.from_stream(ble_uart)
if isinstance(packet, ButtonPacket):
# if buttons in the app are pressed
if packet.pressed:
if packet.button == ButtonPacket.BUTTON_1:
uart.write((commands[0] + "\r\n").encode('ascii'))
if packet.button == ButtonPacket.BUTTON_2:
uart.write((commands[1] + "\r\n").encode('ascii'))
if packet.button == ButtonPacket.BUTTON_3:
uart.write((commands[2] + "\r\n").encode('ascii'))
if packet.button == ButtonPacket.BUTTON_4:
uart.write((commands[3] + "\r\n").encode('ascii'))
A buffer is created to hold any incoming data from the RS232 device. If data comes in over UART from the RS232 device, it is printed to the serial console.
# empty buffer to collect the incoming data
response_buffer = bytearray()
# check for data
time.sleep(1)
while uart.in_waiting:
data = uart.read(uart.in_waiting)
if data:
response_buffer.extend(data)
# decode and print
if response_buffer:
print(response_buffer.decode('ascii'), end='')
print()
Page last edited September 10, 2024
Text editor powered by tinymce.
Assembly
Solder four wires to the RS232 breakout:
- Vin (red wire)
- GND (black wire)
- RX (green wire)
- TX (blue wire)
Solder the other ends of the wires to the FeatherWing:
- Breakout Vin to Proto 3.3V (red wire)
- Breakout GND to Proto GND (black wire)
- Breakout RX to Proto RX (green wire)
- Breakout TX to Proto TX (blue wire)
Secure the RS232 breakout to its two mounting holes with M3 screws. Secure the FeatherWing to its four mounting holes with M2.5 screws.
Page last edited September 10, 2024
Text editor powered by tinymce.
Bluefruit App Setup
The Bluefruit LE Connect app provides iOS & Android devices with a variety of tools to communicate with Bluefruit LE devices. These tools cover basic communication and info reporting as well as more project specific uses such as Arduino Pin Control and a Color Picker.
The iOS app is a free download from Apple's App Store. It requires iOS 11.3 or later and works on iPhones, iPads, and iPod Touches.
The Android app is a free download from the Google Play Store. It requires Android 4.4 or later.
The app is compatible with these BLE devices from Adafruit, and possibly more:
- Bluefruit LE nRF8001 Breakout
- Bluefruit LE Friend
- Flora Wearable Bluefruit LE Module
- Adafruit Bluefruit LE SPI Friend
- Adafruit Bluefruit LE Micro
- Adafruit Feather 32u4 Bluefruit LE
- Adafruit Feather M0 Bluefruit LE
- Adafruit Feather nRF52 Bluefruit LE - nRF52832
- Adafruit Feather nRF52840 Express
- Adafruit CLUE
First off - install the app from one of the App stores listed above if you haven't already.
If Bluetooth is disabled on your device, enable it by going to Settings->Bluetooth on your iOS device, or the analogous setting on your Android device.
If you plan to use the app to send location/GPS data to Bluefruit LE, enable Location Services. Enable it on iOS using Settings->Privacy->Location Services.
Page last edited September 10, 2024
Text editor powered by tinymce.
Scan for Devices
On launch, the app will automatically begin to scan for nearby Bluetooth LE devices. Devices are presented in a table view in the order in which they were discovered.
The device list will display all BLE devices discovered by the app (not just Bluefruit hardware) - so you may see a quite a few "" or <Unknown> entries for devices that don't advertise their name, as seen above.
- To refresh the list and start a new scan, simply swipe down on the current list.
- Each device's signal strength is displayed in the left side of its row.
If you tap on the device entry (not on Connect), you'll see more detail about a particular device:
Tap the middle of a device's table row to reveal its relevant advertisement data.
- Any device listed with a "Connect" button at the right can be accessed in Info mode.
- Any device listed as "UART Capable" can be used with all modes - Info, UART, Pin I/O, & Controller.
The Multiple UART feature allows to monitor incoming data from, and send data to multiple devices simultaneously.
To use it:
- Activate the Multiple UART Mode switch
- Tap Connect next to each device you'd like to include
- Tap the Start button below the Multiple UART mode to begin.
Once connected, you can choose UART or Plotter module to view incoming data from all connected peripherals. In the UART module, you can send data to one or all connected devices at once.
Tap the Connect button on the UART capable list entry you wish to use and choose a connection mode from the menu that appears.
If you’re having trouble finding your Bluefruit device in the scanned peripherals list, ensure the board is powered and not paired with any other BLE devices. If the problem persists, it could be due to caching issues in the iOS or Android operating system. For a fix, try the following:
- Cycle Bluetooth - Turn your mobile device’s Bluetooth radio off and on again in the Settings app.
- Relaunch App - Quit the Bluetooth LE Connect app and restart it. (instructions for iOS & Android)
- Cycle Power - Restart your mobile device by powering it off and restarting.
Doing one or both of the above solves most peripheral scanning issues. If you're still having trouble, try searching the Adafruit Support forum for your issue.
Page last edited September 10, 2024
Text editor powered by tinymce.
Use
Power up the Feather via USB. You'll see the NeoPixel light up red. Open the Bluefruit Connect app and connect to the board. Once a connection is established, you'll see the NeoPixel light up blue.
Navigate to the Control Pad in the Bluefruit Connect app. Use the number buttons to send the UART commands to the RS232 device.
Customization
You can update the code to work with your RS232 device. At the top of the code, the serial baud rate and commands are defined.
# baud rate for your device baud = 38400 # commands for your device commands = ["AVI=1", "AVI=2", "AVI=3", "AVI=4"]
You can add the commands as strings and they'll be encoded in the loop.
Page last edited September 10, 2024
Text editor powered by tinymce.