Skocz do zawartości

Przeszukaj forum

Pokazywanie wyników dla tagów 'woda'.

  • Szukaj wg tagów

    Wpisz tagi, oddzielając przecinkami.
  • Szukaj wg autora

Typ zawartości


Kategorie forum

  • Elektronika i programowanie
    • Elektronika
    • Arduino i ESP
    • Mikrokontrolery
    • Raspberry Pi
    • Inne komputery jednopłytkowe
    • Układy programowalne
    • Programowanie
    • Zasilanie
  • Artykuły, projekty, DIY
    • Artykuły redakcji (blog)
    • Artykuły użytkowników
    • Projekty - DIY
    • Projekty - DIY roboty
    • Projekty - DIY (mini)
    • Projekty - DIY (początkujący)
    • Projekty - DIY w budowie (worklogi)
    • Wiadomości
  • Pozostałe
    • Oprogramowanie CAD
    • Druk 3D
    • Napędy
    • Mechanika
    • Wydarzenia
    • Sprzedam/Kupię/Zamienię/Praca
    • Inne
  • Ogólne
    • Ogłoszenia organizacyjne
    • Dyskusje o FORBOT.pl
    • Na luzie

Kategorie

  • Quizy o elektronice
  • Quizy do kursu elektroniki I
  • Quizy do kursu elektroniki II
  • Quizy do kursów Arduino
  • Quizy do kursu STM32L4
  • Quizy do pozostałych kursów

Szukaj wyników w...

Znajdź wyniki, które zawierają...


Data utworzenia

  • Rozpocznij

    Koniec


Ostatnia aktualizacja

  • Rozpocznij

    Koniec


Filtruj po ilości...

Data dołączenia

  • Rozpocznij

    Koniec


Grupa


Imię


Strona

