From c725b4eee0ef11a479a3ae6da6923092afcfa8ab Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Thu, 7 Sep 2023 10:14:30 +0100 Subject: [PATCH] Tufty 2040: Vector examples. Add AdvRe.af for PicoW Explorer and Tufty 2040 spectrometer examples. --- micropython/examples/common/AdvRe.af | Bin 0 -> 3747 bytes .../picow_explorer/vector_spectrometer.py | 3 +- .../examples/tufty2040/vector_clock.py | 119 ++++++++++++++++++ .../examples/tufty2040/vector_spectrometer.py | 118 +++++++++++++++++ 4 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 micropython/examples/common/AdvRe.af create mode 100644 micropython/examples/tufty2040/vector_clock.py create mode 100644 micropython/examples/tufty2040/vector_spectrometer.py diff --git a/micropython/examples/common/AdvRe.af b/micropython/examples/common/AdvRe.af new file mode 100644 index 0000000000000000000000000000000000000000..558bb738a1d42ba0dc12a92798cfcbd9d75a2e97 GIT binary patch literal 3747 zcmaJ@NpmDe75;)~nQ=;13z6aIm{2NYS)Lk(#!z4eLm6yCVfF^RK(k{3w(*$FHk%jb zKk4F29dzl7FLjwqU396-9O|M=o%z0em95f@!xK|8uiwkJeQ(Kp`ISeW#_s?e@Po%E z@Cg4a10Kd9=7+O6iARC5T;Mqzp)Zytp1@;3QI?qFnsG{Gm``UjY~ecku*@*SXA*G( zSr&5a;j?f>UXqxjx5J-9$X!9L$ARfo>YoR)GN<|%fV?cQk34a{Xq@Z#k`YfZka%W> zFB@?UH;tI%D@N?#Nh6-bSCi;#^p($;SHUm}5l_K|TrqzgJ`V*s-$EiwT$Q|lD2WZ{0laWnHdJLqNNoEMDw*Z|+h9}?$} ziSwt#dBr#fcom(>eT3JHa}|G1efWCcg=Jvd+%nM--Z0S?{sJuWC7a~0X7FMB&4_*c z-3;#IABlJ~oq5ZMBfL%GnSzb}&m{Vn5m)hVvwVR67-x?Enw!T@I_Fo0~3C|@4cuFm9Kmkxpz=atLYs~{2gB%R)=@Q&DyL9O=z*_;5wdf zUF#Y&s9o)O-q9PqW_?C|YOkF9o@6Ic zcjZ^U$*EiPx%3>*PNXk8jIxeV)^LoW^@^v;tGvnD&_??QvQMQR?Zz3cU$UQ9#i~%0 zgO|MZtyd(nKJtf@Kj=phRPH341jUJfAP(Kfe=1Zs@stI4@wZ&#YDT$o%!}Mrw#w>I zhek3Y-GVv$#)}^@BC0)Q6WTkUo=;_CqBD7uw~XM0gbO#cA_7%GY{mgs7%QwNj{Inn=bNm_hMd{Y#Em_qx!p~@TAnPbMOUg` zEB1l9JN9mgl2CA-sINK0L%GjftTx%|n>ZnE>6U7&iDp!tFw&5|onrUiJhM3^&oE9F z(u|E}Yp^H3JswzFu^!vfZ*GpEy5_a$Iq}xN_sYcIO}%kxs^eZE#+t2>ZS^6umK|-C zG&%CSo(;~Fs+8tqE835JKpZ08)Ha)+zJy!s^1*sSC1DsdrT2cwW@qUaZn0wB6o>Lv zF4eL+ULCvJ?zVnzMeA$XeKj!**Rvkw7S}~(ugGeYus_nCP#zKg?aT)kv>M`cB@4M@ zY*zWyAv>2dHH$;#Q;s|I6>(4dJXJF7amuf-gA<0@ePn5e)4$M@wrXQpY;u#^?zkJy zv%67Z+kN|fjYYqxj;rIIZw0*(rD=2iQB@h&ewz{54Rq;boF>^CwuZZJ+B6YEHLnoD z`)-EIb_2I*%vNXl*Toxyw+VmoXS|={Zb_S1dm!G+$;a%&>FLJl#s{+x4o~N&^A9EG zWXI0LW<;cO+AHxc&bUd|n@}5vw*obkBd3xw+y0gv@2bd)+Bz${c{kd_gN5jYr@4`| zv1yPo(4#im5JR$+CPrtr`K5h3+TQE=Qy%7F(|PCCJxN>Kh%Qq-H~C#eulrXTWJZ)~ zUz48bZexZkazDujjc#X293KN?nL1VHl&?H+1JCa=Us+Y$$*RtXeuy7mGmB=y2RSz_ zksbMeP*THt#J$MLCN$w-zf>$fC3gYUKYR@)`bzpkC0@zqAH^;=FeuZV{?9Wx=WoS!DEi@G4L^xf*M{D0kO BGMfMZ literal 0 HcmV?d00001 diff --git a/micropython/examples/picow_explorer/vector_spectrometer.py b/micropython/examples/picow_explorer/vector_spectrometer.py index e04d8937..012e299a 100644 --- a/micropython/examples/picow_explorer/vector_spectrometer.py +++ b/micropython/examples/picow_explorer/vector_spectrometer.py @@ -5,7 +5,6 @@ from breakout_as7262 import BreakoutAS7262 from picographics import PicoGraphics, DISPLAY_PICO_W_EXPLORER, PEN_RGB332 from picovector import PicoVector, Polygon, RegularPolygon, ANTIALIAS_X4 -PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5} PINS_PICO_EXPLORER = {"sda": 20, "scl": 21} i2c = PimoroniI2C(**PINS_PICO_EXPLORER) @@ -25,7 +24,7 @@ display.set_backlight(0.8) vector = PicoVector(display) vector.set_antialiasing(ANTIALIAS_X4) -# Load an Alright Font +# Load an Alright Font, find this in common/AdvRe.af result = vector.set_font("/AdvRe.af", 30) WIDTH, HEIGHT = display.get_bounds() diff --git a/micropython/examples/tufty2040/vector_clock.py b/micropython/examples/tufty2040/vector_clock.py new file mode 100644 index 00000000..afb626c9 --- /dev/null +++ b/micropython/examples/tufty2040/vector_clock.py @@ -0,0 +1,119 @@ +import time +import gc + +from picographics import PicoGraphics, DISPLAY_TUFTY_2040, PEN_RGB332 +from picovector import PicoVector, Polygon, RegularPolygon, Rectangle, ANTIALIAS_X4 + + +display = PicoGraphics(DISPLAY_TUFTY_2040, pen_type=PEN_RGB332) + +vector = PicoVector(display) +vector.set_antialiasing(ANTIALIAS_X4) + +RED = display.create_pen(200, 0, 0) +BLACK = display.create_pen(0, 0, 0) +GREY = display.create_pen(200, 200, 200) +WHITE = display.create_pen(255, 255, 255) + +""" +# Redefine colours for a Blue clock +RED = display.create_pen(200, 0, 0) +BLACK = display.create_pen(135, 159, 169) +GREY = display.create_pen(10, 40, 50) +WHITE = display.create_pen(14, 60, 76) +""" + +WIDTH, HEIGHT = display.get_bounds() + +hub = RegularPolygon(int(WIDTH / 2), int(HEIGHT / 2), 24, 5) + +face = RegularPolygon(int(WIDTH / 2), int(HEIGHT / 2), 48, int(HEIGHT / 2)) + +print(time.localtime()) + +last_second = None + +while True: + t_start = time.ticks_ms() + year, month, day, hour, minute, second, _, _ = time.localtime() + + if last_second == second: + continue + + last_second = second + + display.set_pen(0) + display.clear() + + display.set_pen(BLACK) + display.circle(int(WIDTH / 2), int(HEIGHT / 2), int(HEIGHT / 2)) + display.set_pen(WHITE) + display.circle(int(WIDTH / 2), int(HEIGHT / 2), int(HEIGHT / 2) - 4) + + display.set_pen(GREY) + + for a in range(60): + tick_mark = Rectangle(int(WIDTH / 2) - 3, 10, 6, int(HEIGHT / 48)) + vector.rotate(tick_mark, 360 / 60.0 * a, int(WIDTH / 2), int(HEIGHT / 2)) + vector.translate(tick_mark, 0, 2) + vector.draw(tick_mark) + + for a in range(12): + hour_mark = Rectangle(int(WIDTH / 2) - 5, 10, 10, int(HEIGHT / 10)) + vector.rotate(hour_mark, 360 / 12.0 * a, int(WIDTH / 2), int(HEIGHT / 2)) + vector.translate(hour_mark, 0, 2) + vector.draw(hour_mark) + + angle_second = second * 6 + second_hand_length = int(HEIGHT / 2) - int(HEIGHT / 8) + second_hand = Polygon((-2, -second_hand_length), (-2, int(HEIGHT / 8)), (2, int(HEIGHT / 8)), (2, -second_hand_length)) + vector.rotate(second_hand, angle_second, 0, 0) + vector.translate(second_hand, int(WIDTH / 2), int(HEIGHT / 2) + 5) + + angle_minute = minute * 6 + angle_minute += second / 10.0 + minute_hand_length = int(HEIGHT / 2) - int(HEIGHT / 24) + minute_hand = Polygon((-5, -minute_hand_length), (-10, int(HEIGHT / 16)), (10, int(HEIGHT / 16)), (5, -minute_hand_length)) + vector.rotate(minute_hand, angle_minute, 0, 0) + vector.translate(minute_hand, int(WIDTH / 2), int(HEIGHT / 2) + 5) + + angle_hour = (hour % 12) * 30 + angle_hour += minute / 2 + hour_hand_length = int(HEIGHT / 2) - int(HEIGHT / 8) + hour_hand = Polygon((-5, -hour_hand_length), (-10, int(HEIGHT / 16)), (10, int(HEIGHT / 16)), (5, -hour_hand_length)) + vector.rotate(hour_hand, angle_hour, 0, 0) + vector.translate(hour_hand, int(WIDTH / 2), int(HEIGHT / 2) + 5) + + display.set_pen(GREY) + + vector.draw(minute_hand) + vector.draw(hour_hand) + vector.draw(second_hand) + + display.set_pen(BLACK) + + for a in range(60): + tick_mark = Rectangle(int(WIDTH / 2) - 3, 10, 6, int(HEIGHT / 48)) + vector.rotate(tick_mark, 360 / 60.0 * a, int(WIDTH / 2), int(HEIGHT / 2)) + vector.draw(tick_mark) + + for a in range(12): + hour_mark = Rectangle(int(WIDTH / 2) - 5, 10, 10, int(HEIGHT / 10)) + vector.rotate(hour_mark, 360 / 12.0 * a, int(WIDTH / 2), int(HEIGHT / 2)) + vector.draw(hour_mark) + + vector.translate(minute_hand, 0, -5) + vector.translate(hour_hand, 0, -5) + vector.draw(minute_hand) + vector.draw(hour_hand) + + display.set_pen(RED) + vector.translate(second_hand, 0, -5) + vector.draw(second_hand) + vector.draw(hub) + + display.update() + gc.collect() + + t_end = time.ticks_ms() + print(f"Took {t_end - t_start}ms") diff --git a/micropython/examples/tufty2040/vector_spectrometer.py b/micropython/examples/tufty2040/vector_spectrometer.py new file mode 100644 index 00000000..1ed00ffc --- /dev/null +++ b/micropython/examples/tufty2040/vector_spectrometer.py @@ -0,0 +1,118 @@ +import math +import time +from pimoroni_i2c import PimoroniI2C +from breakout_as7262 import BreakoutAS7262 +from picographics import PicoGraphics, DISPLAY_TUFTY_2040, PEN_RGB332 +from picovector import PicoVector, Polygon, RegularPolygon, ANTIALIAS_X4 + +PINS_TUFTY_2040 = {"sda": 4, "scl": 5} +i2c = PimoroniI2C(**PINS_TUFTY_2040) + +# Set up the AS7262 Spectrometer +as7262 = BreakoutAS7262(i2c) +as7262.set_gain(BreakoutAS7262.X16) +as7262.set_measurement_mode(BreakoutAS7262.CONT_ROYGBR) +as7262.set_illumination_current(BreakoutAS7262.MA12) +as7262.set_indicator_current(BreakoutAS7262.MA4) +as7262.set_leds(True, True) + +# Set up the display +display = PicoGraphics(DISPLAY_TUFTY_2040, pen_type=PEN_RGB332) +display.set_backlight(0.8) + +# Set up PicoVector +vector = PicoVector(display) +vector.set_antialiasing(ANTIALIAS_X4) + +# Load an Alright Font, find this in common/AdvRe.af +result = vector.set_font("/AdvRe.af", 30) + +WIDTH, HEIGHT = display.get_bounds() + +CENTER_X = int(WIDTH / 2) +CENTER_Y = int(HEIGHT / 2) + +RADIUS = 90 +DEBUG = False + +RED = display.create_pen(255, 0, 0) +ORANGE = display.create_pen(255, 128, 0) +YELLOW = display.create_pen(255, 255, 0) +GREEN = display.create_pen(0, 255, 0) +BLUE = display.create_pen(0, 0, 255) +VIOLET = display.create_pen(255, 0, 255) + +BLACK = display.create_pen(0, 0, 0) +GREY = display.create_pen(128, 128, 128) +WHITE = display.create_pen(255, 255, 255) + +LABELS = ["R", "O", "Y", "G", "B", "V"] +COLS = [RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET] + + +# Custom regular_polygon function to give each point its own "radius" +def regular_polygon(o_x, o_y, radius, rotation): + sides = 6 + angle = math.radians(360 / sides) + rotation = math.radians(rotation) + + points = [] + + for side in range(sides): + current_angle = side * angle + rotation + x = math.cos(current_angle) * radius[side] + y = math.sin(current_angle) * radius[side] + points.append((int(x) + o_x, int(y) + o_y)) + + return points + + +lines = RegularPolygon(CENTER_X, CENTER_Y, 6, RADIUS) +label_points = list(RegularPolygon(CENTER_X, CENTER_Y, 6, RADIUS * 0.7, -(360 / 12))) + + +while True: + # Clear to black + display.set_pen(BLACK) + display.clear() + + # Add the title + display.set_pen(WHITE) + vector.text("Spectrograph", 5, -5) + + # Get the spectrometer readings + reading = list(as7262.read()) + + # Print out the readings + if DEBUG: + for i in range(6): + print(f"{LABELS[i]}: {reading[i]:0.2f}", end=" ") + print("") + + # Draw the lines separating each section + display.set_pen(GREY) + for (x, y) in lines: + display.line(CENTER_X, CENTER_Y, int(x), int(y)) + + # Scale readings for display + for i in range(6): + reading[i] = int(reading[i] / 3.0) + reading[i] = min(reading[i], RADIUS) + + # Create a 6 point polygon with each points distance from the center + # scaled by the corresponding reading. + points = regular_polygon(CENTER_X, CENTER_Y, reading, 0) + + # Split the polygon into six triangles, one for each channel + # draw each one, along with its corresponding label + point_a = points[-1] + for i in range(6): + point_b = points[i] + label_x, label_y = label_points[i] + display.set_pen(COLS[i]) + vector.text(LABELS[i], int(label_x) - 5, int(label_y) - 20) + vector.draw(Polygon(point_a, point_b, (CENTER_X, CENTER_Y))) + point_a = point_b + + display.update() + time.sleep(1.0 / 60)