Primary Process

Primary Process Setup and Loop

 

Setup

We're finally in the main portion of the code that controls the Thermal Camera's primary process. We still need to define a couple of things to get ready to use the camera.

The first portion of the primary process loop sets the default display modes. The process sets the camera to display active images using the display range that was provided by the thermal_cam_config.py file.

After the default mode flags are set, the image_group display group is activated and a "ready" tone is sounded.

The primary is now ready to start looping.

Download: file
###--- PRIMARY PROCESS SETUP ---###
display_image = True   # Image display mode; False for histogram
display_hold  = False  # Active display mode; True to hold display
display_focus = False  # Standard display range; True to focus display range
orig_max_range_f = 0   # There are no initial range values
orig_min_range_f = 0

# Activate display and play welcome tone
board.DISPLAY.show(image_group)
panel.play_tone(880, 0.1)  # A5; ready to start looking

Primary Process Loop, Part I

Because of its complexity, the primary process loop is divided into two sections to make it easier to understand. The first section fetches the image sensor's data, analyzes and displays the sensor data as an image or histogram, and checks to see if any of the sensor elements have exceeded the alarm threshold.

Retrieve Sensor Data, Display Image or Histogram, Check Alarm Threshold

The image sensor's 64 data elements are moved into the image list as long as the display_hold flag is false; otherwise a "-HOLD-" status message is displayed. Also, the status message area is cleared whenever gathering image sensor data.

Download: file
###--- PRIMARY PROCESS LOOP ---###
while True:
    if display_hold:  # Flash hold status text label
        flash_status("-HOLD-")
    else:
        image = amg8833.pixels  # Get camera data list if not in hold mode
        status_label.text = ""  # Clear hold mode status text label

This section checks the display_image flag to see whether to display a sensor image or histogram. If display_image is True, the update_image_frame() helper is used to display the data contained in the image list as an thermal image. When False, update_histo_frame() displays the data as a histogram distribution.

Download: file
if display_image:  # Image display mode and gather min, max, and sum stats
        v_min, v_max, v_sum = update_image_frame()
    else:  # Histogram display mode and gather min, max, and sum stats
        v_min, v_max, v_sum = update_histo_frame()

After the display is updated with an image or histogram, the current alarm threshold value, ALARM_F, is converted to a string and displayed.

The minimum and maximum Celsius values returned by the update_image_frame() and update_histo_frame() helpers are converted to a string representation of the equivalent Fahrenheit temperature values and displayed.

The returned "sum bucket" value (v_sum) is divided by the number of sensor elements to produce an average temperature value. The average temperature value is converted to a string representation of the equivalent Fahrenheit value and displayed.

Download: file
# Display alarm setting and maxumum, minimum, and average stats
    alarm_value.text = str(ALARM_F)
    max_value.text   = str(celsius_to_fahrenheit(v_max))
    min_value.text   = str(celsius_to_fahrenheit(v_min))
    ave_value.text   = str(celsius_to_fahrenheit(v_sum // 64))

The next step in the primary process loop checks the returned maximum value against the current alarm threshold (ALARM_C). If the threshold is met or exceeded, the NeoPixels flash red while two tones are played through the speaker. The second tone's frequency is proportional to the maximum temperature relative value above the alarm threshold.

Download: file
# Flash first NeoPixel and play alarm notes if alarm threshold is exceeded
    # Second alarm note frequency is proportional to value above threshold
    if v_max >= ALARM_C:
        panel.pixels.fill(RED)
        panel.play_tone(880, 0.015)  # A5
        panel.play_tone(880 + (10 * (v_max - ALARM_C)), 0.015)  # A5
        panel.pixels.fill(BLACK)

Primary Process Loop, Part II

The second portion of the primary process loop checks to see if any buttons have been pressed and sets the appropriate flags to modify display functions. This section also watches the SET button to activate the setup_mode() helper to permit changing camera parameters.

Watch the Buttons and Change Parameters

This section of the primary loop code looks for any of the buttons to be pressed. If any of the HOLD, IMG/HST, or FOCUS buttons are pressed, then the corresponding display mode flag is toggled. After a flag is toggled, the code waits until the button is released then plays a short confirmation tone before continuing in the primary loop.

Download: file
# See if a panel button is pressed
    if panel.button.a:  # Toggle display hold (shutter = button A)
        panel.play_tone(1319, 0.030)  # E6
        while panel.button.a:
            pass   # wait for button release
        if not display_hold:
            display_hold = True
        else:
            display_hold = False

    if panel.button.b:  # Toggle image/histogram mode (display mode = button B)
        panel.play_tone(659, 0.030)  # E5
        while panel.button.b:
            pass  # wait for button release
        if display_image:
            display_image = False
        else:
            display_image = True

When the FOCUS button is first pressed, not only is the display_focus flag set, but the currently measured minimum and maximum values are used as the display range. When in FOCUS mode, the new display range values will provide more detail based on the range of temperatures measured in the image. Pressing the FOCUS button the second time will restore the original default or set display range values, restoring the original image resolution.

Download: file
if panel.button.select:  # toggle focus mode (focus mode = select button)
        panel.play_tone(698, 0.030)  # F5
        if display_focus:
            display_focus = False  # restore previous (original) range values
            MIN_RANGE_F = orig_min_range_f
            MAX_RANGE_F = orig_max_range_f
            # update range min and max values in Celsius
            MIN_RANGE_C = fahrenheit_to_celsius(MIN_RANGE_F)
            MAX_RANGE_C = fahrenheit_to_celsius(MAX_RANGE_F)
            flash_status("ORIG", 0.2)
        else:
            display_focus = True  # set range values to image min/max
            orig_min_range_f = MIN_RANGE_F
            orig_max_range_f = MAX_RANGE_F
            MIN_RANGE_F = celsius_to_fahrenheit(v_min)
            MAX_RANGE_F = celsius_to_fahrenheit(v_max)
            MIN_RANGE_C = v_min  # update range temp in Celsius
            MAX_RANGE_C = v_max  # update range temp in Celsius
            flash_status("FOCUS", 0.2)
        while panel.button.select:
            pass  # wait for button release

When the SET button is pressed, the setup_mode() helper is executed. When setup has completed, this section of code goes back to the start of the primary loop to start the display and button monitoring process again.

Download: file
if panel.button.start:  # activate setup mode (setup mode = start button)
        panel.play_tone(784, 0.030)  # G5
        while panel.button.start:
            pass  # wait for button release

        # Update alarm and range values
        ALARM_F, MAX_RANGE_F, MIN_RANGE_F = setup_mode()
        ALARM_C = fahrenheit_to_celsius(ALARM_F)
        MIN_RANGE_C = fahrenheit_to_celsius(MIN_RANGE_F)
        MAX_RANGE_C = fahrenheit_to_celsius(MAX_RANGE_F)

    # bottom of primary loop
This guide was first published on Jan 29, 2020. It was last updated on Jan 29, 2020.
This page (Primary Process) was last updated on Aug 09, 2020.