/ TFT_Sidekick_With_FT232H / tft_sidekick_basic.py
tft_sidekick_basic.py
1 # SPDX-FileCopyrightText: 2019 Carter Nelson for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 5 import time 6 from collections import deque 7 import random 8 import math 9 # Blinka CircuitPython 10 import board 11 import digitalio 12 import adafruit_rgb_display.ili9341 as ili9341 13 # Matplotlib 14 import matplotlib.pyplot as plt 15 # Python Imaging Library 16 from PIL import Image 17 18 #pylint: disable=bad-continuation 19 #==| User Config |======================================================== 20 REFRESH_RATE = 0.5 21 HIST_SIZE = 61 22 PLOT_CONFIG = ( 23 #-------------------- 24 # PLOT 1 (upper plot) 25 #-------------------- 26 { 27 'line_config' : ( 28 {'color' : '#FF0000', 'width' : 2, 'style' : '--'}, 29 { }, 30 ) 31 }, 32 #-------------------- 33 # PLOT 2 (lower plot) 34 #-------------------- 35 { 36 'title' : 'sin()', 37 'ylim' : (-1.5, 1.5), 38 'line_config' : ( 39 {'color' : '#00FF00', 'width' : 4}, 40 ) 41 } 42 ) 43 44 def update_data(): 45 ''' Do whatever to update your data here. General form is: 46 y_data[plot][line].append(new_data_point) 47 ''' 48 # upper plot data 49 for data in y_data[0]: 50 data.append(random.random()) 51 52 # lower plot data 53 y_data[1][0].append(math.sin(0.5 * time.monotonic())) 54 55 #==| User Config |======================================================== 56 #pylint: enable=bad-continuation 57 58 # Setup X data storage 59 x_time = [x * REFRESH_RATE for x in range(HIST_SIZE)] 60 x_time.reverse() 61 62 # Setup Y data storage 63 y_data = [ [deque([None] * HIST_SIZE, maxlen=HIST_SIZE) for _ in plot['line_config']] 64 for plot in PLOT_CONFIG 65 ] 66 67 # Setup display 68 disp = ili9341.ILI9341(board.SPI(), baudrate = 24000000, 69 cs = digitalio.DigitalInOut(board.D4), 70 dc = digitalio.DigitalInOut(board.D5), 71 rst = digitalio.DigitalInOut(board.D6)) 72 73 # Setup plot figure 74 plt.style.use('dark_background') 75 fig, ax = plt.subplots(2, 1, figsize=(disp.width / 100, disp.height / 100)) 76 77 # Setup plot axis 78 ax[0].xaxis.set_ticklabels([]) 79 for plot, a in enumerate(ax): 80 # add grid to all plots 81 a.grid(True, linestyle=':') 82 # limit and invert x time axis 83 a.set_xlim(min(x_time), max(x_time)) 84 a.invert_xaxis() 85 # custom settings 86 if 'title' in PLOT_CONFIG[plot]: 87 a.set_title(PLOT_CONFIG[plot]['title'], position=(0.5, 0.8)) 88 if 'ylim' in PLOT_CONFIG[plot]: 89 a.set_ylim(PLOT_CONFIG[plot]['ylim']) 90 91 # Setup plot lines 92 #pylint: disable=redefined-outer-name 93 plot_lines = [] 94 for plot, config in enumerate(PLOT_CONFIG): 95 lines = [] 96 for index, line_config in enumerate(config['line_config']): 97 # create line 98 line, = ax[plot].plot(x_time, y_data[plot][index]) 99 # custom settings 100 if 'color' in line_config: 101 line.set_color(line_config['color']) 102 if 'width' in line_config: 103 line.set_linewidth(line_config['width']) 104 if 'style' in line_config: 105 line.set_linestyle(line_config['style']) 106 # add line to list 107 lines.append(line) 108 plot_lines.append(lines) 109 110 def update_plot(): 111 # update lines with latest data 112 for plot, lines in enumerate(plot_lines): 113 for index, line in enumerate(lines): 114 line.set_ydata(y_data[plot][index]) 115 # autoscale if not specified 116 if 'ylim' not in PLOT_CONFIG[plot].keys(): 117 ax[plot].relim() 118 ax[plot].autoscale_view() 119 # draw the plots 120 canvas = plt.get_current_fig_manager().canvas 121 plt.tight_layout() 122 canvas.draw() 123 # transfer into PIL image and display 124 image = Image.frombytes('RGB', canvas.get_width_height(), 125 canvas.tostring_rgb()) 126 disp.image(image) 127 128 print("looping") 129 while True: 130 update_data() 131 update_plot() 132 time.sleep(REFRESH_RATE)