Close
0%
0%

More accurate thermal imaging cameras

A pair of calibrated thermal imaging cameras with ambient correction based around the Tiny1C thermal imaging sensor.

Similar projects worth following
This project describes my LWIR thermal imaging camera designs based on the IRayTek Tiny1C Bolometer. With these designs, I want to explore the ability to calibrate the cameras and to compensate for environmental conditions such as ambient temperature, humidity and distance to the object being measured for increased radiometric temperature accuracy.

Like my earlier tCam and tCamMini designs, based around the Flir Lepton, there are two cameras, [perhaps] unimaginatively named, iCam and iCamMini. iCam is a handheld camera with a local 3.5" touchscreen and iCamMini is designed for remote operation and sports either a NTSC/PAL CVBS analog video output or Wi-Fi with a web interface. Again I am using the versatile Espressif ESP32 as the brains. There is one codebase that generates three binaries used by both cameras.

Camera features

  • 256 x 192 pixel resolution at up to around 22 FPS
  • Optional distance and temperature/humidity sensors for ambient correction
  • Micro-SD Card DCIM storage for JPG image files
  • Rechargeable 3.7V Li-Po battery and/or external 5V DC power
  • Battery-backed RTC for JPG image timestamp
  • [iCam] 3.5" 480x320 pixel touchscreen with GUI interface
  • [iCamMini] Wi-Fi mode (AP or STA) with web-browser based GUI interface
  • [iCamMini] Video mode with either NTSC or PAL analog output
  • Capable of 1-point or 2-point calibration against a known blackbody radiator

GUI Interface

  • LVGL based (both iCam touchscreen and iCamMini Web Browser)
  • Ten color palettes
  • Selectable Min/Max Temperature Markers
  • Selectable Spot Marker
  • Selectable Region Marker
  • Camera Settings
  • Micro-SD Card File Browser and image display

