from machine import Pin, I2C, ADC, PWM, Timer
import ssd1306
import dht
import time
# 硬件初始化
i2c = I2C(scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
dht22 = dht.DHT22(Pin(15))
pir = Pin(13, Pin.IN)
button = Pin(5, Pin.IN, Pin.PULL_UP)
# RGB LED引脚
rgb_r = PWM(Pin(14), freq=1000)
rgb_g = PWM(Pin(27), freq=1000)
rgb_b = PWM(Pin(26), freq=1000)
# 光敏传感器参数
LIGHT_SENSOR = ADC(Pin(34)) # GPIO34是ADC输入引脚
GAMMA = 0.7 # 光敏电阻的伽马值
RL10 = 50 # 10勒克斯时的电阻值(kΩ)
R1 = 10 # 分压电阻值(kΩ)
# 系统变量
auto_mode = True
led_state = 0 # 0=关, 1=红, 2=绿, 3=蓝
last_update = time.ticks_ms()
light_lux = 0 # 光照强度(lux)
light_percent = 0 # 光照强度百分比(0-100)
temperature = 0.0
humidity = 0.0
motion_detected = False
def read_light_sensor(timer=None):
"""读取光敏传感器并计算光照强度"""
global light_lux, light_percent
try:
# 读取ADC原始值 (0-4095)
adc_value = LIGHT_SENSOR.read()
# 计算光照强度百分比
light_percent = min(100, max(0, int(adc_value * 100 / 4095)))
# 转换为电压 (假设3.3V参考电压)
voltage = adc_value * 3.3 / 4095
# 计算光敏电阻的实际电阻值
if voltage > 0:
r_ldr = R1 * (3.3 - voltage) / voltage
else:
r_ldr = float('inf') # 避免除以零
# 计算光照强度(lux)
try:
light_lux = (RL10 * 1000 * pow(10, GAMMA) / r_ldr) ** (1 / GAMMA)
except (ZeroDivisionError, OverflowError):
light_lux = 0
except Exception as e:
print("光敏传感器读取错误:", e)
light_lux = 0
light_percent = 0
def read_sensors():
"""读取其他传感器数据"""
global temperature, humidity, motion_detected
try:
dht22.measure()
temperature = dht22.temperature()
humidity = dht22.humidity()
motion_detected = pir.value()
except Exception as e:
print("传感器读取错误:", e)
def set_rgb(r, g, b):
"""设置RGB LED颜色 (0-255)"""
rgb_r.duty(int(r * 1023 / 255)) # 转换为0-1023范围
rgb_g.duty(int(g * 1023 / 255))
rgb_b.duty(int(b * 1023 / 255))
# 更新LED状态
global led_state
if r > 0: led_state = 1
elif g > 0: led_state = 2
elif b > 0: led_state = 3
else: led_state = 0
def update_display():
"""更新OLED显示"""
oled.fill(0)
oled.text("Temp: {:.1f}C".format(temperature), 0, 0)
oled.text("Hum: {:.1f}%".format(humidity), 0, 10)
oled.text("Light: {}%".format(light_percent), 0, 20)
oled.text("Lux: {:.0f}".format(light_lux), 0, 30)
oled.text("Motion: {}".format("YES" if motion_detected else "NO"), 0, 40)
oled.text("Mode: {}".format("AUTO" if auto_mode else "MANUAL"), 0, 50)
led_text = "OFF"
if led_state == 1: led_text = "RED"
elif led_state == 2: led_text = "GREEN"
elif led_state == 3: led_text = "BLUE"
oled.text("LED: {}".format(led_text), 64, 50)
oled.show()
def print_to_console():
"""在控制台输出中文信息"""
print("\n" + "="*40)
print("智能家居监控系统 - 实时数据")
print("="*40)
print("温度: {:.1f}°C".format(temperature))
print("湿度: {:.1f}%".format(humidity))
print("光照强度: {}%".format(light_percent))
print("光照强度: {:.0f} lux".format(light_lux))
print("人体检测: {}".format("检测到人体" if motion_detected else "无人体"))
print("工作模式: {}".format("自动模式" if auto_mode else "手动模式"))
led_text = "关闭"
if led_state == 1: led_text = "红色"
elif led_state == 2: led_text = "绿色"
elif led_state == 3: led_text = "蓝色"
print("LED状态: {}".format(led_text))
print("="*40)
# 创建并启动光敏传感器定时器
light_timer = Timer(0)
light_timer.init(period=1000, mode=Timer.PERIODIC, callback=read_light_sensor)
# 系统启动
print("系统启动中...")
print("等待传感器初始化...")
oled.fill(0)
oled.text("系统启动中...", 0, 20)
oled.text("请稍候...", 0, 40)
oled.show()
time.sleep(2) # 给传感器初始化时间
# 初始读取一次光敏传感器
read_light_sensor()
try:
while True:
# 每2秒更新一次主传感器
if time.ticks_ms() - last_update > 2000:
last_update = time.ticks_ms()
# 读取温湿度和运动传感器
read_sensors()
# 自动模式控制逻辑
if auto_mode:
if temperature < 18:
set_rgb(0, 0, 255) # 蓝色
elif 18 <= temperature < 25:
set_rgb(0, 255, 0) # 绿色
else:
set_rgb(255, 0, 0) # 红色
# 根据光照调整亮度
brightness = int(light_percent * 255 / 100)
if led_state == 1:
rgb_r.duty(int(brightness * 1023 / 255))
elif led_state == 2:
rgb_g.duty(int(brightness * 1023 / 255))
elif led_state == 3:
rgb_b.duty(int(brightness * 1023 / 255))
# 运动检测闪烁
if motion_detected:
set_rgb(0, 0, 0) # 关闭LED
time.sleep(0.2)
if led_state == 1: set_rgb(255, 0, 0)
elif led_state == 2: set_rgb(0, 255, 0)
elif led_state == 3: set_rgb(0, 0, 255)
# 更新显示
update_display()
# 控制台输出
print_to_console()
# 按钮处理
if not button.value(): # 按钮按下
time.sleep(0.05) # 简单防抖
if not button.value(): # 确认按下
print("[按钮按下]")
# 记录按下时间
start_time = time.ticks_ms()
# 等待按钮释放或超时
while not button.value():
if time.ticks_ms() - start_time > 1000:
# 长按处理 - 切换模式
auto_mode = not auto_mode
set_rgb(0, 0, 0) # 关闭LED
print("模式切换: {}".format("自动模式" if auto_mode else "手动模式"))
break
time.sleep(0.05)
# 短按处理 - 手动模式切换LED颜色
if time.ticks_ms() - start_time < 1000 and not auto_mode:
led_state = (led_state + 1) % 4
if led_state == 0:
set_rgb(0, 0, 0)
print("LED状态: 关闭")
elif led_state == 1:
set_rgb(255, 0, 0)
print("LED状态: 红色")
elif led_state == 2:
set_rgb(0, 255, 0)
print("LED状态: 绿色")
elif led_state == 3:
set_rgb(0, 0, 255)
print("LED状态: 蓝色")
# 等待按钮释放
while not button.value():
time.sleep(0.05)
except KeyboardInterrupt:
# 停止定时器
light_timer.deinit()
# 关闭LED
set_rgb(0, 0, 0)
# 显示关机信息
oled.fill(0)
oled.text("系统已停止", 0, 30)
oled.show()
print("\n程序已停止")