from machine import Pin, I2C
import ssd1306
import dht
import _thread
import time
import random
# OLED 初始化
i2c = I2C(0, sda=Pin(6), scl=Pin(7), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# 键盘 初始化
P01 = Pin(8, Pin.IN, Pin.PULL_UP)
P02 = Pin(2, Pin.IN, Pin.PULL_UP)
P03 = Pin(9, Pin.IN, Pin.PULL_UP)
P04 = Pin(3, Pin.IN, Pin.PULL_UP)
P05 = Pin(4, Pin.IN, Pin.PULL_UP)
P06 = Pin(5, Pin.IN, Pin.PULL_UP)
# 按键防抖
def pressed(pin):
if pin.value() == 0:
time.sleep_ms(10)
if pin.value() == 0:
return True
return False
# 硬件引脚固定
dht_sensor = dht.DHT22(Pin(10))
buzzer = Pin(20, Pin.OUT)
buzzer.value(0)
time.sleep(1)
# 全局时钟变量
Clock_s = 0
Clock_d = 0
Clock_s_final = 0
Clock_m_final = 0
Clock_h_final = 0
# 全局温湿度计变量
temp = 0
humi = 0
# ==================== 贪吃蛇函数(主线程运行) ====================
def snake_game():
# 限定游戏区域
gx = 1
gy = 1
gw = 86
gh = 63
snake = [[30,30],[20,30],[10,30]]
dx = 10
dy = 0
game_exit = False
# 生成食物
def new_food():
while True:
x = random.randint(gx+10, gx+gw-10)//10*10
y = random.randint(gy+10, gy+gh-10)//10*10
if [x,y] not in snake:
return [x,y]
food = new_food()
while not game_exit:
oled.fill(0)
oled.rect(gx, gy, gw, gh, 1)
# P03 退出游戏
if pressed(P03):
game_exit = True
break
# 方向按键:上2 下5 左4 右6
if pressed(P02) and dy != 10:
dx, dy = 0, -10
if pressed(P05) and dy != -10:
dx, dy = 0, 10
if pressed(P04) and dx != 10:
dx, dy = -10, 0
if pressed(P06) and dx != -10:
dx, dy = 10, 0
# 蛇头
head = [snake[0][0]+dx, snake[0][1]+dy]
# 撞墙撞身
if head[0]<=gx or head[0]>=gx+gw or head[1]<=gy or head[1]>=gy+gh or head in snake:
oled.text("GAME OVER",22,28)
oled.show()
time.sleep(1)
break
snake.insert(0,head)
if head == food:
food = new_food()
else:
snake.pop()
# 绘制
for pos in snake:
oled.fill_rect(pos[0],pos[1],8,8,1)
oled.fill_rect(food[0],food[1],8,8,1)
oled.show()
time.sleep(1)
# ==================================================================
# 线程1:时钟计时
def task1():
global Clock_s, Clock_d, Clock_s_final, Clock_m_final, Clock_h_final
while True:
Clock_s += 1
time.sleep(1)
Clock_h_final = Clock_s // 3600
clock_s = Clock_s % 3600
Clock_m_final = clock_s // 60
Clock_s_final = clock_s % 60
if Clock_h_final == 24:
Clock_d += 1
Clock_s = 0
# 线程2:按键检测
def task2():
while True:
time.sleep_ms(100)
if pressed(P01):
snake_game() # P01按下启动贪吃蛇(主线程运行)
print(1)
if pressed(P02):
print(2)
if pressed(P03):
print(3)
if pressed(P04):
print(4)
if pressed(P05):
print(5)
if pressed(P06):
print(6)
time.sleep_ms(30)
# 线程3:DHT22温湿度计
def task3():
global temp, humi
while True:
time.sleep_ms(200)
try:
dht_sensor.measure()
temp = dht_sensor.temperature()
humi = dht_sensor.humidity()
except Exception:
pass
time.sleep(2)
# 线程4:预留空闲
def task4():
while True:
time.sleep(1)
# 线程5:预留空闲
def task5():
while True:
time.sleep(2)
# 仅启动5个线程
_thread.start_new_thread(task1, ())
_thread.start_new_thread(task2, ())
_thread.start_new_thread(task3, ())
_thread.start_new_thread(task4, ())
_thread.start_new_thread(task5, ())
# 主线程OLED正常显示
while True:
oled.fill(0)
oled.rect(0, 0, 128, 64, 1)
oled.rect(0, 0, 87, 64, 1)
oled.rect(86, 0, 128, 11, 1)
oled.text(f"{Clock_h_final:02d}:{Clock_m_final:02d}", 87, 2)
oled.rect(86, 10, 128, 11, 1)
oled.text(f"{temp}C", 87, 12)
oled.rect(86, 10, 128, 21, 1)
oled.text(f"{humi}%", 87, 22)
oled.show()
time.sleep_ms(50)Loading
xiao-esp32-c3
xiao-esp32-c3