Video Interface (iCamMini)

  • Selectable NTSC or PAL non-interlaced timing
  • 288 x 192 pixel monochrome display with two palettes
  • Selectable Min/Max Temperature Markers
  • Selectable Spot Marker
  • Camera settings using local buttons

  • GUI

    Dan Julio11/20/2024 at 22:45 2 comments

    (pretty pictures below if this is TL;DR)

    I'm using LVGL for the iCam and iCamMini Web GUIs. The video output uses a much simpler set of 8-bit monochrome drawing routines since LVGL doesn't really support 8-bit monochrome.   I chose LVGL for the web interface because I don't really know traditional web programming but am experienced with LVGL and can use emscripten to compile a C program into WebAssembly that would run in any modern browser.  The LVGL people already use emscripten to publish live demos in their HTML documentation so it was easy to figure out how to build.  The result looks slightly different than traditional web page layouts but it works.

    The part I'm proud of is creating a view/model-controller paradigm that let me write essentially one set of GUI code works both on the embedded (SPI-accessed) 3.5" gCore LCD and also in a browser.  When running in the browser it can resize and react to events like rotation of a mobile device to change its layout dynamically.  The connection between the GUI view and model-controller is done through a set/get/response API that maps to direct function calls when the GUI is running on the same platform as the model-controller and serialization/de-serialization through a websocket when the GUI is running in the browser.  For example the GUI might issue a GET EMISSIVITY command to update the emissivity control panel.  This ends up executing a get_emissivity_handler() subroutine.  The subroutine is executed directly by the API on the combined platform and as the result of parsing an incoming websocket packet on the remote platform. 

    I do take a few performance short-cuts.  For example the actual thermal image is a 256 x 192 x 8-bit scaled raw image chunk of data.  All 49,152 bytes (+ some additional data) have to get sent over the websocket by iCamMini.  But on the iCam platform I only pass a 4-byte pointer to a shared data structure instead of copying the data.

    I say the GUI can automatically adjust to the screen but there are limits.  In all cases during my layout I had to make sure it would fit on the relatively constrained iCam 480x320 pixel LCD.  For performance reasons I picked fixed 1.5x or 2.0x magnification of the image (so I could use some very optimized bi-linear interpolation code)  and this sets how big the display can be on a desktop browser.  In other cases I adjust limits so the various screens look good on a mobile phone.  I have yet to do testing on a tablet so it's possible further optimizations might be necessary.

    When running on an iCamMini, the code starts the Espressif web server which serves a single large html page to the first connected client.  This page contains a very small amount of HTML and CSS and the big WebAssembly binary (> 400kB)  that runs when the page loads.  It initiates a websocket connection with the server and from then on all commands and data pass through that.  The web LVGL drivers render to a javascript canvas using SDL.

    The WebAssembly code is its own program and can run even when the iCam is disconnected from it for some reason.  For this reason I am attempting to catch various disconnect scenarios or have iCamMini inform the GUI when it is powering down so the GUI can display a default page indicating it's disconnected (and has a reconnect button).

    All C code is contained in a single project structured for the Espressif IDF build environment.  The majority of the code is shared between the two cameras with only some custom device-specific code.  I have a script which sets specific sdkconfig files for each camera type and the linker is configured to only include necessary code.  There is another directory that is ignored by the IDF tools but is where I build the emscripten code.   It contains its own main.c file which is the WebAssembly LVGL GUI program.  There...

    Read more »

  • iCamMini ​Prototype

    Dan Julio11/20/2024 at 03:05 1 comment

    My vision for iCamMini is for a remotely accessed camera.  For example to be flown on a drone or remotely operated vehicle or to be mounted (suitably protected) outdoors or on a lab bench monitoring a circuit while the user sits at a computer.  The video interface can be connected to a long-range transmitter or the camera can be accessed via Wi-Fi for shorter range applications.

    The prototype consists of a baseboard I designed called iCamCtrl and a Tiny1C breakout board.   I didn't originally design-in a RTC chip so a PCF85063-based breakout from Seeed Studio was added and I directly soldered the AHT20 and VL53L4CX breakouts to the Tiny1C board.

    It utilizes a ESP32 Pico module with 8 MB Flash and 2 MB PSRAM.

    Block Diagram

    I'm currently designing a Rev 2 that fixes some issues and integrates the RTC and backup battery.

    iCamMini has several hardware interfaces.

    • USB-C for power/charging and programming via a CH340K USB UART.
    • Video Output
    • CMOS Serial port with flow-control.  Currently this is unused.

    It can be powered from a variety of sources

    • USB-C
    • 3.7V Li-Po battery
    • 5V through the video output port
    • 5V through the serial port

    All inputs are reverse diode protected and multiple can be powered simultaneously without reverse flow.  The idea is to make the camera easily powered by other devices, for example a video transmitter might output 5V for the analog camera.

    A jumper, sampled at boot, selects between Wi-Fi or Video mode.

    It has two LEDs and two multi-function push-buttons for local control.  The push buttons are used to control power, take a picture (stored as a JPG file in the local Micro-SD card), reset the Wi-Fi to default settings and control setting some camera parameters when the video output is active.  One LED indicates charge mode (directly controlled by the TP4056 charger controller IC) and the other, red/green LED indicates various status or fault conditions under control of the ESP32.

    Soft Power Control

    Soft power control allows firmware to shut down the camera (for example for a critically low battery condition).  It is implemented using a pair of P-channel MOSFETs that act as a high-side switch between incoming power and the internal 3.3V regulators.  One is switched on whenever one of the push buttons is pressed.  The other is switched on under control of the ESP32.  The user presses the power button and the ESP32 starts to boot.  The first thing firmware does after booting is to switch the other MOSFET on and then light the LED to indicate to the user power is on.  Then the user can let go of the power button.  This takes a fraction of a second.  The ESP32 can also sense the state of the push button so it can detect a long-press (or other software command) to switch off power and turn off the second MOSFET (after waiting for the switch to be released).   A side-effect of this method is that the power button has to be held closed while loading firmware.

    The other button is a purely software read peripheral.


    Wi-Fi Mode GUI

    In Wi-Fi mode the camera runs a simple web server that can be connected to by a single desktop or mobile browser.  The same LVGL GUI as iCam, but slightly resized based on the browser, is displayed through the magic of websockets and emscripten.   It supports rotation for mobile devices.


    Video Interface

    The video interface is designed to drive a 75-ohm video device like a monitor or transmitter.  In actuality the Rev 1 prototype can't quite achieve the 1v p-p required voltage range because I was overloading the DAC output so the Rev 2 includes a video amplifier.

    The video output is generated using the ESP32 8-bit DAC and DMA engines with heavily modified code that started out as aqauticus' ESP32 composite video library.  The original code could only display 51 brightness levels.  My code can display 170 brightness levels.  The reason all 256 DAC output codes can't be used for video levels...

    Read more »

  • iCam Prototype

    Dan Julio11/19/2024 at 22:12 0 comments

    The iCam prototype consists of one of my gCore development boards in a hacked prototype 3D printed enclosure wired to a sensor assembly consisting of the TIny1C breakout, an Adafruit VL53LC4X time-of-flight distance sensor (0-6m) and a Sparkfun AHT20 temperature/humidity sensor.

    This camera is designed to be handheld for portable use with a portrait display

    Hardware is pretty simple.

    Essentially the gCore supplies 3.3V to the sensors which is switched on when it is switched on, a SPI interface for the Tiny1C VOSPI and a "sensor" I2C bus for all three devices.  Another I2C bus exists on gCore for access to the touchscreen controller and RTC/PMIC controller.

    It turns out the VL53L4CX has a strange functionality in that once initialized, further initialization sequences can corrupt the internal calibration.  To manage this I connect the SHUTDOWN pin on the VL53L4CX breakout (which essentially functions as a hardware reset) to the Tiny1C breakout reset and the firmware resets both devices before any initialization.

    My hardware prototype has two push buttons connected to inputs on gCore.  They were used with some test software I wrote using the Arduino ESP32 environment because I didn't have the touchscreen input running but are unused in the current Espressif IDF camera firmware.

    The following wiring diagram shows specifically how it is connected (this time using an Adafruit AHT20 breakout which might be slightly more available).

    Currently the firmware treats the VL53L4CX and AHT20 as optional peripherals.  It can use them to feed a compensation algorithm if they're present but functions without them as well.

    In the long haul I plan to design a different closure to capture all the hardware.  It's possible the screen orientation might change to landscape although I prefer the way the portrait type of camera is held as opposed to the traditional SLR style.  The advantage of the landscape orientation is that I could design a very simple PCB that would connect gCore to the sensor breakout boards (or even include the breakout board components directly).

  • Introducing the Tiny1C and breakout

    Dan Julio11/19/2024 at 21:16 0 comments

    Tiny1C

    The Tiny1C thermal imaging module (bolometer) by Infiray (or IRayTek - its been hard for me to understand the web of companies) is a small, low-cost, device like the Flir Lepton but with slightly higher resolution and faster frame rate.

    From its datasheet

    • 256x192 or 160x120 pixel resolution (I'm using 256x192 pixel models)
    • 2.0 F1.1, 3.2mm F1.1 or 4.3mm F1.2 lens (I've been using the 3.2 F1.1 lens)
    • 12μm Wafer-Level Packaged (WLP) uncooled Vanadium Oxide (VOx) Uncooled Infrared Focal Plane Detector
    • 8~14μm LWIR range
    • <40mK @25°C Noise Equivalent Temperature Difference (NETD)
    • 8-bit parallel DVP or SPI video interface (I'm using the SPI interface)
    • I2C Command and Control interface
    • 16-bit YUV422, 14-bit radiometric output or 10- or 14-bit raw data mode (I am using raw data mode)
    • Built-in image processing pipeline (I'm using this to sharpen the image and perform AGC calculations)
    • -15°C ~ 150°C (High Gain) or 50°C ~ 550°C (Low Gain) range
    • +/- 2°C or 2% typical measurement accuracy
    • Built in shutter for flat field correction (FFC)
    • Typical 240 mW power consumption (600 mW during FFC)


    Breakout Board (rev 2)

    I designed a 1.25 x 1" (32x25.4mm) breakout board loosely modeled on the Lepton breakout board to expose the power, SPI and I2C interfaces.  It also makes available the module's serial interface (which outputs some log info but otherwise seems un-useful) and some GPIO pins which seem currently unused.

    The Tiny1C requires a 3.3V logic power supply and a very low-noise 5V low-current analog supply.  The breakout board uses a capacitive boost converter followed by a very low noise linear regulator to generate the 5V from the 3.3V supply.  The breakout board also includes a power-on reset pulse generator which is also useful for the distance sensor (as I found out part-way through coding).

    The Tiny1C connects using a very small press-fit connector and I designed a set of 3D printed shims to properly space the module from the board.  I also use my favorite 3M double-sticky tape when I'm not screwing the breakout board into an enclosure or holder.

    Some extras available (as of Nov 19 2024)

    I have a few extra assembled boards that I can make available for pretty cheap (no Tiny1C modules).  Contact me if you're interested.  I'll delete this section once they're gone.

    Breakout (rev 1)

    The first version was a monster compared! 

View all 4 project logs

Enjoy this project?

Share

Discussions

robomaniac wrote 11/27/2024 at 15:48 point

nice project t Dan, saw it in hackster.io newsletter. Next time you could get SparkFun “ Flexible Qwiic Cable - 50mm “(PRT-17260) cut in two and solder wire to thermal camera in the middle and the connector attach to both dev board on each side in the appropriate qwicc connectors 😜

  Are you sure? yes | no

Dan Julio wrote 11/28/2024 at 16:26 point

Thanks!  You're right (I have a bunch of Qwiic cables) but I would also have to add a wire from the RESET_N on the Tiny1C breakout to the XSHUT input on the VL53LC4X board.  That part has a strange behavior in that if you run the initialization command sequence multiple times then its accuracy is degraded (even documented in the user manual).  So my firmware hard resets both the Tiny1C and the VL53LC4X at boot before initialization.

I'm actually experimenting with hanging the VL53LC4X off the Rev 3 Tiny1C breakout board and using a QWIIC cable to the AHT20 sensor.  Using the cable here is nice because that sensor actually wants to be away from the camera body and any heat it generates so it can really sense ambient temp.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates