An Adafruit IO - connected, CircuitPython remote thermal camera.
Project Objective
I have an Adafruit IO (AIO)-connected corrosion monitoring system in my remote laboratory (the workshop bench in the garage) to keep an eye on the temperature and humidity inside and outside the lab. It uses CircuitPython to monitor the temperature and humidity, and it also uses AIO Plus to connect it to the weather outside. But here’s the thing: the temperature and humidity sensor can’t tell if a door or window is left open. It takes way too long to notice the change. I wish it could “see” if a small area inside the workshop has a different temperature than the rest of the space. It would also be great if it could detect human motion in the workshop or if the soldering iron was left on.
Requirements
- Periodically capture and upload a thermal image of a critical portion of the workshop.
- Monitor for temperature extremes and upload an image when exceeded.
- Detect human motion and upload an image.
- Provide a local color display with automatic brightness control.
- Continuously update the local display image at least twice a second to quickly detect motion and respond to thermal events.
- Upload the captured thermal image on a remotely accessible AIO dashboard page via the local WiFi network.
- Upload bitmap image payload to AIO in less than 10 seconds.
- Power from a USB 5-volt wall wart.
Future and Nice-to-Have
- Blank the screen when motion has not been detected for a preset amount of time (screen saver).
- SD Card storage of images and temperature statistics with historical view UI.
- Trigger AIO notification events related to motion or alarm settings.
- Upload minimum, average, maximum temperature values with image; display on dashboard.
- Interface to Apple HomeKit.
- Capture local audio.
- Live MEMENTO photo overlay.
To speed up prototyping and algorithm development, CircuitPython was the choice for the software side of things. Besides, the code needed for creating images with a thermal camera and for reliable communication with AIO already exists in other projects that I've recently developed.
Acknowledgments
Thanks to Dave Astels and Matt Land for working out the details for bitmap file header and data formatting example for the Adafruit_CircuitPython_BitmapSaver helper library. The code inspired the approach used for this project.
Brent Rubell's DIY IoT Doorbell Camera with MEMENTO learning guide made it easy to experiment with bitmap image uploads to an AIO feed. Very comprehensive and helpful. Thank you!
Coding the Thermal Camera in CircuitPython
The thermal camera component of the code was derived from the Improved AMG8833 PyGamer Thermal Camera project, drawing upon its sensor capture and linear interpolation techniques. For a comprehensive exploration of this approach, please refer to the thermal camera learning guide.
This project introduces a thermal image “screen capture” capability and establishes a connection to an AIO graphic image feed, enabling the transfer of the thermal image to the workshop’s AIO dashboard. Instead of transmitting a substantial bitmap of the screen image, only the interpolated 15x15 pixel image is sent to the AIO image feed as a compact .bmp stream, encoded as base64 text. The AIO image object is subsequently enlarged on the server side to accommodate the dimensions required for the dashboard.
In addition to standard CircuitPython libraries, a fonts folder, and the settings.toml file, the Workshop Thermal Camera (WTC) code comprises three primary modules and one helper module:
- code.py: This module serves as the primary process, listing adjustable operational parameters, attaching peripheral devices (excluding the display), implementing methods for working with internet resources, and executing the routine that captures the thermal image display grid and uploads the bitmap image to an AIO feed. It also detects motion and monitors whether the maximum temperature exceeds the alarm limit.
- wtc_display: This class object module abstracts the TFT FeatherWing to emulate a displayio display object. It establishes the image grid using displayio shapes, positions the statistical elements on the display, and provides a text alert reporting feature. Its properties include those of typical displays (width, height, brightness), along with additional attributes specific to the thermal camera.
- camera_amg88xx.py: This driver-like class object instantiates and abstracts the AMG8833 thermal sensor module. If selected, it offers auto-focusing and linear interpolation from 8x8 sensor elements to 15x15 pixels. Its properties include a method for acquiring sensor data.
- index_to_rgb_iron.py: This helper function returns an RGB color value based on the iron heat spectrum, which linearly correlates with a 0.0 to 1.0 index input value.
Project Code Repository
The project's CircuitPython code, helpers, fonts, and libraries can be found in the Workshop_Thermal_Camera/bundle folder of the Workshop Thermal Camera repository.
The settings.toml File
Remember, at a minimum, the settings.toml file needs to contain your WiFi router and AIO account credentials:
CIRCUITPY_WIFI_SSID = "MyRouterSSID" CIRCUITPY_WIFI_PASSWORD = "a-very-secure-password" # AIO Credentials AIO_USERNAME="username" AIO_KEY="a-very-long-40-character-key-string-1234"
System Components
The thermal camera components consist of:
- ESP32-S3 4Mb/2Mb Feather.
- 2.4" TFT FeatherWing (optionally wired for display brightness control and an ambient light sensor).
- AMG8833 Thermal Camera Breakout, connected to the ESP32 Feather with a 100mm STEMMA-QT cable.
- An optional ALS-PT19 Analog Light Sensor Breakout connected to the TFT FeatherWing's +3V, GND, and A3 pads. The light sensor is used to automatically control display brightness in proportion to the ambient light level.
If display brightness control is needed, the TFT FeatherWing will require a short jumper wire soldered to connect the TX pin and LITE pads to allow PWM control of the display backlight brightness. (See photo.)
For automatic display brightness control, connect the ALS-PT19 light sensor output to the A3 GPIO pin pad. Also connect the sensor's power and ground to the FeatherWing's 3V and GND pads. For the prototype, three Dupont Cable 20cm Soft Silicon wires were cut in half and with the wire end soldered to the sensor breakout and the Dupont pin end inserted into the outer row of the Feather socket as shown in the wiring photos.
This page (AIO-Connected Workshop Thermal Camera) was last updated on August 17, 2025.