from machine import Pin, I2C, ADC, PWM
import framebuf
import time
# ------------------- OLED 驱动 -------------------
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xA4)
SET_NORM_INV = const(0xA6)
SET_DISP = const(0xAE)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xA0)
SET_MUX_RATIO = const(0xA8)
SET_COM_OUT_DIR = const(0xC0)
SET_DISP_OFFSET = const(0xD3)
SET_COM_PIN_CFG = const(0xDA)
SET_DISP_CLK_DIV = const(0xD5)
SET_PRECHARGE = const(0xD9)
SET_VCOM_DESEL = const(0xDB)
SET_CHARGE_PUMP = const(0x8D)
class SSD1306(framebuf.FrameBuffer):
def __init__(self, width, height, external_vcc):
self.width = width
self.height = height
self.external_vcc = external_vcc
self.pages = self.height // 8
self.buffer = bytearray(self.pages * self.width)
super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
self.init_display()
def init_display(self):
for cmd in (
SET_DISP | 0x00,
SET_MEM_ADDR, 0x00,
SET_DISP_START_LINE | 0x00,
SET_SEG_REMAP | 0x01,
SET_MUX_RATIO, self.height - 1,
SET_COM_OUT_DIR | 0x08,
SET_DISP_OFFSET, 0x00,
SET_COM_PIN_CFG, 0x02 if self.height <= 32 else 0x12,
SET_DISP_CLK_DIV, 0x80,
SET_PRECHARGE, 0x22 if self.external_vcc else 0xF1,
SET_VCOM_DESEL, 0x30,
SET_CONTRAST, 0xFF,
SET_ENTIRE_ON,
SET_NORM_INV,
SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
SET_DISP | 0x01
):
self.write_cmd(cmd)
self.fill(0)
self.show()
def write_cmd(self, cmd): pass
def write_data(self, buf): pass
def show(self): pass
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False):
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.temp[0] = 0x80
self.temp[1] = cmd
self.i2c.writeto(self.addr, self.temp)
def write_data(self, buf):
self.i2c.writevto(self.addr, [b"\x40", buf])
def show(self):
self.write_cmd(SET_COL_ADDR)
self.write_cmd(0)
self.write_cmd(self.width - 1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_data(self.buffer)
# ------------------- 硬件初始化(和你接线完全对应) -------------------
sw_up = Pin(23, Pin.IN, Pin.PULL_UP)
sw_right = Pin(19, Pin.IN, Pin.PULL_UP)
sw_down = Pin(18, Pin.IN, Pin.PULL_UP)
sw_left = Pin(5, Pin.IN, Pin.PULL_UP)
buzzer = PWM(Pin(27), freq=1000, duty=0)
ldr = ADC(Pin(34))
ldr.atten(ADC.ATTN_11DB)
i2c = I2C(0, sda=Pin(21), scl=Pin(22), freq=400000)
oled = SSD1306_I2C(128, 64, i2c)
# ------------------- 全局变量 -------------------
h, m, s = 11, 1, 48
temp_offset = 0
set_mode = 0
screen_rot = 0
# ------------------- 蜂鸣器提示音 -------------------
def beep(freq=1000, duration=100):
buzzer.freq(freq)
buzzer.duty(512)
time.sleep_ms(duration)
buzzer.duty(0)
def beep_ok():
beep(1500, 100)
time.sleep_ms(100)
beep(2000, 100)
# ------------------- 按键消抖检测 -------------------
def key_pressed(pin):
if pin.value() == 0:
time.sleep_ms(50)
if pin.value() == 0:
while pin.value() == 0:
pass
beep()
return True
return False
# ------------------- OLED显示更新(加了模式提示) -------------------
def display():
oled.fill(0)
# 显示模式提示
mode_text = ["Normal", "Set Hour", "Set Min", "Set Temp"]
oled.text(mode_text[set_mode], 0, 0)
if screen_rot == 0:
oled.text(f"{h:02d}:{m:02d}:{s:02d}", 20, 25)
oled.text(f"Temp: {25+temp_offset:.1f}C", 30, 50)
elif screen_rot == 1:
oled.text(f"{h:02d}:{m:02d}:{s:02d}", 60, 10)
oled.text(f"Temp: {25+temp_offset:.1f}C", 70, 30)
elif screen_rot == 2:
oled.text(f"{h:02d}:{m:02d}:{s:02d}", 20, 25)
oled.text(f"Temp: {25+temp_offset:.1f}C", 30, 40)
elif screen_rot == 3:
oled.text(f"{h:02d}:{m:02d}:{s:02d}", 10, 20)
oled.text(f"Temp: {25+temp_offset:.1f}C", 20, 40)
oled.show()
# ------------------- 按键逻辑处理 -------------------
def handle_keys():
global set_mode, screen_rot, h, m, temp_offset
if key_pressed(sw_up):
screen_rot = (screen_rot + 1) % 4
if key_pressed(sw_right):
set_mode = (set_mode + 1) % 4
if key_pressed(sw_down):
if set_mode == 1:
h = (h + 1) % 24
elif set_mode == 2:
m = (m + 1) % 60
elif set_mode == 3:
temp_offset = max(-10, min(10, temp_offset + 1))
if key_pressed(sw_left):
if set_mode == 1:
h = (h - 1) % 24
elif set_mode == 2:
m = (m - 1) % 60
elif set_mode == 3:
temp_offset = max(-10, min(10, temp_offset - 1))
# ------------------- 主循环 -------------------
beep_ok()
display()
while True:
handle_keys()
display()
s += 1
if s >= 60:
s = 0
m += 1
if m >= 60:
m = 0
h += 1
if h >= 24:
h = 0
time.sleep(1)Loading
esp32-devkit-c-v4
esp32-devkit-c-v4