Znaleziono 2 wyniki

  1. 1. Cel i zakres Celem projektu jest ciągły nadzór nad parametrami środowiskowymi w serwerowni: temperaturą, wilgotnością względną oraz poziomem hałasu. Urządzenie ma wczesne wykrywać anomalie (np. awaria klimatyzacji, wzrost hałasu wentylatorów), rejestrować historię i raportować wartości do systemu Domoticz. 2. Architektura systemu System składa się z dwóch warstw: Warstwa akwizycji – Arduino Nano (8-bit MCU) zbiera szybkie próbki analogowe z mikrofonu MAX9814 oraz dane z czujnika SHT20 po magistrali I²C. Dane są wstępnie przetwarzane i przesyłane przez UART do Raspberry Pi. Warstwa bramki i zapisu – Raspberry Pi 4 (Raspbian/Linux) realizuje: odczyt dwóch sond DS18B20 po 1-Wire (wejście jądra: /sys/bus/w1/devices/28-00000053483a oraz drugi czujnik), harmonogram zadań cron (interwał 1 min), agregację i wysyłkę wszystkich wartości do Domoticz poprzez HTTP: http://{domoticz_host}:{domoticz_port}/json.htm?type=command&param=udevice&idx={device_idx}&nvalue={nvalue}&svalue={svalue} 3. Sensory i interfejsy 3.1. Temperatura – DS18B20 (2 szt.) Wodoodporne sondy 1-Wire zasilane z 3,3 V lub 5 V (w zależności od trasy). Obie podłączone równolegle do jednego kanału 1-Wire na Raspberry Pi z rezystorem podciągającym 4,7 kΩ do linii danych. Oprogramowanie identyfikuje unikalne adresy czujników; skrypt czyta pliki w1_slave, filtruje wartości CRC i przekazuje wynik w °C do Domoticz. Interwał próbkowania: 60 s. 3.2. Wilgotność i temperatura – SHT20 (I²C) Czujnik cyfrowy z sondą w stalowej obudowie, połączony przewodem ok. 5 m. Ze względu na długość magistrali zastosowano TCA4307 (Adafruit 5159) – bufor/Hot-Swap I²C stabilizujący zbocza i umożliwiający gorące dołączanie. Kolory przewodów: biały – GND, niebieski – 3,3 V, zielony – SDA → A5 Arduino, żółty – SCL → A4 Arduino. Częstotliwość I²C nominalnie 100 kHz (zalecane przy długich liniach). 3.3. Poziom dźwięku – MAX9814 (A0) Mikrofon elektretowy z automatycznym wzmocnieniem (AGC), zasilany 3,3–5 V, wyjście analogowe do A0 Arduino. Procedura pomiaru: przez 3 s wykonywany jest pomiar co 0,2 s (15 próbek), a następnie liczona jest amplituda (różnica między maksimum a minimum). Wynik odpowiada przybliżonej głośności/zmienności akustycznej w otoczeniu i służy do detekcji nietypowych zdarzeń (np. hałas łożysk, alarmy). 4. Komunikacja i format danych Arduino Nano komunikuje się z Raspberry Pi przez UART (np. 115200 8N1). Ramka danych może mieć postać JSON/CSV, np.: TEMP1=23.56;TEMP2=23.42;HUM=45.1;SHTT=23.7;SND=128 Raspberry Pi łączy dane z DS18B20 z ramką z Nano, waliduje zakresy (np. –40…85 °C dla DS18B20, 0…100% RH dla SHT20) i wysyła do Domoticz odpowiednimi idx. Wysyłka realizowana przez skrypt uruchamiany z cron co minutę; w przypadku błędu HTTP przewidziany jest retry oraz zapis do lokalnego logu. 5. Zasilanie i okablowanie Urządzenia zasilane z jednej szyny 5 V z zabezpieczeniem (bezpiecznik/ogranicznik prądu). Zastosowano: Radiator i wentylację Raspberry Pi 4 (zespół odprowadzania ciepła), Obudowę plastikową z przepływem powietrza, Shield Proto z listwą ARK dla solidnych przyłączy, Przewody 3- i 4-żyłowe (ok. 30 m) prowadzone z dala od kabli zasilania 230 V; zalecane skrętki dla linii sygnałowych. Przewidziano gniazdo RJ45 jako przepust/organizację okablowania sygnałowego. 6. Montaż i bezpieczeństwo Wszystkie połączenia sygnałowe wykonane jako niskonapięciowe SELV. Linie 1-Wire i I²C prowadzone możliwie krótko; dla odcinków dłuższych – ekran lub bufor (jak TCA4307). Obudowa zamknięta, dostęp serwisowy przez pokrywę. Brak bezpośrednich połączeń z siecią 230 V w urządzeniu. 7. Oprogramowanie i utrzymanie System: Raspbian z włączonymi modułami w1-gpio, i2c, serial. Usługi: skrypt akwizycji uruchamiany przez cron co 1 min; logi rotowane (logrotate). Zabezpieczenia: ograniczenie dostępu HTTP do Domoticz (token/hasło), firewall sieciowy, separacja VLAN gdzie możliwe. Kalibracja: wstępna weryfikacja sond temperatury w znanym punkcie (np. 0 °C z lodem); sanity-check wilgotności na referencyjnych warunkach; próg alarmu akustycznego ustalany empirycznie w godzinach normalnej pracy serwerowni. 8. Integracja z Domoticz Dla każdego parametru utworzono urządzenie w Domoticz (oddzielne idx dla: Temp1, Temp2, Wilgotność, Temp SHT, Hałas). Dane przekazywane poprzez żądanie HTTP GET zgodnie z API Domoticz. W systemie konfiguruje się sceny/zdarzenia: alarm wysokiej temperatury, długotrwały wzrost hałasu, trend wilgotności (np. wykrycie zalania/awarii nawilżania). 9. Testy i kryteria akceptacji Test komunikacji: poprawny odczyt wszystkich sensorów przez 24 h bez utraty ramek. Test odporności: symulacja wzrostu temperatury (np. odłączenie jednego klimatyzatora) – rejestracja i alarm. Test akustyczny: sztuczne źródło hałasu – wzrost amplitudy o ustalony próg, wygenerowanie zdarzenia. Pora na zdjęcia poglądowe, najpierw po zmontowaniu: Uruchomienie systemu bez niespodzianki: A tak po uporządkowaniu połączeń i skręceniu: Na koniec kody źródłowe do czujników. Zaczynam od dwóch czujników temperatury w serwerowni. Posiadają tylko trzy wyprowadzenia. #!/usr/bin/env python3 import os import time import requests # Ładowanie modułów (możesz dodać te polecenia do /etc/rc.local lub skonfigurować je w systemd) os.system('modprobe w1-gpio') os.system('modprobe w1-therm') # Ustawienie ścieżki do czujnika DS18B20 device_folder = '/sys/bus/w1/devices/28-00000053483a' device_file = os.path.join(device_folder, 'w1_slave') def read_temp_raw(): with open(device_file, 'r') as f: lines = f.readlines() return lines def read_temp(): lines = read_temp_raw() # Czekamy, aż pierwszy wiersz potwierdzi poprawny odczyt ('YES') while lines[0].strip()[-3:] != 'YES': time.sleep(0.2) lines = read_temp_raw() equals_pos = lines[1].find('t=') if equals_pos != -1: temp_string = lines[1][equals_pos+2:] temp_c = float(temp_string) / 1000.0 return temp_c raise RuntimeError("Błąd odczytu temperatury!") # Odczyt temperatury temperature = read_temp() print("Temperatura: {:.2f} °C".format(temperature)) # Konfiguracja Domoticz domoticz_host = "localhost" domoticz_port = "8080" device_idx = "1" # <--- zmień na właściwy numer urządzenia w Domoticz nvalue = 0 svalue = "{:.2f}".format(temperature) # Ustaw dane autoryzacyjne (login/hasło) username = "update" # <--- wpisz swój login password = "password" # <--- wpisz swoje hasło # Przygotowanie adresu URL do aktualizacji urządzenia w Domoticz url = f"http://{domoticz_host}:{domoticz_port}/json.htm?type=command&param=udevice&idx={device_idx}&nvalue={nvalue}&svalue={svalue}" print("Wysyłanie danych do Domoticz:", url) try: response = requests.get(url, timeout=10, auth=(username, password)) if response.status_code == 200: print("Pomyślnie wysłano dane do Domoticz.") else: print("Błąd wysyłania danych, kod HTTP:", response.status_code) except Exception as e: print("Błąd przy wysyłaniu danych do Domoticz:", e) Powinny być dwa takie skrypty umieszczone w podkatalogu aplikacji Domoticz, u mnie są temp1.py i temp2.py, różnią się tylko w jednej linii kodu: device_idx = "1" # <--- zmień na właściwy numer urządzenia w Domoticz - dla temp1.py device_idx = "2" # <--- zmień na właściwy numer urządzenia w Domoticz - dla temp2.py Pora teraz na czujnik wilgotności i temperatury w serwerowni: #!/usr/bin/env python3 # -*- coding: utf-8 -*- # # Odczyt SHT30 + wysyłka temperatury i wilgotności do Domoticz # import time import socket import requests from smbus2 import SMBus # ---------- 1. Funkcje pomocnicze ---------- # a) Bieżący adres IP (lub wpisz "localhost") def get_local_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.connect(("8.8.8.8", 80)) return s.getsockname()[0] finally: s.close() # b) CRC-8 z datasheetu SHT3x (polinom 0x31, init 0xFF) def crc8(data): crc = 0xFF for byte in data: crc ^= byte for _ in range(8): crc = (crc << 1) ^ 0x31 if (crc & 0x80) else (crc << 1) crc &= 0xFF return crc # c) Odczyt jednorazowy temperatury [°C] i RH [%] def read_sht30(bus, addr=0x44): CMD_SINGLE_HIGHREP = [0x2C, 0x06] # single-shot, high repeatability, no CS bus.write_i2c_block_data(addr, CMD_SINGLE_HIGHREP[0], CMD_SINGLE_HIGHREP[1:]) time.sleep(0.015) # 15 ms zgodnie z arkuszem raw = bus.read_i2c_block_data(addr, 0x00, 6) # weryfikacja CRC if crc8(raw[0:2]) != raw[2] or crc8(raw[3:5]) != raw[5]: raise RuntimeError("Błędna suma CRC (SHT30)") raw_temp = raw[0] << 8 | raw[1] raw_humid = raw[3] << 8 | raw[4] temp_c = -45 + 175 * (raw_temp / 65535.0) rh = 100 * (raw_humid / 65535.0) return round(temp_c, 2), round(rh, 1) # d) Podpowiedz status wilgotności dla Domoticz def humidity_status(rh): if 40 <= rh <= 60: return 1 # Comfortable if rh < 30: return 2 # Dry if rh > 70: return 3 # Wet return 0 # Normal # ---------- 2. Konfiguracja ---------- DOMO_HOST = get_local_ip() # albo "localhost" DOMO_PORT = 8080 DEVICE_IDX = 3 # <-- wstaw IDX czujnika Temp+Hum USERNAME = "update" PASSWORD = "password" # ---------- 3. Główna logika ---------- with SMBus(1) as bus: try: temp, rh = read_sht30(bus) h_stat = humidity_status(rh) # Format dla czujnika Temp+Hum: "T;RH;HumStat" svalue = f"{temp:.2f};{rh:.1f};{h_stat}" url = (f"http://{DOMO_HOST}:{DOMO_PORT}/json.htm?" f"type=command&param=udevice&idx={DEVICE_IDX}" f"&nvalue=0&svalue={svalue}") print(f"Odczyt SHT30 → {temp:.2f} °C {rh:.1f}% RH") r = requests.get(url, timeout=10, auth=(USERNAME, PASSWORD)) r.raise_for_status() #print(f"Wysłano do Domoticz ({DOMO_HOST}), HTTP {r.status_code} OK") except Exception as e: print("Błąd:", e) Teraz pora na kod, który został wgrany do Arduino Nano (bardzo lubię z niego korzystać). Skrypt ma za zadanie wysyłać dane z drugiego czujnika temperatury i wilgotności oraz poziom dźwięku w serwerowni. Te wszystkie dane są przekazywane do Raspberry Pi 4 w zadanych interwałach czasowych. #include <Wire.h> #include <Adafruit_SHT31.h> Adafruit_SHT31 sht31; /* ---------- CZASY ---------- */ const unsigned long PERIOD_SHT_MS = 30000UL; // 30 s const unsigned long SOUND_STEP_MS = 200UL; // 0,2 s const uint8_t SOUND_BUF_LEN = 18; // 18 próbek → 3,6 s /* ---------- PINY ---------- */ const uint8_t PIN_SOUND = A0; /* ---------- ZMIENNE ---------- */ unsigned long lastSht = 0; unsigned long lastSound = 0; uint16_t soundBuf[SOUND_BUF_LEN]; uint8_t soundIx = 0; bool bufFilled = false; void setup() { Serial.begin(9600); Wire.begin(); if (!sht31.begin(0x44)) { Serial.println(F("Nie znaleziono czujnika SHT-30!")); while (true) delay(1000); } } void loop() { unsigned long now = millis(); /* --- 1. SHT-30 co 30 s --- */ if (now - lastSht >= PERIOD_SHT_MS) { lastSht = now; float t = sht31.readTemperature(); float rh = sht31.readHumidity(); if (!isnan(t) && !isnan(rh)) { Serial.print(F("SHT:")); Serial.print(t, 1); Serial.print(','); Serial.println(rh, 1); } else { Serial.println(F("SHT_ERR")); } } /* --- 2. próbkowanie dźwięku co 0,2 s --- */ if (now - lastSound >= SOUND_STEP_MS) { lastSound = now; uint16_t raw = analogRead(PIN_SOUND); // 0-1023 soundBuf[soundIx++] = raw; if (soundIx >= SOUND_BUF_LEN) { // bufor pełny soundIx = 0; bufFilled = true; } if (bufFilled && soundIx == 0) { // co 18 próbek (3,6 s) uint16_t vMin = soundBuf[0]; uint16_t vMax = soundBuf[0]; for (uint8_t i = 1; i < SOUND_BUF_LEN; ++i) { if (soundBuf[i] < vMin) vMin = soundBuf[i]; if (soundBuf[i] > vMax) vMax = soundBuf[i]; } uint16_t amp = vMax - vMin; // amplituda Serial.print(F("WPSE:")); Serial.println(amp); // np. WPSE:187 } } } Teraz muszę jeszcze odebrać dane z portu USB Raspberry Pi 4 i wysłać to do Domoticza, program działa w pętli nieskończonej i musi być uruchomiony na starcie tylko raz. #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Odczyt danych z Arduino (SHT30 + czujnik dźwięku) po UART i wysyłka do Domoticz (idx: temperatura+wilgotność oraz sensor dźwięku). """ import serial import time import requests # ---------- KONFIGURACJA ---------- SERIAL_PORT = "/dev/ttyUSB0" BAUDRATE = 9600 DOMO_HOST = "localhost" DOMO_PORT = 8080 IDX_SHT = 4 # Temp + Hum (dummy) IDX_SOUND = 5 # Custom Sensor (General) USERNAME = "update" PASSWORD = "password" NVALUE = 0 # nvalue = 0 dla pomiarów liczbowych # ---------- FUNKCJE POMOCNICZE ---------- def humidity_status(rh: float) -> int: """Zwraca kod statusu RH zgodnie z Domoticz.""" if 40 <= rh <= 60: return 1 # Comfortable if rh < 30: return 2 # Dry if rh > 70: return 3 # Wet return 0 # Normal def domo_update(idx: int, svalue: str) -> None: """Wysyła pojedynczy odczyt do Domoticz.""" url = (f"http://{DOMO_HOST}:{DOMO_PORT}/json.htm" f"?type=command&param=udevice&idx={idx}" f"&nvalue={NVALUE}&svalue={svalue}") r = requests.get(url, timeout=10, auth=(USERNAME, PASSWORD)) r.raise_for_status() # ---------- INICJALIZACJA UART ---------- ser = serial.Serial(SERIAL_PORT, BAUDRATE, timeout=1) time.sleep(2) # Arduino resetuje się po ustawieniu DTR print("Start – oczekiwanie na dane z UART...") # ---------- GŁÓWNA PĘTLA ---------- while True: try: line = ser.readline().decode("utf-8", errors="ignore").strip() except serial.SerialException as e: print("Błąd portu szeregowego:", e) time.sleep(5) continue if not line: continue print("UART >", line) try: # ----- Pakiet SHT30 ------------------------------------------------- if line.startswith("SHT:"): # Oczekiwany format z Arduino: "SHT:23.4,46.7" try: temp_str, rh_str = line[4:].split(",") temp = float(temp_str) rh = float(rh_str) except ValueError: print("Błędny format SHT:", line) continue h_stat = humidity_status(rh) # Domoticz wymaga: "temp;humidity;humidity_status" svalue = f"{temp:.2f};{rh:.1f};{h_stat}" domo_update(IDX_SHT, svalue) # print("↑ Domoticz SHT", svalue) # ----- Pakiet natężenia dźwięku ------------------------------------ elif line.startswith("WPSE:"): # Oczekiwany format: "WPSE:512" try: raw = int(line[5:]) except ValueError: print("Błędny format WPSE:", line) continue domo_update(IDX_SOUND, str(raw)) # print("↑ Domoticz SOUND", raw) # ----- Nierozpoznany prefiks --------------------------------------- else: print("Nieznany format:", line) except requests.RequestException as e: print("Błąd HTTP:", e) # ­Niewielka pauza odciążająca CPU time.sleep(0.05) Ostatnią rzeczą jest konfiguracja crona, aby regularnie przesyłać dane co minutę: * * * * * /home/norbert/domoticz/myscrypts/temp1.py * * * * * /home/norbert/domoticz/myscrypts/temp2.py * * * * * /usr/bin/python3 /home/norbert/domoticz/myscrypts/sht30.py Dane, które są przesyłane z Arduino do Rasperry Pi 4 są realizowane jako zwyczajna usługa linuksa, poniżej jej konfiguracja: [Unit] Description=Arduino ↔ Domoticz bridge After=network-online.target Wants=network-online.target [Service] Type=simple User=norbert # Użytkownik musi być w grupie „dialout”, żeby otworzyć /dev/ttyUSB0 Group=norbert ExecStart=/usr/bin/env python3 /home/norbert/domoticz/myscrypts/arduino2domoticz2.py WorkingDirectory=/home/norbert/domoticz/myscrypts Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target
  2. Wie ktoś może czy toto działa przez metalowe ścianki pojemnika? https://botland.com.pl/pl/czujniki-poziomu-cieczy/6931-dfrobot-gravity-czujnik-poziomu-cieczy-bezkontaktowy.html
×
×
  • Utwórz nowe...