|
| 1 | +import time |
| 2 | +import board |
| 3 | +import busio |
| 4 | +import adafruit_mlx90640 |
| 5 | +import displayio |
| 6 | +import terminalio |
| 7 | +from adafruit_display_text.label import Label |
| 8 | + |
| 9 | +number_of_colors = 64 |
| 10 | +palette = displayio.Palette(number_of_colors) # Palette with all our colors |
| 11 | + |
| 12 | +## Heatmap code inspired from: http://www.andrewnoske.com/wiki/Code_-_heatmaps_and_color_gradients |
| 13 | +color_A = [[0, 0, 0], [0, 0, 255], [0, 255, 255], [0, 255, 0], [255, 255, 0], \ |
| 14 | + [255, 0, 0], [255, 255, 255]] |
| 15 | +color_B = [[0, 0, 255], [0, 255, 255] , [0, 255, 0], [255, 255, 0], [255, 0, 0]] |
| 16 | +color_C = [[0, 0, 0], [255, 255, 255]] |
| 17 | +color_D = [[0, 0, 255], [255, 0, 0]] |
| 18 | + |
| 19 | +color = color_B |
| 20 | +NUM_COLORS = len (color) |
| 21 | + |
| 22 | +def MakeHeatMapColor(): |
| 23 | + for c in range(number_of_colors): |
| 24 | + value = c * (NUM_COLORS-1) / (number_of_colors - 1) |
| 25 | + idx1 = int(value) # Our desired color will be after this index. |
| 26 | + if idx1 == value : # This is the corner case |
| 27 | + red = color[idx1][0] |
| 28 | + green = color[idx1][1] |
| 29 | + blue = color[idx1][2] |
| 30 | + else: |
| 31 | + idx2 = idx1+1 # ... and before this index (inclusive). |
| 32 | + fractBetween = value - idx1 # Distance between the two indexes (0-1). |
| 33 | + red = int(round((color[idx2][0] - color[idx1][0]) * fractBetween + color[idx1][0])) |
| 34 | + green = int(round((color[idx2][1] - color[idx1][1]) * fractBetween + color[idx1][1])) |
| 35 | + blue = int(round((color[idx2][2] - color[idx1][2]) * fractBetween + color[idx1][2])) |
| 36 | + palette[c]= ( 0x010000 * red ) + ( 0x000100 * green ) + ( 0x000001 * blue ) |
| 37 | + |
| 38 | +MakeHeatMapColor() |
| 39 | + |
| 40 | +# Bitmap for colour coded thermal value |
| 41 | +image_bitmap = displayio.Bitmap( 32, 24, number_of_colors ) |
| 42 | +# Create a TileGrid using the Bitmap and Palette |
| 43 | +image_tile= displayio.TileGrid(image_bitmap, pixel_shader=palette) |
| 44 | +# Create a Group that scale 32*24 to 128*96 |
| 45 | +image_group = displayio.Group(scale=4) |
| 46 | +image_group.append(image_tile) |
| 47 | + |
| 48 | +scale_bitmap = displayio.Bitmap( number_of_colors, 1, number_of_colors ) |
| 49 | +# Create a Group Scale must be 128 divided by number_of_colors |
| 50 | +scale_group = displayio.Group(scale=2) |
| 51 | +scale_tile = displayio.TileGrid(scale_bitmap, pixel_shader=palette, x = 0, y = 60) |
| 52 | +scale_group.append(scale_tile) |
| 53 | + |
| 54 | +for i in range(number_of_colors): |
| 55 | + scale_bitmap[i, 0] = i # Fill the scale with the palette gradian |
| 56 | + |
| 57 | +# Create the super Group |
| 58 | +group = displayio.Group() |
| 59 | + |
| 60 | +min_label = Label(terminalio.FONT, max_glyphs=10, color=palette[0], x = 0, y = 110) |
| 61 | +max_label = Label(terminalio.FONT, max_glyphs=10, color=palette[number_of_colors-1], \ |
| 62 | + x = 80, y = 110) |
| 63 | + |
| 64 | +# Add all the sub-group to the SuperGroup |
| 65 | +group.append(image_group) |
| 66 | +group.append(scale_group) |
| 67 | +group.append(min_label) |
| 68 | +group.append(max_label) |
| 69 | + |
| 70 | +# Add the SuperGroup to the Display |
| 71 | +board.DISPLAY.show(group) |
| 72 | + |
| 73 | +mini = 0 |
| 74 | +maxi = 0 |
| 75 | + |
| 76 | +my_a1 = 20 |
| 77 | +my_a2 = 37 |
| 78 | + |
| 79 | +def temp2index(s, a1, a2): |
| 80 | + b1 = 0 |
| 81 | + b2 = number_of_colors - 1 |
| 82 | + |
| 83 | + if s < a1: |
| 84 | + r = b1 |
| 85 | + elif s > a2: |
| 86 | + r = b2 |
| 87 | + else: |
| 88 | + r = int( round( b1 + ( (s - a1) * (b2 - b1) / (a2 - a1) ) ) ) |
| 89 | + return r |
| 90 | + |
| 91 | +i2c = busio.I2C(board.SCL, board.SDA, frequency=800000) |
| 92 | + |
| 93 | +mlx = adafruit_mlx90640.MLX90640(i2c) |
| 94 | +print("MLX addr detected on I2C") |
| 95 | +print([hex(i) for i in mlx.serial_number]) |
| 96 | + |
| 97 | +#mlx.refresh_rate = adafruit_mlx90640.RefreshRate.REFRESH_2_HZ |
| 98 | +mlx.refresh_rate = adafruit_mlx90640.RefreshRate.REFRESH_4_HZ |
| 99 | + |
| 100 | +frame = [0] * 768 |
| 101 | + |
| 102 | +while True: |
| 103 | + stamp = time.monotonic() |
| 104 | + try: |
| 105 | + mlx.getFrame(frame) |
| 106 | + except ValueError: |
| 107 | + # these happen, no biggie - retry |
| 108 | + continue |
| 109 | + print("Read 2 frames in %0.2f s" % (time.monotonic()-stamp)) |
| 110 | + |
| 111 | + mini = frame[0] # Define a default min and max value |
| 112 | + maxi = frame[0] # Will be updated by temp2index function |
| 113 | + |
| 114 | + for h in range(24): |
| 115 | + for w in range(32): |
| 116 | + t = frame[h*32 + w] |
| 117 | + if t > maxi: |
| 118 | + maxi = t |
| 119 | + if t < mini: |
| 120 | + mini = t |
| 121 | + image_bitmap[w, (23-h)] = temp2index(t, my_a1, my_a2) |
| 122 | + |
| 123 | + min_label.text="%0.2f" % (my_a1) |
| 124 | + |
| 125 | + max_string="%0.2f" % (my_a2) |
| 126 | + max_label.x=120-(5*len(max_string)) # Tricky calculation to left align |
| 127 | + max_label.text=max_string |
| 128 | + |
| 129 | + my_a1 = mini # Automatically change the color scale |
| 130 | + my_a2 = maxi |
0 commit comments