# Итоговая работа
# Студент: Максимова В.В.
# Группа: ВД-3-23
import dht
from machine import Pin, PWM, ADC
import utime
# ========== НАСТРОЙКИ ==========
# Датчики
dht_sensor = dht.DHT22(Pin(8))
TRIG = Pin(7, Pin.OUT)
ECHO = Pin(5, Pin.IN)
ldr = ADC(Pin(26))
# RGB светодиод
red = PWM(Pin(15), freq=1000)
green = PWM(Pin(14), freq=1000)
blue = PWM(Pin(13), freq=1000)
# Пьезоэлемент
buzzer = PWM(Pin(12), freq=1000)
# ========== КНОПКА (ПРАВИЛЬНАЯ НАСТРОЙКА) ==========
# Для кнопки, которая замыкает GP16 на GND при нажатии
# Используем встроенный PULL_UP резистор
emergency_button = Pin(16, Pin.IN, Pin.PULL_UP)
# ========== ПЕРЕМЕННЫЕ ==========
emergency_mode = False
max_duty = 65535
# ========== ФУНКЦИЯ ЧТЕНИЯ DHT22 ==========
def read_dht22():
for attempt in range(3):
try:
dht_sensor.measure()
temp = dht_sensor.temperature()
hum = dht_sensor.humidity()
return temp, hum, True
except Exception as e:
if attempt < 2:
utime.sleep_ms(500)
else:
print(f" DHT22 ошибка: {e}")
return 21.0, 50.0, False
return 21.0, 50.0, False
# ========== ФУНКЦИИ RGB ==========
def set_color(r, g, b):
red.duty_u16(int(max_duty * r / 100))
green.duty_u16(int(max_duty * g / 100))
blue.duty_u16(int(max_duty * b / 100))
def turn_off_led():
set_color(0, 0, 0)
def blink_color(r, g, b, on_time, off_time, count=1):
for _ in range(count):
set_color(r, g, b)
utime.sleep(on_time)
turn_off_led()
utime.sleep(off_time)
# ========== ФУНКЦИИ ЗВУКА ==========
def play_tone(freq, duration):
if freq > 0:
buzzer.freq(freq)
buzzer.duty_u16(32768)
utime.sleep(duration)
buzzer.duty_u16(0)
def alarm_sound():
for _ in range(3):
play_tone(2000, 0.15)
utime.sleep(0.1)
# ========== ДАТЧИК РАССТОЯНИЯ ==========
def get_distance():
TRIG.low()
utime.sleep_us(2)
TRIG.high()
utime.sleep_us(10)
TRIG.low()
timeout = 30000
start_time = utime.ticks_us()
while ECHO.value() == 0:
if utime.ticks_diff(utime.ticks_us(), start_time) > timeout:
return None
start_pulse = utime.ticks_us()
while ECHO.value() == 1:
if utime.ticks_diff(utime.ticks_us(), start_time) > timeout:
return None
end_pulse = utime.ticks_us()
duration = utime.ticks_diff(end_pulse, start_pulse)
distance = (duration * 0.0343) / 2
return distance if distance < 400 else None
# ========== ДАТЧИК ОСВЕЩЁННОСТИ ==========
def read_lux():
raw = ldr.read_u16()
voltage = raw / 65535 * 3.3
if voltage >= 3.3:
return 500
try:
resistance = 10000 * voltage / (3.3 - voltage)
gamma = 0.7
rl10 = 50
lux = (rl10 * 1000 * (10 ** gamma) / resistance) ** (1 / gamma)
return min(lux, 2000)
except:
return 500
# ========== КНОПКА С АНТИДРЕБЕЗГОМ (УПРОЩЁННАЯ И НАДЁЖНАЯ) ==========
last_button_state = 1
def check_emergency():
global emergency_mode, last_button_state
current = emergency_button.value()
# Если кнопка нажата (сигнал 0) и до этого не была нажата
if current == 0 and last_button_state == 1:
utime.sleep_ms(50) # Антидребезг
if emergency_button.value() == 0:
emergency_mode = not emergency_mode
last_button_state = 0
return True
# Если кнопка отпущена
elif current == 1 and last_button_state == 0:
utime.sleep_ms(50)
if emergency_button.value() == 1:
last_button_state = 1
return False
# ========== ТЕСТОВАЯ ФУНКЦИЯ ==========
def test_emergency_button():
print("\n>>> Тест кнопки: нажмите GP16 для проверки <<<")
start_time = utime.time()
while utime.time() - start_time < 10:
if emergency_button.value() == 0:
print("✅ Кнопка работает! Обнаружено нажатие")
play_tone(1000, 0.2)
return True
utime.sleep(0.1)
print("⚠️ Кнопка не была нажата в течение 10 секунд")
return False
# ========== ИНИЦИАЛИЗАЦИЯ ==========
print("=" * 50)
print("Итоговая работа")
print("Студент: Максимова В.В.")
print("Система: Температура | Влажность | Расстояние | Освещённость")
print("Аварийная кнопка: GP16 (нажать для экстренной остановки)")
print("=" * 50)
# Тест RGB
print("\nТест RGB LED...")
set_color(100, 0, 0)
utime.sleep(0.3)
set_color(0, 100, 0)
utime.sleep(0.3)
set_color(0, 0, 100)
utime.sleep(0.3)
turn_off_led()
print("✓ RGB OK")
# Тест DHT22
print("Тест DHT22...")
utime.sleep(1)
temp, hum, ok = read_dht22()
if ok:
print(f"✓ DHT22 OK: T={temp:.1f}°C, H={hum:.1f}%")
else:
print("⚠️ DHT22: будут использованы значения по умолчанию")
# ТЕСТ КНОПКИ
test_emergency_button()
print("\n" + "=" * 50)
print("ПЕРЕХОД В ОСНОВНОЙ РЕЖИМ")
print("Нажмите кнопку GP16 для аварийной остановки")
print("=" * 50 + "\n")
# ========== ОСНОВНОЙ ЦИКЛ ==========
count = 0
while True:
# Проверка аварийной кнопки
if check_emergency():
if emergency_mode:
print("\n" + "!" * 50)
print("⚠️⚠️⚠️ АВАРИЙНАЯ ОСТАНОВКА АКТИВИРОВАНА! ⚠️⚠️⚠️")
print("!" * 50)
play_tone(2000, 0.3)
else:
print("\n✅ Аварийный режим снят. Возврат к нормальной работе.")
play_tone(1000, 0.2)
# ========== АВАРИЙНЫЙ РЕЖИМ ==========
if emergency_mode:
set_color(100, 0, 0)
play_tone(2000, 0.15)
utime.sleep(0.15)
turn_off_led()
utime.sleep(0.1)
print("🔴 АВАРИЙНЫЙ РЕЖИМ! Нажмите кнопку GP16 для выхода...")
continue
# ========== НОРМАЛЬНЫЙ РЕЖИМ ==========
count += 1
temp, hum, dht_ok = read_dht22()
distance = get_distance()
if distance is None:
distance = 100
lux = read_lux()
status = "✓" if dht_ok else "⚠️"
print(f"\n[{count}] {status} T={temp:.1f}°C H={hum:.1f}% | 📏 dist={distance:.1f}см | 💡 lux={lux:.0f}")
# Логика реакции
if distance < 20:
print("🚨 ОПАСНО: объект слишком близко! (< 20 см)")
blink_color(100, 0, 0, 0.25, 0.25, 2)
play_tone(1000, 0.25)
elif (20.0 <= temp <= 22.0) and (40.0 <= hum <= 60.0):
print("✅ КОМФОРТНАЯ ЗОНА")
set_color(0, 100, 0)
buzzer.duty_u16(0)
elif temp < 20 or temp > 22 or hum < 40 or hum > 60:
reasons = []
if temp < 20: reasons.append(f"T={temp:.1f}°C < 20")
if temp > 22: reasons.append(f"T={temp:.1f}°C > 22")
if hum < 40: reasons.append(f"H={hum:.1f}% < 40")
if hum > 60: reasons.append(f"H={hum:.1f}% > 60")
print(f"⚠️ НЕКОМФОРТНО: {', '.join(reasons)}")
blink_color(100, 50, 0, 0.4, 0.4, 1)
play_tone(500, 0.2)
elif lux < 100:
print("🌙 СЛИШКОМ ТЕМНО (< 100 люкс)")
blink_color(0, 0, 100, 0.5, 0.5, 2)
play_tone(700, 0.2)
elif lux > 500:
print("☀️ СЛИШКОМ ЯРКО (> 500 люкс)")
blink_color(100, 100, 100, 0.3, 0.7, 2)
else:
print("✅ Все параметры в норме")
set_color(0, 100, 0)
buzzer.duty_u16(0)
if distance is not None and distance < 15 and temp > 28:
print("⚠️⚠️⚠️ КРИТИЧЕСКАЯ СИТУАЦИЯ!")
alarm_sound()
utime.sleep(1.5)