Lepton thermal camera composite video out with selectable color palettes

Have the lepton 3.5 with an H7 board, this program runs fine but instead of having a three position switch that selects the palette at startup (the if/else), I want to use a single push button to move between the three palettes during normal operation (without having to restart board).

# On Off On switch 

import sensor, image, time, math, tv, pyb

# Set GPIO input
switchColorOne = pyb.Pin("P9", pyb.Pin.IN, pyb.Pin.PULL_UP)
switchColorTwo = pyb.Pin("P8", pyb.Pin.IN, pyb.Pin.PULL_UP)
switchButton = pyb.Pin("P7", pyb.Pin.IN, pyb.Pin.PULL_UP) # This is the button

# Set threshold_list by switch
if switchColorOne.value() == 0 | switchColorTwo.value() == 0:
    # Color Tracking Thresholds (L Min, L Max, A Min, A Max, B Min, B Max)
    threshold_list = [( 70, 100,  -30,   40,   20,  100)]
else:
    # Color Tracking Thresholds (Grayscale Min, Grayscale Max)
    threshold_list = [(220, 255)]

print("Resetting Lepton...")
# These settings are applied on reset
sensor.reset()
print("Lepton Res (%dx%d)" % (sensor.ioctl(sensor.IOCTL_LEPTON_GET_WIDTH),
                              sensor.ioctl(sensor.IOCTL_LEPTON_GET_HEIGHT)))
print("Radiometry Available: " + ("Yes" if sensor.ioctl(sensor.IOCTL_LEPTON_GET_RADIOMETRY) 
else "No"))

# Set color palette by switch
if switchColorOne.value() == 0:
    sensor.set_pixformat(sensor.RGB565)
elif switchColorTwo.value() == 0:
    sensor.set_pixformat(sensor.GRAYSCALE)
else:
    sensor.set_color_palette(sensor.PALETTE_IRONBOW)
    sensor.set_pixformat(sensor.RGB565)

sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=5000)
clock = time.clock()

tv.init(triple_buffer=False) # Initialize the tv.
tv.channel(8) # For wireless video transmitter shield

while(True):
    clock.tick()
    img = sensor.snapshot()
    tv.display(sensor.snapshot()) # Take a picture and display the image.

I tried this:

    if switchButton == False:
    sensor.reset()
    value = (value + 1)%3
    if value == 0:
        threshold_list = [( 70, 100,  -30,   40,   20,  100)]
        sensor.set_color_palette(sensor.PALETTE_IRONBOW)
        sensor.set_pixformat(sensor.RGB565)
    elif value == 1:
        threshold_list = [( 70, 100,  -30,   40,   20,  100)]
        sensor.set_pixformat(sensor.RGB565)
    else:
        threshold_list = [(220, 255)]
        sensor.set_pixformat(sensor.GRAYSCALE)

I wasn’t sure where to put it, it didn’t work kept getting errors. I’ve taken a python 101 type class but this stuff is a little over my head. Someone mentioned interrupts, I looked at this micropython documentation on gpio interrupts and this openmv python documentation on interrupt handlers but I am having a hard time grasping. Google isn’t helping much, I get mostly results on python GUI buttons.

Also, there’s some blob tracking code in there, I was just experimenting.

Any help pointing me in the right direction, or just assurance that I need to learn interrupter handling and callback functions, would be very appreciated.

Hi, I can fix your code up if you still need it… but, no, you are making this more complex than you think.

Just call sensor.set_pixformat() in the loop given the button position.

Finally, is possible, gate the call to set_pi format so it’s not called every loop unless the button is pressed.

I would appreciate to see how you would fix it. I felt like there was a simple solution that I was unaware of.

Something like this:

# On Off On switch 

import sensor, image, time, math, tv, pyb, micropython

threshold_list = None

def switchCb(num):
    if num == 1:
        sensor.set_pixformat(sensor.RGB565)
        threshold_list = [( 70, 100,  -30,   40,   20,  100)]
    elif num == 2:
        sensor.set_pixformat(sensor.GRAYSCALE)
        threshold_list = [(220, 255)]

def switchColorOneCb(line):
    # This is run during an interrupt so it's not safe to do much here.
    # micropython.schedule calls switchCb between MicroPython byte codes.
    micropython.schedule(switchCb, 1)

def switchColorTwoCb(line):
    # This is run during an interrupt so it's not safe to do much here.
    # micropython.schedule calls switchCb between MicroPython byte codes.
    micropython.schedule(switchCb, 2)

def switchButtonCb(line):
    # This is run during an interrupt so it's not safe to do much here.
    # micropython.schedule calls switchCb between MicroPython byte codes.
    micropython.schedule(switchCb, 0)

# Set GPIO input
switchColorOne = pyb.ExtInt("P9", pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, switchColorOneCb)
switchColorTwo = pyb.ExtInt("P8", pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, switchColorTwoCb)
switchButton = pyb.ExtInt("P7", pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, switchButtonCb)

print("Resetting Lepton...")
# These settings are applied on reset
sensor.reset()
print("Lepton Res (%dx%d)" % (sensor.ioctl(sensor.IOCTL_LEPTON_GET_WIDTH),
                              sensor.ioctl(sensor.IOCTL_LEPTON_GET_HEIGHT)))
print("Radiometry Available: " + ("Yes" if sensor.ioctl(sensor.IOCTL_LEPTON_GET_RADIOMETRY) 
else "No"))

sensor.set_color_palette(sensor.PALETTE_IRONBOW)
sensor.set_pixformat(sensor.RGB565)

sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=5000)
clock = time.clock()

tv.init(triple_buffer=False) # Initialize the tv.
tv.channel(8) # For wireless video transmitter shield

while(True):
    clock.tick()
    img = sensor.snapshot()
    tv.display(sensor.snapshot()) # Take a picture and display the image.

Do I write an interrupt in the while loop to call the switchVuttonCb()? switchColorOne and switchColorTwo will be removed, leaving only the switchButton. Sorry, this is my first time trying to do this and I’m pretty in the woods.

The interrupt methods are called as an interrupt… meaning that they magically get called outside of your loop context.

The main loop doesn’t need to think about them. They will just get run between MicroPython code when there’s a falling edge on any of those pins.