# Automatisk P-skive: Raspberry Pi Pico + DS3231 + MPU6050 + Waveshare Pico-ePaper-2.13
# Holder bilen stille i STILLE_SEK sekunder -> skærmen viser ankomsttid (rundet op).
# Bilen kører -> skærmen slukkes (hvid).
#
# Forbindelser:
# DS3231 og MPU6050 på I2C0: SDA = GP4, SCL = GP5, 3V3, GND (MPU6050 AD0 -> 3V3)
# Knap mellem GP14 og GND (skifter mellem 15 og 30 min. afrunding)
# e-paper: DIN=GP11, CLK=GP10, CS=GP9, DC=GP8, RST=GP12, BUSY=GP13, VCC=3V3, GND
#
# Waveshares driver: kopiér deres MicroPython-fil til Picoen som epd2in13.py.
# Er dit modul V3/V4, så ret klassenavnet i importen herunder.
import time
import framebuf
import machine
from machine import Pin, I2C
from epd2in13 import EPD_2in13_Landscape as EPD # <-- ret ved behov
DEBUG = True # True = almindelig sleep (USB virker), False = lightsleep (strømbesparelse)
STILLE_SEK = 60 # sekunder med ro før bilen regnes som parkeret
KOER_SAMPLES = 5 # antal bevægelser i træk før bilen regnes som kørende
TAERSKEL = 1500 # følsomhed for bevægelse (mindre = mere følsom)
interval = 30 # afrunding i minutter (knappen skifter 15/30)
i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=100000)
knap = Pin(14, Pin.IN, Pin.PULL_UP)
knap_trykket = False
def knap_irq(p):
global knap_trykket
knap_trykket = True
knap.irq(knap_irq, Pin.IRQ_FALLING)
# ---------- DS3231 ----------
def bcd(b): return (b >> 4) * 10 + (b & 0x0F)
def tobcd(n): return ((n // 10) << 4) | (n % 10)
def laes_rtc():
d = i2c.readfrom_mem(0x68, 0x00, 3)
return bcd(d[2] & 0x3F), bcd(d[1]), bcd(d[0] & 0x7F) # t, m, s
def saet_rtc(t, m, s=0):
i2c.writeto_mem(0x68, 0x00, bytes([tobcd(s), tobcd(m), tobcd(t)]))
# Sæt tiden én gang: saet_rtc(14, 30) og fjern linjen igen
# ---------- MPU6050 ----------
MPU = 0x69 # AD0 skal være forbundet til 3V3 (0x68 er DS3231)
LAV_STROM = True # True = kun accelerometer, lavt forbrug. Sæt False hvis værdierne er 0.
if LAV_STROM:
i2c.writeto_mem(MPU, 0x6B, b'\x28') # cycle-mode, temperatursensor fra
i2c.writeto_mem(MPU, 0x6C, b'\x07') # gyroskop i standby, 1,25 Hz
else:
i2c.writeto_mem(MPU, 0x6B, b'\x00') # væk fra sleep, alt aktivt
def accel():
d = i2c.readfrom_mem(MPU, 0x3B, 6)
def v(hi, lo):
x = (hi << 8) | lo
return x - 65536 if x > 32767 else x
return v(d[0], d[1]), v(d[2], d[3]), v(d[4], d[5])
def bevaegelse(forrige, nu):
return sum(abs(a - b) for a, b in zip(forrige, nu)) > TAERSKEL
# ---------- Skærm ----------
epd = EPD()
def stor_tekst(fb, tekst, x, y, s, farve=0x00):
w = 8 * len(tekst)
tmp = framebuf.FrameBuffer(bytearray(w), w, 8, framebuf.MONO_VLSB)
tmp.text(tekst, 0, 0, 1)
for xx in range(w):
for yy in range(8):
if tmp.pixel(xx, yy):
fb.fill_rect(x + xx * s, y + yy * s, s, s, farve)
def rund_op(t, m, trin):
total = -(-(t * 60 + m) // trin) * trin
total %= 1440
return total // 60, total % 60
def vis(t, m):
epd.init()
epd.fill(0xFF)
epd.text("P ANKOMST", 10, 8, 0x00)
stor_tekst(epd, "%02d:%02d" % (t, m), 5, 40, 6)
epd.display(epd.buffer)
epd.sleep()
def slukket():
epd.init()
epd.fill(0xFF)
epd.display(epd.buffer)
epd.sleep()
# ---------- Hovedløkke ----------
def pause(ms):
if DEBUG:
time.sleep_ms(ms)
else:
machine.lightsleep(ms)
parkeret = False
ankomst = None # (timer, minutter) rå ankomsttid
stille = 0
bev = 0
forrige = accel()
# Ved tænding: antag at bilen holder stille og vis tiden
t, m, _ = laes_rtc()
ankomst = (t, m)
vis(*rund_op(t, m, interval))
parkeret = True
while True:
pause(1000)
nu = accel()
bev_nu = bevaegelse(forrige, nu)
forrige = nu
if knap_trykket:
knap_trykket = False
interval = 15 if interval == 30 else 30
if parkeret and ankomst:
vis(*rund_op(ankomst[0], ankomst[1], interval))
if bev_nu:
bev += 1
stille = 0
else:
stille += 1
bev = 0
if parkeret and bev >= KOER_SAMPLES:
slukket()
parkeret = False
elif not parkeret and stille >= STILLE_SEK:
t, m, _ = laes_rtc()
ankomst = (t, m)
vis(*rund_op(t, m, interval))
parkeret = TrueLoading
epaper-2in9
epaper-2in9