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.
###--- 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.
###--- 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.
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.
# 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.
# 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.
# 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.
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.
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