kai — Raspberry Pi 5 simulation

An interactive Raspberry Pi 5 circuit simulation you can run free in your browser on Velxio, by tingop12345.

Components

Sketch code

import csv 
import os 
import subprocess 
import time 
from datetime import datetime 
from PIL import Image 
import spidev 
import RPi.GPIO as GPIO 
# ============================== 
# CAMERA 
# ============================== 
CAMERA_FILE = "/home/pi/face.jpg" 
ATTENDANCE_FILE = "/home/pi/attendance.csv" 
CAMERA_WIDTH = 320 
CAMERA_HEIGHT = 240 
# ถ้ากล้องไม่ติด ให้ลองถ่ายใหม่อัตโนมัติ 
CAMERA_MAX_TRIES = 8 
CAMERA_RETRY_DELAY = 1.0      
# วินาที 
CAMERA_TIMEOUT = 15           
# วินาทีต่อครั้ง 
# ============================== 
# STUDENT DATA 
# ============================== 
students = { 
"67122519010": "Student 1", 
"67122519031": "Student 2", 
"67122519038": "Student 3", 
"67122519040": "Student 4", 
"67122519046": "Student 5" 
} 
# ============================== 
# TFT ILI9341 (LANDSCAPE) 
# ============================== 
SPI_BUS = 0 
SPI_DEVICE = 0 
SPI_SPEED = 24000000 
TFT_DC = 25 
TFT_RST = 24 
TFT_WIDTH = 320 
TFT_HEIGHT = 240 
# 0x28 = landscape 
# 0xE8 = landscape หมุน 180 องศา 
# 0x68 = landscape กลับซ้าย-ขวา 
# 0xA8 = landscape กลับบน-ล่าง 
TFT_MADCTL = 0x28 
# แก้ปัญหา "รอบแรกจอไม่ขึ้นภาพ" 
TFT_DRAW_REPEAT = 2           
TFT_SETTLE_DELAY = 0.2        
# ส่งภาพซ้ำกี่ครั้งต่อการแสดงหนึ่งครั้ง 
# วินาที รอหลังตั้งค่าจอก่อนส่งภาพ 
# ============================== 
# KEYPAD 4x4 
# ============================== 
KEYPAD_ROWS = [4, 17, 27, 22] 
KEYPAD_COLS = [5, 6, 13, 26] 
KEYPAD_KEYS = [ 
["1", "2", "3", "A"], 
["4", "5", "6", "B"], 
["7", "8", "9", "C"], 
["*", "0", "#", "D"] 
] 
# ============================== 
# TFT CLASS 
# ============================== 
class ILI9341: 
def __init__(self): 
GPIO.setmode(GPIO.BCM) 
 
        GPIO.setup(TFT_DC, GPIO.OUT) 
        GPIO.setup(TFT_RST, GPIO.OUT) 
 
        self.spi = spidev.SpiDev() 
 
        self.spi.open(SPI_BUS, SPI_DEVICE) 
 
        self.spi.max_speed_hz = SPI_SPEED 
        self.spi.mode = 0 
 
        self.reset() 
        self.init_display() 
 
    def reset(self): 
 
        GPIO.output(TFT_RST, GPIO.HIGH) 
        time.sleep(0.05) 
 
        GPIO.output(TFT_RST, GPIO.LOW) 
        time.sleep(0.05) 
 
        GPIO.output(TFT_RST, GPIO.HIGH) 
        time.sleep(0.15) 
 
    def command(self, value): 
 
        GPIO.output(TFT_DC, GPIO.LOW) 
 
        self.spi.writebytes([value]) 
 
    def data(self, data): 
 
        GPIO.output(TFT_DC, GPIO.HIGH) 
 
        for i in range(0, len(data), 4096): 
 
            self.spi.writebytes( 
                data[i:i + 4096] 
            ) 
 
    def init_display(self): 
 
        self.command(0x01) 
        time.sleep(0.15) 
 
        self.command(0x28) 
 
        self.command(0x3A) 
        self.data([0x55]) 
 
        self.command(0x36) 
        self.data([TFT_MADCTL]) 
 
        self.command(0x11) 
        time.sleep(0.12) 
 
        self.command(0x29) 
        time.sleep(0.05) 
 
    def set_window(self, x0, y0, x1, y1): 
 
        self.command(0x2A) 
 
        self.data([ 
            (x0 >> 8) & 0xFF, 
            x0 & 0xFF,