import network
import time
from machine import Pin, I2C
import dht
import ujson
from ssd1306 import SSD1306_I2C
# Инициализация сенсоров
sensor_1 = dht.DHT22(Pin(15))
sensor_2 = dht.DHT22(Pin(2))
sensor_3 = dht.DHT22(Pin(3))
sleep_timeout = 1 # Интервал обновления данных
# Инициализация дисплея SSD1306
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled_width = 128
oled_height = 64
oled = SSD1306_I2C(oled_width, oled_height, i2c)
# Инициализация кнопок
button_enter = Pin(0, Pin.IN, Pin.PULL_UP) # Кнопка "ввод"
button_left = Pin(4, Pin.IN, Pin.PULL_UP) # Кнопка "влево" - 4-й пин
button_right = Pin(16, Pin.IN, Pin.PULL_UP) # Кнопка "вправо" - 16-й пин
button_back = Pin(17, Pin.IN, Pin.PULL_UP) # Кнопка "назад" - 17-й пин
# Пункты меню
menu_items = ["Data", "Graphs", "Settings"]
current_menu_index = 0
current_sensor_index = 0
in_data_screen = False # Флаг для отслеживания, находимся ли мы в окне "Data"
def get_connected_sensors():
connected_sensors = []
for i in range(1, 4): # Проходим по номерам от 1 до 3 (т.к. у нас 3 сенсора)
sensor_name = f'sensor_{i}'
sensor = globals()[sensor_name]
try:
sensor.measure() # Пробуем измерить данные
temperature = sensor.temperature()
if temperature is not None:
connected_sensors.append(sensor_name)
except OSError:
print(f"{sensor_name} не подключен или неисправен.")
return connected_sensors
def display_menu():
"""Функция для отображения текущего пункта меню"""
oled.fill(0) # Очищаем экран
for index, item in enumerate(menu_items):
prefix = ">" if index == current_menu_index else " "
oled.text(f"{prefix} {item}", 0, index * 10)
oled.show() # Обновляем экран
def enter_menu_option():
"""Функция для обработки выбора пункта меню"""
global in_data_screen
selected_item = menu_items[current_menu_index]
if selected_item == "Data":
in_data_screen = True
elif selected_item == "Graphs":
in_data_screen = False
show_graphs_screen()
elif selected_item == "Settings":
in_data_screen = False
show_settings_screen()
def navigate_menu(direction):
"""Функция для навигации по меню"""
global current_menu_index
current_menu_index = (current_menu_index + direction) % len(menu_items)
display_menu()
def display_sensor_data(sensor_name, temperature, humidity):
"""Функция для отрисовки данных сенсора на экране"""
oled.fill(0) # Очищаем экран
oled.text(f"Sensor: {sensor_name}", 0, 0)
oled.text(f"Temp: {temperature}C", 0, 10)
oled.text(f"Humidity: {humidity}%", 0, 20)
oled.show() # Обновляем экран
def measure_and_display_sensor(sensor_name):
"""Функция для измерения и отображения данных с конкретного сенсора"""
sensor = globals()[sensor_name]
sensor.measure()
temperature = sensor.temperature()
humidity = sensor.humidity()
display_sensor_data(sensor_name, temperature, humidity)
def show_graphs_screen():
"""Отображение экрана графиков"""
oled.fill(0)
oled.text("Graphs screen", 0, 0)
oled.text("Display graphs", 0, 10)
oled.show()
def show_settings_screen():
"""Отображение экрана настроек"""
oled.fill(0)
oled.text("Settings screen", 0, 0)
oled.text("Adjust settings", 0, 10)
oled.show()
def on_enter_press(pin):
"""Обработчик нажатия кнопки Enter (ввод)"""
enter_menu_option()
def on_left_press(pin):
"""Обработчик нажатия кнопки влево"""
if in_data_screen:
change_sensor(-1)
else:
navigate_menu(-1)
def on_right_press(pin):
"""Обработчик нажатия кнопки вправо"""
if in_data_screen:
change_sensor(1)
else:
navigate_menu(1)
def on_back_press(pin):
"""Обработчик нажатия кнопки назад"""
global in_data_screen
if in_data_screen:
in_data_screen = False # Возвращаемся из экрана данных
display_menu()
else:
display_menu() # Возвращаемся в главное меню
def change_sensor(direction):
"""Функция для смены текущего сенсора в режиме отображения данных"""
global current_sensor_index
connected_sensors_list = get_connected_sensors()
current_sensor_index = (current_sensor_index + direction) % len(connected_sensors_list)
measure_and_display_sensor(connected_sensors_list[current_sensor_index])
# Привязка кнопок к функциям
button_enter.irq(trigger=Pin.IRQ_FALLING, handler=on_enter_press)
button_left.irq(trigger=Pin.IRQ_FALLING, handler=on_left_press)
button_right.irq(trigger=Pin.IRQ_FALLING, handler=on_right_press)
button_back.irq(trigger=Pin.IRQ_FALLING, handler=on_back_press)
# Начальное отображение меню
display_menu()
# Основной цикл
connected_sensors_list = get_connected_sensors()
while True:
if in_data_screen and connected_sensors_list:
measure_and_display_sensor(connected_sensors_list[current_sensor_index])
time.sleep(sleep_timeout) # Обновляем данные каждые sleep_timeout секунд
else:
time.sleep(0.1) # Небольшая задержка для предотвращения перегрузки процессора