ESP8266-LightMesh to innowacyjny projekt IoT, wykorzystujący technologię ESP-NOW do stworzenia sieci fotorezystorów opartych na modułach ESP8266. Dane o natężeniu światła są przesyłane bezprzewodowo w czasie rzeczywistym do centralnego odbiornika z ekranem OLED, który je wyświetla. System cechuje się wysoką wydajnością, niskim zużyciem energii i brakiem konieczności korzystania z infrastruktury Wi-Fi, co czyni go idealnym do monitorowania środowiska w rozproszonych lokalizacjach.
1. 5x Płytka ESP8266
2. 5x Płytka stykowa
3. 1x wyświetlacz OLED
4. 4x fotorezystor
5. 5x kable zasilające USB - micro USB
6. 4x rezystor
7. 12x przewody męsko - męskie
8. 5x zasilanie np. powerbank
Wszystkie elementy należy połączyć zgodnie z zaleceniami z zajęć oraz kierować się schematami z platformy SIC Start!
Projekt ESP8266-LightMesh to system IoT, który umożliwia monitorowanie natężenia światła w wielu lokalizacjach poprzez zastosowanie sieci bezprzewodowej opartej na protokole ESP-NOW. Składa się z kilku nadawców (modułów ESP8266 z fotorezystorami), które przesyłają dane do centralnego odbiornika wyposażonego w ekran OLED oraz mechanizm zapisu danych do pliku tekstowego. Projekt realizuje ideę rozproszonego monitorowania środowiska z możliwością analizy historycznej dzięki zapisowi wyników.
Projekt został napisany w języku MicroPython, co pozwala na lekkie i efektywne zarządzanie zarówno sprzętem, jak i komunikacją. Protokół ESP-NOW, używany w projekcie, zapewnia szybką wymianę danych między modułami bez konieczności korzystania z infrastruktury Wi-Fi, co zmniejsza zapotrzebowanie na energię. Każdy nadawca jest przypisany do konkretnego fotorezystora i przesyła dane o zmierzonej jasności do odbiornika. Odbiornik następnie wyświetla te dane w czasie rzeczywistym na ekranie OLED i zapisuje je do pliku wraz z sygnaturą czasową.
Opis kodu nadawcy
Kod nadawcy realizuje zadanie zbierania danych z czujnika światła (fotorezystora) i przesyłania ich w formie zakodowanej wiadomości do odbiornika.
-
Inicjalizacja modułu Wi-Fi i ESP-NOW: Moduł ESP8266 jest skonfigurowany w trybie STA (station), co jest wymagane przez protokół ESP-NOW. Następnie protokół ESP-NOW zostaje aktywowany, a adres MAC odbiornika dodany jako peer, aby umożliwić przesyłanie danych do konkretnego urządzenia.
-
Pomiar światła za pomocą fotorezystora: Fotorezystor jest podłączony do wejścia analogowego modułu ESP8266. Kod wykorzystuje funkcję
photoresistor.read()
, aby odczytać aktualne natężenie światła w formie wartości liczbowej. -
Kodowanie i wysyłanie danych: Zmierzona wartość natężenia światła jest przekształcana na ciąg znaków i kodowana w formacie UTF-8, a następnie przesyłana do odbiornika za pomocą funkcji
espnow.asend()
. -
Debugowanie i obsługa błędów: Każda wysyłka jest logowana w konsoli. Jeśli wysyłka się nie powiedzie, pojawi się komunikat błędu, który informuje o problemie. Dzięki temu proces wysyłania może być monitorowany w czasie rzeczywistym.
-
Asynchroniczność: Kod wykorzystuje bibliotekę
uasyncio
, co pozwala na efektywne zarządzanie cyklicznym pomiarem światła i przesyłaniem danych. Opóźnienie między kolejnymi wysyłkami wynosi 0,1 sekundy, co zapewnia płynne działanie systemu.
Opis kodu odbiornika
Odbiornik został zaprojektowany tak, aby obsługiwać dane przesyłane przez kilku nadawców jednocześnie. Każdy nadawca jest identyfikowany na podstawie swojego unikalnego adresu MAC. Kod odbiornika zapewnia:
- Odbiór danych: Funkcja
receive_data()
nasłuchuje wiadomości przesyłanych przez nadawców. Po rozpoznaniu nadawcy na podstawie adresu MAC dane są dekodowane i zapisywane w słownikusensor_data
. - Wyświetlanie na OLED: Dane od każdego nadawcy są wyświetlane na ekranie OLED w osobnych liniach. Wyświetlacz jest aktualizowany w czasie rzeczywistym.
- Zapis do pliku: Dane zebrane od nadawców są co określony czas zapisywane do pliku tekstowego. Dzięki temu można analizować historyczne pomiary światła.
- Obsługa błędów: Kod obsługuje sytuacje, w których wiadomość nie może być poprawnie zdekodowana lub dane od nadawców są niekompletne.
Proces tworzenia projektu
Projekt rozpoczął się od konfiguracji modułów ESP8266 i wgrania na nie firmware MicroPython. Kluczowym krokiem było uzyskanie adresów MAC dla każdego modułu, co zostało zrealizowane za pomocą funkcji wlan.config('mac')
. Te adresy były niezbędne do skonfigurowania komunikacji w sieci ESP-NOW.
Następnie, dla nadawców, skonfigurowano fotorezystory i opracowano kod umożliwiający pomiar natężenia światła. Każdy nadawca został zaprogramowany do przesyłania swoich danych do odbiornika w formacie kompatybilnym z ESP-NOW.
Dla odbiornika stworzono funkcjonalności umożliwiające dekodowanie, wyświetlanie oraz zapisywanie otrzymanych danych. Wyświetlacz OLED został podłączony i skonfigurowany za pomocą interfejsu I2C. Ostatecznie dodano mechanizm cyklicznego zapisywania danych do pliku z sygnaturą czasową.
Potencjalne zastosowania
Projekt ESP8266-LightMesh może znaleźć zastosowanie w różnych dziedzinach, takich jak:
- Inteligentne budynki: Automatyczne monitorowanie i dostosowywanie poziomu oświetlenia w zależności od warunków zewnętrznych.
- Analiza środowiskowa: Pomiar natężenia światła w różnych lokalizacjach na potrzeby badań naukowych.
- Projekty edukacyjne: Nauka protokołu ESP-NOW i zastosowań IoT w praktycznych projektach.
# ODBIORNIK
import network
from aioespnow import AIOESPNow
from machine import Pin, I2C
import ssd1306
import uasyncio as asyncio
import time
# Konfiguracja OLED
i2c = I2C(scl=Pin(5), sda=Pin(4)) # Piny SCL i SDA dla OLED
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# Inicjalizacja WiFi w trybie STA (wymagane przez ESP-NOW)
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
print("Adres MAC odbiornika:", wlan.config('mac'))
# Inicjalizacja ESP-NOW
espnow = AIOESPNow()
espnow.active(True)
# Adresy MAC nadawców
mac_addresses = {
b'\n:\x8d\xcc\xf9\x1b': "sensor1", # Nadawca 1
b'\n:\x8d\xcc\xed\xab': "sensor2", # Nadawca 2
b'\n:\x8d\xcd\x03\xa1': "sensor3", # Nadawca 3
b'\n:\x8d\xcc\xf7m': "sensor4", # Nadawca 4
}
# Słownik do przechowywania wartości od nadawców
sensor_data = {name: None for name in mac_addresses.values()}
async def receive_data():
async for mac, msg in espnow:
mac_bytes = bytes(mac) # Konwertuj bytearray na bytes
print(f"Odebrano wiadomość od: {mac_bytes}")
print(f"Odebrana wiadomość: {msg}") # Debuguj odebrane wiadomości
if mac_bytes in mac_addresses:
sensor_id = mac_addresses[mac_bytes]
try:
# Dekodowanie wiadomości
received_value = int(msg.decode('utf-8'))
sensor_data[sensor_id] = received_value
print(f"Sensor: {sensor_id}, Wartość: {received_value}")
update_display()
except Exception as e:
print(f"Błąd podczas przetwarzania wiadomości od {mac_bytes}: {e}")
else:
print(f"Nieznany nadawca: {mac_bytes}")
def update_display():
oled.fill(0) # Wyczyść ekran
y = 0
# Określ kolejność wyświetlania
ordered_sensors = ["sensor1", "sensor2", "sensor3", "sensor4"]
for sensor in ordered_sensors:
value = sensor_data.get(sensor, "Brak")
oled.text(f"{sensor}: {value if value is not None else 'Brak'}", 0, y)
y += 16
oled.show()
def save_to_file():
timestamp = time.localtime()
filename = "sensor_data.v0.txt"
# Sprawdzamy, czy wszystkie dane są dostępne przed zapisem
if all(value is not None for value in sensor_data.values()):
with open(filename, "a") as file:
file.write(f"{timestamp}: {sensor_data}\n")
print(f"Zapisano dane do pliku: {filename}")
else:
print("Nie wszystkie dane są dostępne, pomijam zapis.")
async def periodic_save():
while True:
# Aktualna sekunda
current_second = time.localtime()[5]
# Wyświetl sekundę zapisu
oled.fill(0)
oled.text(f"Zapis danych: {current_second}s", 0, 0)
update_display()
# Zapisz dane do pliku
save_to_file()
await asyncio.sleep(10)
async def main():
# Uruchom jednocześnie odbieranie danych i zapis do pliku
await asyncio.gather(
receive_data(),
periodic_save()
)
# Uruchom program
asyncio.run(main())
# NADAJNIK
import network
from aioespnow import AIOESPNow
from machine import ADC
import uasyncio as asyncio
# Inicjalizacja WiFi w trybie STA (wymagane przez ESP-NOW)
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
print("Adres MAC nadawcy:", wlan.config('mac')) # Wyświetl adres MAC nadawcy
# Inicjalizacja ADC dla fotorezystora
photoresistor = ADC(0) # Fotorezystor podłączony do ADC
# Inicjalizacja ESP-NOW
espnow = AIOESPNow()
espnow.active(True)
# Adres MAC odbiorcy
receiver_mac = b'\x08:\x8d\xcd\x02\x87' # Zamień na odpowiedni adres MAC odbiorcy
espnow.add_peer(receiver_mac)
# Funkcja do asynchronicznego wysyłania danych
async def send_data():
while True:
try:
# Odczytaj wartość z fotorezystora
light_value = photoresistor.read()
# Zakoduj wartość do wysłania
message = str(light_value).encode('utf-8')
# Wyślij dane do odbiorcy
result = await espnow.asend(receiver_mac, message)
# Sprawdź wynik wysyłki
if result:
print(f"Wysłano: {light_value} do {receiver_mac}")
else:
print("Błąd: Nie udało się wysłać wiadomości")
except Exception as e:
print(f"Błąd podczas wysyłania: {e}")
# Opóźnienie między kolejnymi wysyłkami
await asyncio.sleep(0.1)
# Uruchom asynchroniczne wysyłanie danych
asyncio.run(send_data())
https://randomnerdtutorials.com/esp-now-esp8266-nodemcu-arduino-ide/
https://www.youtube.com/watch?v=4H8TMekmR3E