<===
2025-10-23 10:52:45
WiFi sensor & reaction
( Adafruit CircuitPython 10.0.3 on 2025-10-17; Waveshare ESP32-S3-Zero with ESP32S3 )
----- sensor --------
$ cat code.py
import time
import board
import analogio
import wifi
SSID_PREFIX = "sensor1:"
PASSWORD = "*******"
analog_in = analogio.AnalogIn(board.A0)
while True:
voltage = (analog_in.value / 65535) * 3.3
ssid = f"{SSID_PREFIX}{voltage:.4f}"
if len(ssid) > 32: # Ограничение длины SSID
ssid = ssid[:32]
wifi.radio.stop_ap()
wifi.radio.start_ap(ssid=ssid, password=PASSWORD)
time.sleep(0.5) # Задержка для стабилизации AP
print(f"AP: SSID={ssid}, IP={wifi.radio.ipv4_address_ap or 'Not assigned'}")
time.sleep(15)
------------ client / reaction -----------
$ cat code.py
import time
import board
import wifi
import neopixel
# Настройка NeoPixel с учетом рекомендаций
pixel_pin = board.NEOPIXEL # для платы с встроенным NeoPixel
num_pixels = 1
ORDER = neopixel.GRB
pixels = neopixel.NeoPixel(
pixel_pin, num_pixels, brightness=0.02, auto_write=False, pixel_order=ORDER
)
SSID_PREFIX = "sensor1:"
HYSTERESIS = 0.05
last_led_color = None
def set_pixel_color(color):
global last_led_color
if last_led_color == color:
return
pixels.fill(color)
pixels.show()
last_led_color = color
def parse_voltage_from_ssid(ssid):
try:
voltage = float(ssid[len(SSID_PREFIX):])
print(f"Parsed voltage: {voltage}")
return voltage
except Exception as e:
print(f"Error parsing voltage from SSID '{ssid}': {e}")
return None
while True:
try:
print("Starting Wi-Fi scan...")
networks = list(wifi.radio.start_scanning_networks())
wifi.radio.stop_scanning_networks()
print(f"Found {len(networks)} networks")
matching_ssids = [net.ssid for net in networks if net.ssid and net.ssid.startswith(SSID_PREFIX)]
print(f"Matching SSIDs: {matching_ssids}")
if len(matching_ssids) != 1:
print("Error: Sensor not found or multiple sensors detected")
set_pixel_color((255, 0, 0)) # Красный - сенсор не доступен или дубли
else:
voltage = parse_voltage_from_ssid(matching_ssids[0])
if voltage is None:
print("Error: Voltage parsing failed")
set_pixel_color((255, 0, 0)) # Ошибка парсинга
else:
if voltage < 1.6 - HYSTERESIS:
print(f"Voltage {voltage} < 1.6 - HYSTERESIS, setting BLUE")
set_pixel_color((0, 0, 255)) # Синий
elif voltage > 1.61 + HYSTERESIS:
print(f"Voltage {voltage} > 1.61 + HYSTERESIS, setting GREEN")
set_pixel_color((0, 255, 0)) # Зеленый
else:
print(f"Voltage {voltage} within hysteresis range, keeping last color")
pass
except Exception as e:
print(f"Exception in main loop: {e}")
set_pixel_color((255, 0, 0)) # В случае общей ошибки красный
time.sleep(10)
---------- for test from serv ---
import time
import board
import analogio
import wifi
SSID_PREFIX = "sensor1:"
PASSWORD = "123321321"
wifi.radio.stop_ap(); wifi.radio.start_ap(ssid='sensor1:1.1000', password=PASSWORD)
---------- Хелп для тех кто долистал )) ----------------
Эта система состоит из двух частей — беспроводного сенсора на базе ESP32-S3 с CircuitPython и клиента на аналогичном микроконтроллере, который считывает данные с сенсора через Wi-Fi и отображает состояние через светодиод NeoPixel.
### Как работает сенсор
Сенсор использует аналоговый вход A0 на ESP32-S3 для измерения напряжения. Это может быть любое аналоговое напряжение в диапазоне 0–3.3 В, пропорциональное измеряемой величине (например, датчик температуры, освещенности или батареи). Значение с ADC преобразуется в напряжение с 16-битным разрешением (0–65535), потом нормируется к 3.3 В.
Далее напряжение формируется в строку SSID точки доступа Wi-Fi, например `"sensor1:1.5600"`. Таким образом, данные сенсора передаются «в эфир» через название Wi-Fi сети. Каждые 15 секунд сенсор обновляет SSID, перезапуская точку доступа с новым именем. Это простой способ бесконтактной передачи аналоговых значений без сложного протокола на уровне пакетов.
### Как работает клиент
Клиент — это другой ESP32-S3 с NeoPixel, который периодически сканирует все доступные Wi-Fi сети в зоне, используя встроенный драйвер wifi.radio. Он отфильтровывает сети, имена которых начинаются на `"sensor1:"`. Если найдена ровно одна такая сеть, из имени извлекается значение напряжения.
После этого включается светодиод с цветом, зависящим от значения напряжения:
- Красный — если сенсор не обнаружен или найдено несколько сетей с таким именем (конфликт).
- Синий — если измеренное напряжение меньше 1.6 В (с учетом гистерезиса ±0.05 В для стабильности).
- Зеленый — если напряжение выше 1.61 В (с тем же гистерезисом).
- Цвет не меняется при промежуточных значениях для предотвращения дребезга индикатора.
### Технические особенности
- Используется микроконтроллер Espressif ESP32-S3 с 32-разрядным процессором Xtensa LX7, который поддерживает Wi-Fi 802.11b/g/n и Bluetooth LE 5.0, а также встроенный 12-битный ADC для аналоговых измерений.
- CircuitPython упрощает работу с Wi-Fi, NeoPixel и ADC, позволяя с минимальным количеством кода реализовать функционал.
- Гистерезис в программном обеспечении защищает систему от нестабильных переходов при изменениях измеренного сигнала на порогах.
- Точка доступа Wi-Fi с именем, содержащим данные, работает без аутентификации клиентов (хотя в коде установлен пароль для точки).
- Малое энергопотребление и компактность позволяют использовать систему в IoT-приложениях, где требуется простой и надежный сбор аналоговых данных с беспроводной передачей.
### Применение
Такая система может служить для простых удаленных датчиков, где нет необходимости в сложной беспроводной инфраструктуре — например, мониторинг состояния батарей, датчиков температуры, влажности в труднодоступных местах.
Использование имени Wi-Fi сети в качестве носителя данных — легкий и универсальный прием для устройств с Wi-Fi модулем, где сетевые подключения или сложные протоколы нежелательны.
***
Таким образом, эта система — это пример эффективного и минималистичного IoT-решения с современным микроконтроллером ESP32-S3 и CircuitPython для беспроводного мониторинга аналоговых параметров в реальном времени с визуальной обратной связью через светодиод.