ESP8266 - LightMesh, czyli projekt IoT połączenia fotorezystorów w jednej sieci

Typ_projektu
microPython
Zdjecie główne
zdjęcie sensorów i wyświetlacza OLED
Krótki opis projektu

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.

Niezbędne elementy

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 

Sprzęt

Wszystkie elementy należy połączyć zgodnie z zaleceniami z zajęć oraz kierować się schematami z platformy SIC Start!

Opis projektu

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łowniku sensor_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.
Zdjęcia
wyświetlanie wartości
połączenie odbiornika
połączenie nadajnika
plik z zapisem wartości
kod programu
# 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())

Schemat
Tagi
ESPNOW python fotorezystor IoT ESP8266 Tohnny
Odnośniki zewnętrzne
https://start.sic.edu.pl/my/
https://randomnerdtutorials.com/esp-now-esp8266-nodemcu-arduino-ide/
https://www.youtube.com/watch?v=4H8TMekmR3E