Skip to content

Instantly share code, notes, and snippets.

@spencerkittleson
Last active March 25, 2024 23:21
Show Gist options
  • Save spencerkittleson/9369bd8702e72c3c36bf572cda408b7e to your computer and use it in GitHub Desktop.
Save spencerkittleson/9369bd8702e72c3c36bf572cda408b7e to your computer and use it in GitHub Desktop.
from machine import Pin,I2C,SPI,PWM,ADC
import framebuf
import time
import math
DC = 8
CS = 9
SCK = 10
MOSI = 11
RST = 12
BL = 25
Vbat_Pin = 29
width = 240
height = 240
class LCD_1inch28(framebuf.FrameBuffer): # Waveshare RP2040 1.28" IPS LCD Board Driver - Round Display
def __init__(self):
self.width = 240
self.height = 240
self.cs = Pin(CS,Pin.OUT)
self.rst = Pin(RST,Pin.OUT)
self.cs(1)
self.spi = SPI(1,100_000_000,polarity=0, phase=0,sck=Pin(SCK),mosi=Pin(MOSI),miso=None)
self.dc = Pin(DC,Pin.OUT)
self.dc(1)
self.buffer = bytearray(self.height * self.width * 2)
super().__init__(self.buffer, self.width, self.height, framebuf.RGB565)
self.init_display()
self.red = 0x07E0
self.green = 0x001f
self.blue = 0xf800
self.white = 0xffff
self.fill(self.white)
self.show()
self.pwm = PWM(Pin(BL))
self.pwm.freq(5000)
def write_cmd(self, cmd):
self.cs(1)
self.dc(0)
self.cs(0)
self.spi.write(bytearray([cmd]))
self.cs(1)
def write_data(self, buf):
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(bytearray([buf]))
self.cs(1)
def set_bl_pwm(self,duty):
self.pwm.duty_u16(duty)#max 65535
def init_display(self):
"""Initialize display"""
self.rst(1)
time.sleep(0.01)
self.rst(0)
time.sleep(0.01)
self.rst(1)
time.sleep(0.05)
self.write_cmd(0xEF)
self.write_cmd(0xEB)
self.write_data(0x14)
self.write_cmd(0xFE)
self.write_cmd(0xEF)
self.write_cmd(0xEB)
self.write_data(0x14)
self.write_cmd(0x84)
self.write_data(0x40)
self.write_cmd(0x85)
self.write_data(0xFF)
self.write_cmd(0x86)
self.write_data(0xFF)
self.write_cmd(0x87)
self.write_data(0xFF)
self.write_cmd(0x88)
self.write_data(0x0A)
self.write_cmd(0x89)
self.write_data(0x21)
self.write_cmd(0x8A)
self.write_data(0x00)
self.write_cmd(0x8B)
self.write_data(0x80)
self.write_cmd(0x8C)
self.write_data(0x01)
self.write_cmd(0x8D)
self.write_data(0x01)
self.write_cmd(0x8E)
self.write_data(0xFF)
self.write_cmd(0x8F)
self.write_data(0xFF)
self.write_cmd(0xB6)
self.write_data(0x00)
self.write_data(0x20)
self.write_cmd(0x36)
self.write_data(0x98)
self.write_cmd(0x3A)
self.write_data(0x05)
self.write_cmd(0x90)
self.write_data(0x08)
self.write_data(0x08)
self.write_data(0x08)
self.write_data(0x08)
self.write_cmd(0xBD)
self.write_data(0x06)
self.write_cmd(0xBC)
self.write_data(0x00)
self.write_cmd(0xFF)
self.write_data(0x60)
self.write_data(0x01)
self.write_data(0x04)
self.write_cmd(0xC3)
self.write_data(0x13)
self.write_cmd(0xC4)
self.write_data(0x13)
self.write_cmd(0xC9)
self.write_data(0x22)
self.write_cmd(0xBE)
self.write_data(0x11)
self.write_cmd(0xE1)
self.write_data(0x10)
self.write_data(0x0E)
self.write_cmd(0xDF)
self.write_data(0x21)
self.write_data(0x0c)
self.write_data(0x02)
self.write_cmd(0xF0)
self.write_data(0x45)
self.write_data(0x09)
self.write_data(0x08)
self.write_data(0x08)
self.write_data(0x26)
self.write_data(0x2A)
self.write_cmd(0xF1)
self.write_data(0x43)
self.write_data(0x70)
self.write_data(0x72)
self.write_data(0x36)
self.write_data(0x37)
self.write_data(0x6F)
self.write_cmd(0xF2)
self.write_data(0x45)
self.write_data(0x09)
self.write_data(0x08)
self.write_data(0x08)
self.write_data(0x26)
self.write_data(0x2A)
self.write_cmd(0xF3)
self.write_data(0x43)
self.write_data(0x70)
self.write_data(0x72)
self.write_data(0x36)
self.write_data(0x37)
self.write_data(0x6F)
self.write_cmd(0xED)
self.write_data(0x1B)
self.write_data(0x0B)
self.write_cmd(0xAE)
self.write_data(0x77)
self.write_cmd(0xCD)
self.write_data(0x63)
self.write_cmd(0x70)
self.write_data(0x07)
self.write_data(0x07)
self.write_data(0x04)
self.write_data(0x0E)
self.write_data(0x0F)
self.write_data(0x09)
self.write_data(0x07)
self.write_data(0x08)
self.write_data(0x03)
self.write_cmd(0xE8)
self.write_data(0x34)
self.write_cmd(0x62)
self.write_data(0x18)
self.write_data(0x0D)
self.write_data(0x71)
self.write_data(0xED)
self.write_data(0x70)
self.write_data(0x70)
self.write_data(0x18)
self.write_data(0x0F)
self.write_data(0x71)
self.write_data(0xEF)
self.write_data(0x70)
self.write_data(0x70)
self.write_cmd(0x63)
self.write_data(0x18)
self.write_data(0x11)
self.write_data(0x71)
self.write_data(0xF1)
self.write_data(0x70)
self.write_data(0x70)
self.write_data(0x18)
self.write_data(0x13)
self.write_data(0x71)
self.write_data(0xF3)
self.write_data(0x70)
self.write_data(0x70)
self.write_cmd(0x64)
self.write_data(0x28)
self.write_data(0x29)
self.write_data(0xF1)
self.write_data(0x01)
self.write_data(0xF1)
self.write_data(0x00)
self.write_data(0x07)
self.write_cmd(0x66)
self.write_data(0x3C)
self.write_data(0x00)
self.write_data(0xCD)
self.write_data(0x67)
self.write_data(0x45)
self.write_data(0x45)
self.write_data(0x10)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x00)
self.write_cmd(0x67)
self.write_data(0x00)
self.write_data(0x3C)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x01)
self.write_data(0x54)
self.write_data(0x10)
self.write_data(0x32)
self.write_data(0x98)
self.write_cmd(0x74)
self.write_data(0x10)
self.write_data(0x85)
self.write_data(0x80)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x4E)
self.write_data(0x00)
self.write_cmd(0x98)
self.write_data(0x3e)
self.write_data(0x07)
self.write_cmd(0x35)
self.write_cmd(0x21)
self.write_cmd(0x11)
time.sleep(0.12)
self.write_cmd(0x29)
time.sleep(0.02)
self.write_cmd(0x21)
self.write_cmd(0x11)
self.write_cmd(0x29)
def show(self):
self.write_cmd(0x2A)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0xef)
self.write_cmd(0x2B)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0x00)
self.write_data(0xEF)
self.write_cmd(0x2C)
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(self.buffer)
self.cs(1)
class QMI8658(object):
def __init__(self,address=0X6B):
self._address = address
self._bus = I2C(id=1,scl=Pin(I2C_SDL),sda=Pin(I2C_SDA),freq=100_000)
bRet=self.WhoAmI()
if bRet :
self.Read_Revision()
else :
return NULL
self.Config_apply()
def _read_byte(self,cmd):
rec=self._bus.readfrom_mem(int(self._address),int(cmd),1)
return rec[0]
def _read_block(self, reg, length=1):
rec=self._bus.readfrom_mem(int(self._address),int(reg),length)
return rec
def _read_u16(self,cmd):
LSB = self._bus.readfrom_mem(int(self._address),int(cmd),1)
MSB = self._bus.readfrom_mem(int(self._address),int(cmd)+1,1)
return (MSB[0] << 8) + LSB[0]
def _write_byte(self,cmd,val):
self._bus.writeto_mem(int(self._address),int(cmd),bytes([int(val)]))
def WhoAmI(self):
bRet=False
if (0x05) == self._read_byte(0x00):
bRet = True
return bRet
def Read_Revision(self):
return self._read_byte(0x01)
def Config_apply(self):
# REG CTRL1
self._write_byte(0x02,0x60)
# REG CTRL2 : QMI8658AccRange_8g and QMI8658AccOdr_1000Hz
self._write_byte(0x03,0x23)
# REG CTRL3 : QMI8658GyrRange_512dps and QMI8658GyrOdr_1000Hz
self._write_byte(0x04,0x53)
# REG CTRL4 : No
self._write_byte(0x05,0x00)
# REG CTRL5 : Enable Gyroscope And Accelerometer Low-Pass Filter
self._write_byte(0x06,0x11)
# REG CTRL6 : Disables Motion on Demand.
self._write_byte(0x07,0x00)
# REG CTRL7 : Enable Gyroscope And Accelerometer
self._write_byte(0x08,0x03)
def Read_Raw_XYZ(self):
xyz=[0,0,0,0,0,0]
raw_timestamp = self._read_block(0x30,3)
raw_acc_xyz=self._read_block(0x35,6)
raw_gyro_xyz=self._read_block(0x3b,6)
raw_xyz=self._read_block(0x35,12)
timestamp = (raw_timestamp[2]<<16)|(raw_timestamp[1]<<8)|(raw_timestamp[0])
for i in range(6):
# xyz[i]=(raw_acc_xyz[(i*2)+1]<<8)|(raw_acc_xyz[i*2])
# xyz[i+3]=(raw_gyro_xyz[((i+3)*2)+1]<<8)|(raw_gyro_xyz[(i+3)*2])
xyz[i] = (raw_xyz[(i*2)+1]<<8)|(raw_xyz[i*2])
if xyz[i] >= 32767:
xyz[i] = xyz[i]-65535
return xyz
def Read_XYZ(self):
xyz=[0,0,0,0,0,0]
raw_xyz=self.Read_Raw_XYZ()
#QMI8658AccRange_8g
acc_lsb_div=(1<<12)
#QMI8658GyrRange_512dps
gyro_lsb_div = 64
for i in range(3):
xyz[i]=raw_xyz[i]/acc_lsb_div#(acc_lsb_div/1000.0)
xyz[i+3]=raw_xyz[i+3]*1.0/gyro_lsb_div
return xyz
def colour(R,G,B): # Convert RGB888 to RGB565
return (((G&0b00011100)<<3) +((B&0b11111000)>>3)<<8) + (R&0b11111000)+((G&0b11100000)>>5)
LCD = LCD_1inch28() #=============== Initialise the display ===================
LCD.set_bl_pwm(65535) # Brightness
#qmi8658=QMI8658() # Initialise gyro accl
#Vbat= ADC(Pin(Vbat_Pin)) # Lipo voltage pin
# ========== Start of Triangles code =============
# Modified from https://github.com/SpiderMaf/PiPicoDsply/blob/main/filled-triangles.py
# To work on WaveShare Pi Pico displays
# ========== Version 2 FIXED ! 23 May 2022 ==========
class Point:
def __init__(self,x,y):
self.X=x
self.Y=y
def __str__(self):
return "Point(%s,%s)"%(self.X,self.Y)
class Triangle:
def __init__(self,p1,p2,p3):
self.P1=p1
self.P2=p2
self.P3=p3
def __str__(self):
return "Triangle(%s,%s,%s)"%(self.P1,self.P2,self.P3)
def draw(self):
print("I should draw now")
self.fillTri()
# Filled triangle routines ported from http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html
def sortVerticesAscendingByY(self):
if self.P1.Y > self.P2.Y:
vTmp = self.P1
self.P1 = self.P2
self.P2 = vTmp
if self.P1.Y > self.P3.Y:
vTmp = self.P1
self.P1 = self.P3
self.P3 = vTmp
if self.P2.Y > self.P3.Y:
vTmp = self.P2
self.P2 = self.P3
self.P3 = vTmp
def fillTri(self):
self.sortVerticesAscendingByY()
if self.P2.Y == self.P3.Y:
fillBottomFlatTriangle(self.P1, self.P2, self.P3)
else:
if self.P1.Y == self.P2.Y:
fillTopFlatTriangle(self.P1, self.P2, self.P3)
else:
newx = int(self.P1.X + (float(self.P2.Y - self.P1.Y) / float(self.P3.Y - self.P1.Y)) * (self.P3.X - self.P1.X))
newy = self.P2.Y
pTmp = Point( newx,newy )
# print(pTmp)
fillBottomFlatTriangle(self.P1, self.P2, pTmp)
fillTopFlatTriangle(self.P2, pTmp, self.P3)
def fillBottomFlatTriangle(p1,p2,p3):
# print("BF",p1,p2,p3)
if p2.Y > p3.Y:
ty = p3.Y
p3.Y = p2.Y
p2.Y = ty
tx = p3.X
p3.X = p2.X
p2.X = tx
print(p1,p2,p3)
slope1 = float(p2.X - p1.X) / float (p2.Y - p1.Y)
slope2 = float(p3.X - p1.X) / float (p3.Y - p1.Y)
x1 = p1.X
x2 = p1.X + 0.5
# print("B",p1.Y,p2.Y)
for scanlineY in range(p1.Y,p2.Y):
# print(scanlineY)
# LCD.pixel_span(int(x1), scanlineY, int(x2)-int(x1)) # Switch pixel_span() to hline() / Pimoroni to WS
LCD.hline(int(x1),scanlineY, int(x2)-int(x1),c)
LCD.hline(int(x2),scanlineY, -(int(x2)-int(x1)),c)
# LCD.show() # Here and below
# utime.sleep(0.1) # <===== Uncomment to see how graphic elements are drawn
x1 += slope1
x2 += slope2
# LCD.show() # LCD.show() and utime.sleep(0.1)
def fillTopFlatTriangle(p1,p2,p3):
# print("TF",p1,p2,p3)
slope1 = float(p3.X - p1.X) / float(p3.Y - p1.Y)
slope2 = float(p3.X - p2.X) / float(p3.Y - p2.Y)
x1 = p3.X
x2 = p3.X + 0.5
# print("T",p3.Y,p1.Y-1)
for scanlineY in range (p3.Y,p1.Y-1,-1):
# print(scanlineY)
# LCD.pixel_span(int(x1), scanlineY, int(x2)-int(x1)) # Switch pixel_span() to hline() / Pimoroni to WS
LCD.hline(int(x1),scanlineY, int(x2)-int(x1)+1,c)
LCD.hline(int(x2),scanlineY, -(int(x2)-int(x1)-1),c)
# LCD.show()
# utime.sleep(0.1)
x1 -= slope1
x2 -= slope2
# LCD.show()
# ============== End of Triangles Code ===============
# =========== New GFX Routines ============
def clear(c):
LCD.fill(c)
def triangle(x1,y1,x2,y2,x3,y3,c): # Draw outline triangle
LCD.line(x1,y1,x2,y2,c)
LCD.line(x2,y2,x3,y3,c)
LCD.line(x3,y3,x1,y1,c)
def tri_filled(x1,y1,x2,y2,x3,y3,c): # Draw filled triangle
t=Triangle(Point(x1,y1),Point(x2,y2),Point(x3,y3)) # Define corners
t.fillTri() # Call main code block
def circle(x,y,r,c):
LCD.hline(x-r,y,r*2,c)
for i in range(1,r):
a = int(math.sqrt(r*r-i*i)) # Pythagoras!
LCD.hline(x-a,y+i,a*2,c) # Lower half
LCD.hline(x-a,y-i,a*2,c) # Upper half
def ring(x,y,r,c):
LCD.pixel(x-r,y,c)
LCD.pixel(x+r,y,c)
LCD.pixel(x,y-r,c)
LCD.pixel(x,y+r,c)
for i in range(1,r):
a = int(math.sqrt(r*r-i*i))
LCD.pixel(x-a,y-i,c)
LCD.pixel(x+a,y-i,c)
LCD.pixel(x-a,y+i,c)
LCD.pixel(x+a,y+i,c)
LCD.pixel(x-i,y-a,c)
LCD.pixel(x+i,y-a,c)
LCD.pixel(x-i,y+a,c)
LCD.pixel(x+i,y+a,c)
# ===========Start of FONTS Section=========================
# Standard ASCII 5x8 font
# https://gist.github.com/tdicola/229b3eeddc12d58fb0bc724a9062aa05
FONT_HEIGHT = 8
FONT_WIDTH = 5
FONT = bytes([
0x00, 0x00, 0x00, 0x00, 0x00, # <space>
0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
0x18, 0x3C, 0x7E, 0x3C, 0x18,
0x1C, 0x57, 0x7D, 0x57, 0x1C,
0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
0x00, 0x18, 0x3C, 0x18, 0x00,
0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
0x00, 0x18, 0x24, 0x18, 0x00,
0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
0x30, 0x48, 0x3A, 0x06, 0x0E,
0x26, 0x29, 0x79, 0x29, 0x26,
0x40, 0x7F, 0x05, 0x05, 0x07,
0x40, 0x7F, 0x05, 0x25, 0x3F,
0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
0x7F, 0x3E, 0x1C, 0x1C, 0x08,
0x08, 0x1C, 0x1C, 0x3E, 0x7F,
0x14, 0x22, 0x7F, 0x22, 0x14,
0x5F, 0x5F, 0x00, 0x5F, 0x5F,
0x06, 0x09, 0x7F, 0x01, 0x7F,
0x00, 0x66, 0x89, 0x95, 0x6A,
0x60, 0x60, 0x60, 0x60, 0x60,
0x94, 0xA2, 0xFF, 0xA2, 0x94,
0x08, 0x04, 0x7E, 0x04, 0x08, # UP
0x10, 0x20, 0x7E, 0x20, 0x10, # Down
0x08, 0x08, 0x2A, 0x1C, 0x08, # Right
0x08, 0x1C, 0x2A, 0x08, 0x08, # Left
0x1E, 0x10, 0x10, 0x10, 0x10,
0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
0x30, 0x38, 0x3E, 0x38, 0x30,
0x06, 0x0E, 0x3E, 0x0E, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14,
0x24, 0x2A, 0x7F, 0x2A, 0x12,
0x23, 0x13, 0x08, 0x64, 0x62,
0x36, 0x49, 0x56, 0x20, 0x50,
0x00, 0x08, 0x07, 0x03, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
0x08, 0x08, 0x3E, 0x08, 0x08,
0x00, 0x80, 0x70, 0x30, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x60, 0x60, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02,
0x3E, 0x51, 0x49, 0x45, 0x3E,
0x00, 0x42, 0x7F, 0x40, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46,
0x21, 0x41, 0x49, 0x4D, 0x33,
0x18, 0x14, 0x12, 0x7F, 0x10,
0x27, 0x45, 0x45, 0x45, 0x39,
0x3C, 0x4A, 0x49, 0x49, 0x31,
0x41, 0x21, 0x11, 0x09, 0x07,
0x36, 0x49, 0x49, 0x49, 0x36,
0x46, 0x49, 0x49, 0x29, 0x1E,
0x00, 0x00, 0x14, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41,
0x14, 0x14, 0x14, 0x14, 0x14,
0x00, 0x41, 0x22, 0x14, 0x08,
0x02, 0x01, 0x59, 0x09, 0x06,
0x3E, 0x41, 0x5D, 0x59, 0x4E,
0x7C, 0x12, 0x11, 0x12, 0x7C, # A
0x7F, 0x49, 0x49, 0x49, 0x36,
0x3E, 0x41, 0x41, 0x41, 0x22,
0x7F, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x49, 0x49, 0x49, 0x41,
0x7F, 0x09, 0x09, 0x09, 0x01,
0x3E, 0x41, 0x41, 0x51, 0x73,
0x7F, 0x08, 0x08, 0x08, 0x7F,
0x00, 0x41, 0x7F, 0x41, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01,
0x7F, 0x08, 0x14, 0x22, 0x41,
0x7F, 0x40, 0x40, 0x40, 0x40,
0x7F, 0x02, 0x1C, 0x02, 0x7F,
0x7F, 0x04, 0x08, 0x10, 0x7F,
0x3E, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x09, 0x09, 0x09, 0x06,
0x3E, 0x41, 0x51, 0x21, 0x5E,
0x7F, 0x09, 0x19, 0x29, 0x46,
0x26, 0x49, 0x49, 0x49, 0x32,
0x03, 0x01, 0x7F, 0x01, 0x03,
0x3F, 0x40, 0x40, 0x40, 0x3F,
0x1F, 0x20, 0x40, 0x20, 0x1F,
0x3F, 0x40, 0x38, 0x40, 0x3F,
0x63, 0x14, 0x08, 0x14, 0x63,
0x03, 0x04, 0x78, 0x04, 0x03,
0x61, 0x59, 0x49, 0x4D, 0x43,
0x00, 0x7F, 0x41, 0x41, 0x41,
0x02, 0x04, 0x08, 0x10, 0x20,
0x00, 0x41, 0x41, 0x41, 0x7F,
0x04, 0x02, 0x01, 0x02, 0x04,
0x40, 0x40, 0x40, 0x40, 0x40,
0x00, 0x03, 0x07, 0x08, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40,
0x7F, 0x28, 0x44, 0x44, 0x38,
0x38, 0x44, 0x44, 0x44, 0x28,
0x38, 0x44, 0x44, 0x28, 0x7F,
0x38, 0x54, 0x54, 0x54, 0x18,
0x00, 0x08, 0x7E, 0x09, 0x02,
0x18, 0xA4, 0xA4, 0x9C, 0x78,
0x7F, 0x08, 0x04, 0x04, 0x78,
0x00, 0x44, 0x7D, 0x40, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78,
0x7C, 0x08, 0x04, 0x04, 0x78,
0x38, 0x44, 0x44, 0x44, 0x38,
0xFC, 0x18, 0x24, 0x24, 0x18,
0x18, 0x24, 0x24, 0x18, 0xFC,
0x7C, 0x08, 0x04, 0x04, 0x08,
0x48, 0x54, 0x54, 0x54, 0x24,
0x04, 0x04, 0x3F, 0x44, 0x24,
0x3C, 0x40, 0x40, 0x20, 0x7C,
0x1C, 0x20, 0x40, 0x20, 0x1C,
0x3C, 0x40, 0x30, 0x40, 0x3C,
0x44, 0x28, 0x10, 0x28, 0x44,
0x4C, 0x90, 0x90, 0x90, 0x7C,
0x44, 0x64, 0x54, 0x4C, 0x44,
0x00, 0x08, 0x36, 0x41, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02,
0x3C, 0x26, 0x23, 0x26, 0x3C,
0x1E, 0xA1, 0xA1, 0x61, 0x12, # Extension starts here
0x3A, 0x40, 0x40, 0x20, 0x7A,
0x38, 0x54, 0x54, 0x55, 0x59,
0x21, 0x55, 0x55, 0x79, 0x41,
0x22, 0x54, 0x54, 0x78, 0x42, # a-umlaut
0x21, 0x55, 0x54, 0x78, 0x40,
0x20, 0x54, 0x55, 0x79, 0x40,
0x0C, 0x1E, 0x52, 0x72, 0x12,
0x39, 0x55, 0x55, 0x55, 0x59,
0x39, 0x54, 0x54, 0x54, 0x59,
0x39, 0x55, 0x54, 0x54, 0x58,
0x00, 0x00, 0x45, 0x7C, 0x41,
0x00, 0x02, 0x45, 0x7D, 0x42,
0x00, 0x01, 0x45, 0x7C, 0x40,
0x7D, 0x12, 0x11, 0x12, 0x7D, # A-umlaut
0xF0, 0x28, 0x25, 0x28, 0xF0,
0x7C, 0x54, 0x55, 0x45, 0x00,
0x20, 0x54, 0x54, 0x7C, 0x54,
0x7C, 0x0A, 0x09, 0x7F, 0x49,
0x32, 0x49, 0x49, 0x49, 0x32,
0x3A, 0x44, 0x44, 0x44, 0x3A, # o-umlaut
0x32, 0x4A, 0x48, 0x48, 0x30,
0x3A, 0x41, 0x41, 0x21, 0x7A,
0x3A, 0x42, 0x40, 0x20, 0x78,
0x00, 0x9D, 0xA0, 0xA0, 0x7D,
0x3D, 0x42, 0x42, 0x42, 0x3D, # O-umlaut
0x3D, 0x40, 0x40, 0x40, 0x3D,
0x3C, 0x24, 0xFF, 0x24, 0x24,
0x48, 0x7E, 0x49, 0x43, 0x66,
0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
0xFF, 0x09, 0x29, 0xF6, 0x20,
0xC0, 0x88, 0x7E, 0x09, 0x03,
0x20, 0x54, 0x54, 0x79, 0x41,
0x00, 0x00, 0x44, 0x7D, 0x41,
0x30, 0x48, 0x48, 0x4A, 0x32,
0x38, 0x40, 0x40, 0x22, 0x7A,
0x00, 0x7A, 0x0A, 0x0A, 0x72,
0x7D, 0x0D, 0x19, 0x31, 0x7D,
0x26, 0x29, 0x29, 0x2F, 0x28,
0x26, 0x29, 0x29, 0x29, 0x26,
0x30, 0x48, 0x4D, 0x40, 0x20,
0x38, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x38,
0x2F, 0x10, 0xC8, 0xAC, 0xBA,
0x2F, 0x10, 0x28, 0x34, 0xFA,
0x00, 0x00, 0x7B, 0x00, 0x00,
0x08, 0x14, 0x2A, 0x14, 0x22,
0x22, 0x14, 0x2A, 0x14, 0x08,
0x55, 0x00, 0x55, 0x00, 0x55, # 176 (25% block) missing in old code
0xAA, 0x55, 0xAA, 0x55, 0xAA, # 50% block
0xFF, 0x55, 0xFF, 0x55, 0xFF, # 75% block
0x00, 0x00, 0x00, 0xFF, 0x00,
0x10, 0x10, 0x10, 0xFF, 0x00,
0x14, 0x14, 0x14, 0xFF, 0x00,
0x10, 0x10, 0xFF, 0x00, 0xFF,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x14, 0x14, 0x14, 0xFC, 0x00,
0x14, 0x14, 0xF7, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x14, 0x14, 0xF4, 0x04, 0xFC,
0x14, 0x14, 0x17, 0x10, 0x1F,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0x1F, 0x00,
0x10, 0x10, 0x10, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x1F, 0x10,
0x10, 0x10, 0x10, 0x1F, 0x10,
0x10, 0x10, 0x10, 0xF0, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0xFF, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x14,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x1F, 0x10, 0x17,
0x00, 0x00, 0xFC, 0x04, 0xF4,
0x14, 0x14, 0x17, 0x10, 0x17,
0x14, 0x14, 0xF4, 0x04, 0xF4,
0x00, 0x00, 0xFF, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0xF7, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x17, 0x14,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0xF4, 0x14,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x00, 0x00, 0x1F, 0x10, 0x1F,
0x00, 0x00, 0x00, 0x1F, 0x14,
0x00, 0x00, 0x00, 0xFC, 0x14,
0x00, 0x00, 0xF0, 0x10, 0xF0,
0x10, 0x10, 0xFF, 0x10, 0xFF,
0x14, 0x14, 0x14, 0xFF, 0x14,
0x10, 0x10, 0x10, 0x1F, 0x00,
0x00, 0x00, 0x00, 0xF0, 0x10,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x38, 0x44, 0x44, 0x38, 0x44, # alpha - Greek characters start here at 224
0xFC, 0x4A, 0x4A, 0x4A, 0x34, # sharp-s or beta
0x7E, 0x02, 0x02, 0x06, 0x06,
0x02, 0x7E, 0x02, 0x7E, 0x02, # pi
0x63, 0x55, 0x49, 0x41, 0x63,
0x38, 0x44, 0x44, 0x3C, 0x04,
0x40, 0x7E, 0x20, 0x1E, 0x20, # mu
0x06, 0x02, 0x7E, 0x02, 0x02,
0x99, 0xA5, 0xE7, 0xA5, 0x99,
0x1C, 0x2A, 0x49, 0x2A, 0x1C,
0x4C, 0x72, 0x01, 0x72, 0x4C, # omega
0x30, 0x4A, 0x4D, 0x4D, 0x30,
0x30, 0x48, 0x78, 0x48, 0x30,
0xBC, 0x62, 0x5A, 0x46, 0x3D,
0x3E, 0x49, 0x49, 0x49, 0x00,
0x7E, 0x01, 0x01, 0x01, 0x7E, # End of Greek chars
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, # equivalent to 240
0x44, 0x44, 0x5F, 0x44, 0x44, # + or -
0x40, 0x51, 0x4A, 0x44, 0x40, # >=
0x40, 0x44, 0x4A, 0x51, 0x40, # <=
0x00, 0x00, 0xFF, 0x01, 0x03, # top of integral
0xE0, 0x80, 0xFF, 0x00, 0x00, # bottom of integral
0x08, 0x08, 0x6B, 0x6B, 0x08,
0x36, 0x12, 0x36, 0x24, 0x36, # approximately
0x06, 0x0F, 0x09, 0x0F, 0x06, # Degree
0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x00, 0x10, 0x10, 0x00,
0x30, 0x40, 0xFF, 0x01, 0x01, # sq root
0x00, 0x1F, 0x01, 0x01, 0x1E, # n superscript
0x00, 0x19, 0x1D, 0x17, 0x12, # squared (^2)
0x00, 0x3C, 0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00 # 255 also a <space>
])
def character(asc,xt,yt,sz,r,g,b): # Single character sz is size: 1 or 2
cc = colour(r,g,b)
code = asc * 5 # 5 bytes per character
for ii in range(5):
line = FONT[code + ii]
for yy in range(8):
if (line >> yy) & 0x1:
LCD.pixel(ii*sz+xt,yy*sz+yt,cc)
if sz > 1:
LCD.pixel(ii*sz+xt+1,yy*sz+yt,cc)
LCD.pixel(ii*sz+xt,yy*sz+yt+1,cc)
LCD.pixel(ii*sz+xt+1,yy*sz+yt+1,cc)
if sz == 3:
LCD.pixel(ii*sz+xt, yy*sz+yt+2,cc)
LCD.pixel(ii*sz+xt+1,yy*sz+yt+2,cc)
LCD.pixel(ii*sz+xt+2,yy*sz+yt+2,cc)
LCD.pixel(ii*sz+xt+2,yy*sz+yt,cc)
LCD.pixel(ii*sz+xt+2,yy*sz+yt+1,cc)
def prnt_st(asci,xx,yy,sz,r,g,b): # Text string
if sz == 1: move = 6
if sz == 2: move = 11
if sz == 3: move = 17
for letter in(asci):
asci = ord(letter)
character(asci,xx,yy,sz,r,g,b)
xx = xx + move
def cntr_st(s,y,sz,r,g,b): # Centres text on line y
if sz == 1: w = 6
if sz == 2: w = 11
if sz == 3: w = 17
gap = int((width - len(s) * w)/2)
prnt_st(s,gap,y,sz,r,g,b)
# =========== End of font support routines ===========
# ==== Board now setup ========== MAIN BELOW====================
def end_point(theta, rr): # Calculate end of hand offsets
theta_rad = math.radians(theta)
theta_rad = math.radians(theta)
xx = int(rr * math.sin(theta_rad))
yy = -int(rr * math.cos(theta_rad))
return xx,yy
adcpin = 4
sensor = machine.ADC(adcpin)
def ReadTemperature():
adc_value = sensor.read_u16()
volt = (3.3/65535) * adc_value
temperature = 27 - (volt - 0.706)/0.001721
return round(temperature, 1)
# https://youtu.be/X6PRcno_WbQ
clear(0) # Clear the screen
xc = 120 # Coordinates of centre
yc = 120
# === Main loop ===
while True:
circle(xc,yc,120,colour(255,0,0)) # Large blue circle
r = 120 # Tick outer radius - longer radius to stick out by 2 pixels
# Draw the scale ticks - lines from centre
for p in range(0,360,30):
hxn, hyn = end_point(p, r)
LCD.line(120,120,120+hxn,120+hyn,colour(255,255,255))
# Clear centre leaving blue ring with white ticks
circle(xc,yc,100,colour(0,0,0))
# Clear centre circle
circle(xc,yc,102,colour(0,0,0))
# Write Title and Scale values
cntr_st("Temperature",78,1,255,255,255) # Message
prnt_st("0",60,180,2,255,255,255)
prnt_st("100",150,180,2,255,255,255)
prnt_st("10",30,140,2,255,255,255)
prnt_st("90",193,140,2,255,255,255)
prnt_st("20",24,98,2,255,255,255)
prnt_st("80",195,98,2,255,255,255)
prnt_st("30",43,62,2,255,255,255)
prnt_st("70",176,62,2,255,255,255)
prnt_st("40",70,35,2,255,255,255)
prnt_st("60",147,35,2,255,255,255)
prnt_st("50",110,25,2,255,255,255)
temp = round((ReadTemperature() * 9/5) + 32)
cntr_st(str(temp),145,3,255,255,0)
theta = p * 2.7 - 45 # Angle of pointer. Zero is left horizontal
# Calculate coordinates of end of pointer
theta = temp * 2.7 - 45
theta_rad = math.radians(theta)
theta_rad = math.radians(theta)
yn = -int(r * math.sin(theta_rad))
xn = -int(r * math.cos(theta_rad))
xnsm = int(xn/10)
ynsm = int(yn/10)
# Draw new pointer in red
c = colour(255,255,255)
tri_filled(r+xn, r+yn, r+ynsm, r-xnsm, r-ynsm, r+xnsm,c)
circle(xc,yc,10,colour(255,255,255))
LCD.show() # Update screen
time.sleep(0.05) # Short delay
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment