from machine import Pin, ADC, PWM, I2C, Timer
import dht
import ssd1306
import time
# 初始化硬件
mq2 = ADC(Pin(33))
mq2.atten(ADC.ATTN_11DB)
ldr = ADC(Pin(32))
ldr.atten(ADC.ATTN_11DB)
dht_sensor = dht.DHT22(Pin(15))
pir = Pin(35, Pin.IN)
buzzer = Pin(5, Pin.OUT)
# RGB LED控制(PWM)
r = PWM(Pin(18), freq=1000)
g = PWM(Pin(19), freq=1000)
b = PWM(Pin(17), freq=1000)
# OLED显示初始化
i2c = I2C(scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# 舵机控制初始化
servo = PWM(Pin(25), freq=50)
# 超声波模块初始化
trig = Pin(27, Pin.OUT)
echo = Pin(26, Pin.IN)
# 设置RGB颜色(0-100占比)
def set_rgb(red, green, blue):
r.duty(1023 - int(red * 10.23))
g.duty(1023 - int(green * 10.23))
b.duty(1023 - int(blue * 10.23))
# 设置舵机角度(0-180度)
def set_servo_angle(angle):
min_duty = 26
max_duty = 123
duty = int(min_duty + (angle / 180) * (max_duty - min_duty))
servo.duty(duty)
# 超声波测距函数(返回厘米)
def get_distance():
trig.value(0)
time.sleep_us(2)
trig.value(1)
time.sleep_us(10)
trig.value(0)
while echo.value() == 0:
pass
start = time.ticks_us()
while echo.value() == 1:
pass
end = time.ticks_us()
duration = time.ticks_diff(end, start)
distance = duration / 58.0
return distance
# 自动门控制变量
door_open = False
last_open_time = 0
# 数据刷新回调函数
def refresh_data(timer):
global door_open, last_open_time
try:
# 读取传感器数据
dht_sensor.measure()
temp = dht_sensor.temperature()
gas = mq2.read()
light = ldr.read()
motion = pir.value()
distance = get_distance()
oled.fill(0) # 清屏
# 安全状态判断(修改颜色逻辑)
if gas > 4000 or temp > 50:
buzzer.value(1) # 报警触发
set_rgb(100, 0, 0) # 红色报警(修改:原绿色改为红色)
oled.text("ALERT!", 0, 0)
oled.text("Gas: {}".format(gas), 0, 10)
oled.text("Temp: {}".format(temp), 0, 20)
else:
buzzer.value(0) # 安全状态
set_rgb(0, 100, 0) # 绿色常亮(修改:原红色改为绿色)
oled.text("Safe", 0, 0)
oled.text("Gas: {}".format(gas), 0, 10)
oled.text("Temp: {}".format(temp), 0, 20)
# 光线和人体移动检测
if light < 3000 and motion == 1:
set_rgb(0, 0, 100) # 黄色(有人触发)
oled.text("light: {}".format(light), 0, 30)
oled.text("Motion: Yes", 0, 40)
else:
set_rgb(0, 100, 0) # 绿色(无人触发时保持绿色)
oled.text("light: {}".format(light), 0, 30)
oled.text("Motion: No", 0, 40)
# 自动门控制
oled.text("Dist: {:.1f}mm".format(distance), 0, 50)
if distance < 300 and not door_open:
set_servo_angle(90) # 开门
door_open = True
last_open_time = time.ticks_ms()
elif door_open and time.ticks_diff(time.ticks_ms(), last_open_time) > 5000:
set_servo_angle(0) # 超时关门
door_open = False
oled.show() # 更新显示
except Exception as e:
print("Error:", e)
# 启动定时器(每秒刷新)
timer = Timer(0)
timer.init(period=1000, mode=Timer.PERIODIC, callback=refresh_data)
# 主循环
while True:
pass