# Simpele ILI9341 TFT driver voor Wokwi
# Gebaseerd op micropython-ili9341 library
import machine
import time
from machine import Pin, SPI
# ILI9341 commands
ILI9341_SWRESET = 0x01
ILI9341_SLPOUT = 0x11
ILI9341_DISPON = 0x29
ILI9341_CASET = 0x2A
ILI9341_PASET = 0x2B
ILI9341_RAMWR = 0x2C
ILI9341_MADCTL = 0x36
ILI9341_COLMOD = 0x3A
# Colors (RGB565)
BLACK = 0x0000
WHITE = 0xFFFF
RED = 0xF800
GREEN = 0x07E0
BLUE = 0x001F
YELLOW = 0xFFE0
ORANGE = 0xFD20
CYAN = 0x07FF
MAGENTA = 0xF81F
class ILI9341:
def __init__(self, spi, cs, dc, rst=None):
self.spi = spi
self.cs = cs
self.dc = dc
self.rst = rst
self.width = 320 # Terug naar origineel
self.height = 240
self.cs.init(Pin.OUT, value=1)
self.dc.init(Pin.OUT, value=0)
if self.rst:
self.rst.init(Pin.OUT, value=1)
self.init_display()
def write_cmd(self, cmd):
"""Write command"""
self.cs(0)
self.dc(0)
self.spi.write(bytearray([cmd]))
self.cs(1)
def write_data(self, data):
"""Write data"""
self.cs(0)
self.dc(1)
if isinstance(data, int):
data = bytearray([data])
self.spi.write(data)
self.cs(1)
def init_display(self):
"""Initialize ILI9341"""
if self.rst:
self.rst(0)
time.sleep_ms(10)
self.rst(1)
time.sleep_ms(10)
# Software reset
self.write_cmd(ILI9341_SWRESET)
time.sleep_ms(150)
# Sleep out
self.write_cmd(ILI9341_SLPOUT)
time.sleep_ms(120)
# Pixel format
self.write_cmd(ILI9341_COLMOD)
self.write_data(0x55) # 16-bit
# Memory access control
self.write_cmd(ILI9341_MADCTL)
self.write_data(0x48) # Rotation
# Display on
self.write_cmd(ILI9341_DISPON)
time.sleep_ms(10)
print("ILI9341 geïnitialiseerd")
def set_window(self, x0, y0, x1, y1):
"""Set drawing window"""
# Column address
self.write_cmd(ILI9341_CASET)
self.write_data(bytearray([x0 >> 8, x0 & 0xFF, x1 >> 8, x1 & 0xFF]))
# Page address
self.write_cmd(ILI9341_PASET)
self.write_data(bytearray([y0 >> 8, y0 & 0xFF, y1 >> 8, y1 & 0xFF]))
# Memory write
self.write_cmd(ILI9341_RAMWR)
def fill_screen(self, color):
"""Fill entire screen with color"""
self.set_window(0, 0, self.width-1, self.height-1)
# Convert color to bytes
color_bytes = bytearray([color >> 8, color & 0xFF])
self.cs(0)
self.dc(1)
for _ in range(self.width * self.height):
self.spi.write(color_bytes)
self.cs(1)
def fill_rect(self, x, y, w, h, color):
"""Fill rectangle with color"""
if x + w > self.width or y + h > self.height:
return
self.set_window(x, y, x + w - 1, y + h - 1)
color_bytes = bytearray([color >> 8, color & 0xFF])
self.cs(0)
self.dc(1)
for _ in range(w * h):
self.spi.write(color_bytes)
self.cs(1)
def draw_pixel(self, x, y, color):
"""Draw single pixel"""
if x >= self.width or y >= self.height:
return
self.set_window(x, y, x, y)
color_bytes = bytearray([color >> 8, color & 0xFF])
self.cs(0)
self.dc(1)
self.spi.write(color_bytes)
self.cs(1)
def draw_circle_filled(self, x0, y0, r, color):
"""Draw filled circle"""
for y in range(-r, r + 1):
for x in range(-r, r + 1):
if x*x + y*y <= r*r:
self.draw_pixel(x0 + x, y0 + y, color)
# Virus Barometer met echte ILI9341 driver
class VirusBarometer:
def __init__(self):
# SPI en display setup - hogere baudrate
self.spi = SPI(1, baudrate=20000000, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
self.display = ILI9341(self.spi, cs=Pin(5), dc=Pin(2), rst=Pin(4))
# Virus data
self.virus_data = {
'covid': 2, # HOOG
'griep': 3, # ZEER HOOG
'rsv': 1, # MATIG
'last_update': '14:30'
}
# Kleuren
self.level_colors = [GREEN, YELLOW, ORANGE, RED]
self.level_names = ['LAAG', 'MATIG', 'HOOG', 'ZEER HOOG']
def update_display(self):
"""Cleane, simpele virus-barometer layout"""
print("Clean display update...")
# Clear screen
self.display.fill_screen(BLACK)
# Simpele indeling: 3 grote blokken naast elkaar
block_width = 100
block_height = 120
start_y = 60
# COVID blok (links)
covid_color = self.level_colors[self.virus_data['covid']]
self.display.fill_rect(10, start_y, block_width, block_height, covid_color)
# GRIEP blok (midden)
griep_color = self.level_colors[self.virus_data['griep']]
self.display.fill_rect(110, start_y, block_width, block_height, griep_color)
# RSV blok (rechts)
rsv_color = self.level_colors[self.virus_data['rsv']]
self.display.fill_rect(210, start_y, block_width, block_height, rsv_color)
# Kleine legenda onderaan - ver van elkaar
legend_y = 200
self.display.fill_rect(20, legend_y, 15, 15, GREEN) # LAAG
self.display.fill_rect(100, legend_y, 15, 15, YELLOW) # MATIG
self.display.fill_rect(180, legend_y, 15, 15, ORANGE) # HOOG
self.display.fill_rect(260, legend_y, 15, 15, RED) # ZEER HOOG
print("Clean layout voltooid!")
self.print_status()
def print_status(self):
"""Print status naar console"""
print("\n=== VIRUS BAROMETER STATUS ===")
print(f"COVID: {self.level_names[self.virus_data['covid']]}")
print(f"GRIEP: {self.level_names[self.virus_data['griep']]}")
print(f"RSV: {self.level_names[self.virus_data['rsv']]}")
print(f"Update: {self.virus_data['last_update']}")
print("==============================\n")
def simulate_data_change(self):
"""Simuleer data wijzigingen"""
import random
print("Data wijziging simulatie...")
self.virus_data['covid'] = random.randint(0, 3)
self.virus_data['griep'] = random.randint(0, 3)
self.virus_data['rsv'] = random.randint(0, 3)
# Update tijd
hour = time.localtime()[3]
minute = time.localtime()[4]
self.virus_data['last_update'] = f"{hour:02d}:{minute:02d}"
def run(self):
"""Hoofdloop"""
print("Virus Barometer gestart!")
# Initiële display
self.update_display()
# Demo loop
for i in range(10): # 10 updates
time.sleep(3) # Wacht 3 seconden
print(f"\n--- Update {i+1}/10 ---")
self.simulate_data_change()
self.update_display()
print("Demo voltooid!")
# Main programma
def main():
try:
barometer = VirusBarometer()
barometer.run()
except Exception as e:
print(f"Fout: {e}")
import sys
sys.print_exception(e)
if __name__ == "__main__":
main()