Skocz do zawartości

Przeszukaj forum

Pokazywanie wyników dla tagów 'raspberry pi'.

  • 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

  1. Cześć, niedawno, zachęcony jakością kursu Arduino, postanowiłem skorzystać z kursu Raspberry Pi z Forbota. Zakupiłem zestaw elementów oraz Raspberry Pi 5. Niestety, kluczowe informacje zawarte w kursie (takie jak obsługa kamery i sterowanie pinami) okazały się być nieaktualne dla najnowszych urządzeń. Nie chcę jednak porzucać tematu i chować maliny do szafy, stąd pytanie - czy polecacie jakieś książki lub inne kursy, które będą aktualne i przystępne dla osoby początkującej?
  2. Przeglądając listę możliwych integracji Home Assistant w większości jest tam to czego potrzebujemy. Sam byłem w szoku, gdy aplikacja podpowiedziała mi integrację z tunerem audio, o którym bym nawet nie pomyślał że się do tego nadaje. Problem pojawia się, gdy wymyślimy sobie własne DIY, które robi coś unikatowego i chcemy to podłączyć pod automatykę domowa. Jedną z metod jest użycie Template Switch (czyli takiego wirtualnego przełącznika) i powiązanie go funkcją lambda z np. komponentem magistrali UART i komunikowanie się z naszym DIY. Problem w tym, że będziemy musieli poświęcić cały układ WiFi na pomost pomiędzy DIY, a centralką HA. W tym artykule postaram się nakreślić, jak zacząć pisać własne komponenty do ESPHome. Przygotowanie Niby jest do tego instrukcja (custom sensor i custom generic component), ale mimo wszystko po przeczytaniu tego co tam zamieszczono, przejrzeniu przykładów, zapytaniu na oficjalnym kanale na Discordzie, odpowiedź znalazłem dopiero na szarym końcu internetu. Wyjdźmy od tego jak tworzymy aplikacje (wsad np. do ESP8266 tu ESP-01S). Mając postawiony HA i zainstalowany dodatek ESPHome, dodajemy nowy sprzęt: Wybieramy nazwę: Rodzaj płytki: Pomijamy wgrywanie, bo trzeba zmienić coś w konfiguracji. Wybieramy więc edit: Mamy tu kilka domyślnych ustawień: esphome: name: spectrum-display esp8266: board: esp01_1m # Enable logging logger: # Enable Home Assistant API api: ota: password: "xxx" wifi: ssid: !secret wifi_ssid password: !secret wifi_password # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "xxx" password: "xxx" captive_portal: Nazwa - potrzebna do mDNS jako hostname. Niestety po aktualizacji coś słabo działa. Na stronie ESPHome sugeruje się używanie statycznego IP, które ma też przyspieszać łączenie: Dlatego dodajemy fragment dotyczący stałego IP: wifi: ssid: !secret wifi_ssid password: !secret wifi_password manual_ip: static_ip: 192.168.0.102 gateway: 192.168.0.1 subnet: 255.255.255.0 # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "xxx" password: "xxx" Co w efekcie zobaczymy w logu: Hasło do WiFi mamy ustawione w ESPHome (secrets). Zapisujemy, wgrywamy podłączając urządzenie przez USB lub wgrywając używając OTA, oczywiście jeżeli znamy hasło i adres urządzenia. W moim przypadku jest ta druga opcja: Gotowe komponenty Komponent to pewna funkcjonalność (nawet bardzo rozbudowana). Np. może to być przełącznik światła dołączonego do konkretnego wyprowadzenia (patrz przykład). W przypadku bardziej rozbudowanych komponentów, np. obsłudze protokołu komunikacji, obsługa zawęża się do wskazania urządzenia (np. DS18B20 1-wire) i podania wyprowadzenia. Takich komponentów możemy dodawać wiele i będą działać niezależnie od siebie. To tak jakbyśmy uruchomili wiele współbieżnych procesów. W praktyce wygląda to bardziej jak kod Arduino, w którym przy pomocy funkcji millis() wykonujemy "współbieżnie" wiele funkcji. Podstawy za nami. Teraz konfigurację można wzbogacić o jakieś podstawowe komponenty. Przykładowo kod do sterowania diodą na płytce pod pinem 2: # Enable Home Assistant API api: light: - platform: binary name: "Onboard LED" output: onboard_led_out output: - id: onboard_led_out platform: gpio pin: GPIO2 Id posłuży nam do dodania tzw. encji czyli kontrolki na panelu widocznym w Home Assistant. Wgrywamy i przechodzimy do głównej strony i edytujemy widok panelu: Od razu widzimy encję: Modyfikujemy wedle uznania: i gotowe! Możemy poklikać w nowo dodany przycisk. Najpewniej logika przycisku będzie odwrócona ze względu na sposób podłączenia LED na płytce ESP-01S. Możemy zmienić to w konfiguracji: output: - id: onboard_led_out platform: gpio pin: GPIO2 inverted: true I działa Własny komponent Napisanie własnego komponentu nie jest aż tak trudne. Autorzy uznali, że będą wzorować się na koncepcji kodu Arduino , w którym można wyróżnić bloki setup() i loop(). Problem w tym, że nie wiadomo gdzie zapisać te pliki. Na stronie z poradnikiem tworzenia własnych komponentów jest co prawda informacja: Ale niewiele to wnosi, bo nigdzie nie jest napisane gdzie jest ten katalog... Z pomocą przychodzi test przykładowej konfiguracji, w której chcę dodać jakiś plik: Czyli jest to ścieżka: /config/esphome/ Sprawdźmy jak wygląda zawartość tego katalogu, tylko zanim do teog przejdziemy, potrzeba nam SSH - bo w systemie HA nie ma domyślnie takich udogodnień. W repozytorium znajdujemy SSH, ustawiamy hasło i możemy się zalogować. Użytkownik root, hasło własne, port 22. Używam polecenie ls z dopiskiem -a, aby wyświetlić ukryte pliki i katalogi: la -a /config/esphome/ W tym miejscu można umieścić własne pliki bibliotek - tuż obok widzimy plik yaml konfiguracji. Ja swoje pliki umieszczam w katalogu custom_components tak by nie tworzyć bałaganu: Wewnątrz katalogu tworzę plik fps_meter.h: touch fps_meter.h Do pracy korzystam z WinSCP i VSC - zapis pliku w VSC od razu zdalnie go aktualizuje: Dla testu wpisuję kod służący do wyznaczania częstotliwości odświeżeni: #include "esphome.h" class FPSCounter : public Component, public Sensor { private: const unsigned long INTERVAL = 5000; unsigned long counter; unsigned long last_millis; float fps; public: float get_setup_priority() const override { return esphome::setup_priority::LATE; } void setup() override { last_millis = millis(); int last_button_state = HIGH; } void loop() override { if(millis() - last_millis > INTERVAL) { fps = (1000.0 * counter) / (millis() - last_millis); ESP_LOGD("FPS_COUNTER", "%lu sec passed, FPS: %f", INTERVAL, fps); publish_state(fps); counter = 0; last_millis = millis(); } ++counter; } }; I zapisuję. Do tego jak działa ten kod jeszcze wrócimy, ale na razie istotne jest, że w pętli wykonywane jest sprawdzenie częstości odświeżania i okresowo informacja wysyła jest do HA. Komponent jest czujnikiem (dziedziczy po klasie Sensor) ponieważ zwraca pewne informacje do centralki. Teraz trzeba użyć naszą klasę. Przechodzimy do konfiguracji i najpierw dodajemy plik biblioteki: esphome: name: spectrum-display includes: - custom_components/fps_meter.h oraz tworzymy komponent: api: sensor: - platform: custom lambda: |- auto fps_meter = new FPSCounter(); App.register_component(fps_meter); return {fps_meter}; sensors: name: "FPS counter" light: - platform: binary name: "Onboard LED" output: onboard_led_out output: - id: onboard_led_out platform: gpio pin: GPIO2 inverted: true Dodajemy typ sensor (to po czym dziedziczy nasz komponent), a w funkcji lambda korzystamy ze zdefiniowanej klasy FPSCounter. Dodajemy też nazwę, która może nam się przydać. Wgrywamy nowy kod i w logu zobaczymy, że coś zostało wyznaczone - mamy częstotliwość odświeżania około 60Hz: Możemy też znaleźć nasz "czujnik" wśród encji: i nasze obie kontrolki działają, powiedzmy "równolegle" Kod programu Wracając na chwilę do kodu programu: #include "esphome.h" class FPSCounter : public Component, public Sensor { public: float get_setup_priority() const override { return esphome::setup_priority::LATE; } void setup() override { } void loop() override { }; widzimy, że szablon jest dość prosty. Tworzymy klasę, która dziedziczy po komponencie i sensorze, aby móc wysyłać informacje (dostępna staje się wtedy metoda publish_state(). Jak wspomniałem setup i loop to metody, które możemy uzupełnić kodem wykonywanym odpowiednio przy starcie i cyklicznie. get_setup_priority() służy ustaleniu jaki priorytet ma nasza klasa. Możliwych narzędzi jest naprawdę wiele, zainteresowanych odsyłam do lektury dokumentacji i analizy przykładów. Kod klasy możemy rozbić na osobne pliki .cpp i .h. Warto jeszcze wspomnieć o czymś, co mnie bardzo mocno zmyliło - o bibliotekach/narzędziach deweloperskich ESPHome. W kodzie widzimy, że dodajemy plik esphome.h, ale nie jest to biblioteka: W pliku tym mamy podlinkowane biblioteki, które będziemy używać, a sam plik wygenerowany zostanie automatycznie... zostanie, ponieważ nasza biblioteka jest w katalogu /config/esphome, ale przed kompilacją jest kopiowana do katalogu projektu: Czyli dla powtórzenia: nasze pliki bibliotek trzymamy w głównym katalogu np. /config/esphome/custom_components/ w pliku .yaml dodajemy ścieżkę: custom_components/plik_biblioteki.h w kodzie pliku plik_biblioteki.h dodajemy esphome.h jakby był tuż obok, bo przed kompilacją zostanie tam przekopiowany tworząc kod pamietamy żeby podlinkować zawartość katalogu src Kuszące może być edytowanie zawartości katalogu src jednak tu uwaga w pliku README.txt: THIS DIRECTORY IS AUTO-GENERATED, DO NOT MODIFY ESPHome automatically populates the build directory, and any changes to this directory will be removed the next time esphome is run. For modifying esphome's core files, please use a development esphome install, the custom_components folder or the external_components feature. Oznacza to, że ten katalog jest wygenerowany automatycznie na bazie pliku .yaml i nie powinniśmy w nim nic mieszać.
  3. 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
  4. Cześć, Chciałem pokazać Wam mój projekt, który powstał głównie dla frajdy. Co dokładnie robi ten system? Pozwala z poziomu aplikacji Android: - włączać i wyłączać przekaźniki (np. światła w akwariach), - ustawiać harmonogram działania (czas startu i końca) dla pierwszego przekaźnika (z ogólnie 4 możliwych). Od strony tzw. "backendu": - Raspberry Pi 5 ma uruchomione mosquitto (MQTT), które dostępne jest na publicznym IP przez port TLS (8883) - mam więc dostęp do tego systemu w sposób (stosunkowo) bezpieczny, z dowolnego miejsca na świecie, z pomocą telefonu. - Całość komunikacji jest szyfrowana (zarówno mosquitto, apka na Androidzie, jak i urządzenia docelowe z Pico W korzystają z certyfikatów x509). Dodatkowo na brokerze jest login i hasło. Dodatkowo na Raspberry działa fail2ban, więc łatwo do systemu włamać się nie da. Procedura generowania kluczy opisana jest w README w repozytorium projektu. Dodatkowy bajer: urządzenia Pico W są wykrywane automatycznie – bez ręcznego dodawania ich do aplikacji Androidowej. Zajmuje się tym demon systemowy na Raspberry (aqua_topic_provider/provider.c). Lista wykrytych urządzeń wysyłana jest następnie do brokera MQTT, który udostępnia listę wykrytych urządzeń dla każdego zainteresowanego klienta (tu - aplikacja Android). Dodanie nowego urządzenia do systemu jest więc stosunkowo proste: Dla każdego nowego urządzenia z Pico W wystarczy lekko zmodyfikować konfigurację firmware (dodać sprzętowy MAC Pico W, ilość przycisków (przekaźników) oraz (dowolną) nazwę hosta - pod tą nazwą urządzenia występują na liście w aplikacji na Androidzie). Potem wystarczy skompilować, wgrać na Pico W, i tyle - apka na Androidzie po chwili pokaże nowe urządzenie na liście. Więcej info w readme na repo: pliki (Credentials.h / MacHostMapping.cpp) Architektura systemu System składa się z trzech głównych komponentów: 1. Raspberry Pi Pico W – jednostka wykonawcza: - steruje przekaźnikami, - reaguje na fizyczne przyciski, - obsługuje MQTT przez TLS (PubSubClient + WiFiClientSecure), - synchronizuje czas lokalny przez NTP (protokół pobierania aktualnego czasu z internetu), - nasłuchuje na UDP 0.0.0.0 (wszystkie interfejsy lokalne) / port 12345 - by dać się wykryć, - maszyna stanów obsługuje cykl życia aplikacji. Urządzenia wyglądają trochę topornie, ale to nie musi być piękne, tylko ma działać Program na Pico W korzysta z frameworka arduino-pico / https://github.com/earlephilhower/arduino-pico Do tego Arduinowy driver OLED (Adafruit_SSD1306), WiFi, MQTT (PubSubClient). Jest też zaimplementowana opcja update firmware urządzeń z Pico W przez OTA (ArduinoOTA). Całość firmware napisana jest jednakże w c++ (jedyny plik .ino ma raptem kilka linijek), i gdzieś mi chodzi po głowie by oddzielić biblioteki Arduino w osobnym module, i kiedyś zmigrować całość na jakieś inne środowisko, ale ogólnie chyba nie ma to sensu - systen działa stabilnie i bezproblemowo 24/7). 2. Raspberry Pi 5 – serwer i broker: - działa tu Mosquitto (MQTT broker), - demon w C cyklicznie wysyła pakiety UDP ("AQUA_DISCOVER" na 239.255.255.250:12345), (wspomniany wyżej provider.c) - Pico W odpowiada pakietem UDP "AQUA_FOUND|MAC|IP|hostname|amountOfSwitches" (DiscoverMe.cpp), - na podstawie tych odpowiedzi budowany jest JSON i publikowany na topicu: AQUA_DEVICES_UPDATE Przykładowa odpowiedź: { "devices": [ { "mac": "28:cd:c1:05:b8:76", "ip": "10.8.0.2", "hostName": "akwarium_duże_w_salonie", "switches": 1 }, { "mac": "28:cd:c1:05:b8:64", "ip": "10.8.0.3", "hostName": "akwarium_bojowniki_w_salonie", "switches": 2 } ] } 3. Aplikacja Android – interfejs użytkownika: - napisana głównie w Javie (bo lubię), z drobnymi elementami w Kotlinie, - korzysta z Eclipse paho w trybie klienta MQTT (org.eclipse.paho.client.mqttv3) - zapisuje się na główny topic AQUA_DEVICES_UPDATE, i później na pomocnicze topici AQUA_DEVICE_* - na tej podstawie buduje listę urządzeń widoczną w aplikacji, - każde urządzenie dostaje pozycję na liście (nazwa, przełączniki, przycisk ustalania harmonogramu). - komunikacja jest dwukierunkowa - czyli w apce włączam/wyłączam przekaźniki w urządzeniach, a w urządzeniach naciśnięcie danego przycisku odświeża stan switcha w apce w czasie rzeczywistym. Komunikacja przez brokera Gdy użytkownik: - zmienia stan przekaźnika (np. ON/OFF), - ustawia nowy harmonogram (np. 7:00–22:00), aplikacja Android publikuje odpowiedni JSON na MQTT: Włączanie przekaźnika: Topic: AQUA_DEVICE_SWITCH_SET/akwarium_duże_w_salonie { "isOn1": true } Ustawienie harmonogramu: Topic: AQUA_DEVICE_TIME_SET/akwarium_duże_w_salonie { "dateHourStart": 420, "dateHourEnd": 1320 } Te liczby to po prostu ilość minut od godziny 0:00. Pico W odpowiada statusem: Topic: AQUA_DEVICE_STATUS/akwarium_duże_w_salonie { "status": "ok", "dateHourStart": 420, "dateHourEnd": 1320, "isOn1": true [...] } Aplikacja na Pico W sama decyduje, czy pierwszy przekaźnik ma być włączony/wyłączony na podstawie lokalnego czasu i ustawionego harmonogramu. Można oczywiście ręcznie ten przekaźnik włączyć/wyłączyć, ale ostatecznie o określonych godzinach jego stan zostanie nadpisany przez ustalony harmonogram. Oczywiście prócz tego Pico W działają w pełni autonomicznie. Broker w tym przypadku służy tylko do ustawiania parametrów, i kontroli stanu przycisków przez aplikację. Pliki konfiguracyjne + submoduł W repozytorium nie ma plików z danymi wrażliwymi. Sam projekt wymaga by sklonować go z odświeżeniem submodułów: git clone --recurse-submodules https://github.com/jaszczurtd/lights-timer.git Ważne jest, by zawartość folderu "libraries" przekopiować do folderu "libraries" zarządzanego przez Arduino. Ważne jest również by odpowiednio skonfigurować i uzupełnić zawartość plików libraries/Credentials/ca_cert.c, oraz libraries/Credentials/MacHostMapping.h/.cpp – trzeba je dostosować do: - nazwy i hasła WiFi, - loginu/hasła/ip (domeny) do brokera MQTT, - certyfikatu x509 - przypisania MAC → hostname i liczby przekaźników. Sama wersja Arduino IDE z której korzystam to 2.3.x. Nie wiem czy to zadziała z wcześniejszymi wersjami. Po resztę informacji odsyłam do README w repozytorium. Dlaczego w ogóle to zbudowałem? Oczywiście wiem, że istnieją gotowe systemy smart home, które to wszystko robią lepiej, i pewnie jeszcze więcej – ale nie w tym rzecz. Prócz samej chęci tworzenia, jestem jednym z tych, którzy chcą mieć sterowanie domem w komórce, ale maja awersję do chmur wszelakich - stwierdziłem że nie chcę żeby światło w moich akwariach zależało od jakiegoś serwera cholera wie gdzie, albo nawet w Chinach. I najważniejsze - lubię malinki. Jedna chodzi 24/7, i robi za domowe centrum sterowania wszechświatem, więc idealnie nadaje się jako pośrednik dla tego systemu. I jeszcze pewnie odpowiedź na pytanie które się kołacze w głowie niejednego z was - ten projekt może się wydawać swoistym overkillem w temacie zdalnego włączania przekaźników. I tak pewnie by było, gdyby chodziło tylko o te przekaźniki. Ale struktura tego projektu i całe środowisko tak naprawdę zbudowałem z myślą o kilku ciekawszych rzeczach, którymi się pochwalę w przyszłości, i przy których to całe security, brokery, discovery itp, jest po prostu niezbędne. A co planuję dodać jeszcze do tego konkretnego projektu? - na pewno konfigurację WiFi dla Pico W z poziomu urządzeń (teraz trzeba to zmieniać w źródłach), - będzie pomiar temperatury wody w akwariach, - przyda się sterowanie chłodzeniem/grzaniem wody w akwariach, - może rozbuduję harmonogram, - reszta pomysłów jest na razie tajna Na razie moja żona (zapalona akwarystka) nie zgłasza konkretnego, dodatkowego zapotrzebowania, więc chwilowo zostaje tak jak jest. Ale to się wkrótce zapewne zmieni. Chętnie odpowiem na pytania, wyjaśnię dlaczego coś jest tak, a nie inaczej, etc. Pewnie są jakieś bugi, których chwilowo nie wykryłem, pewnie są miejsca które można lepiej ogarnąć, wiadomo. Repozytorium kodu https://github.com/jaszczurtd/lights-timer Pozdrawiam! Marcin (jaszczurtd)
  5. Cześć, Chciałbym podzielić się projektem, który pochłonął mnie na ostatnie tygodnie – w pełni autonomiczny sterownik nawadniania do ogórków. Wszystko zaczęło się od prostego problemu: mam dość dużą działkę i zbiornik na deszczówkę, ale jest on oddalony od miejsca, które wymaga podlewania o jakieś 50 metrów, a do tego muszę pokonać różnicę wysokości około 3-5 metrów. Ręczne noszenie wody odpadało. Głównym założeniem było stworzenie urządzenia, które będzie w pełni konfigurowalne bez podłączania do komputera. Chciałem mieć możliwość zmiany harmonogramów podlewania, uruchamiania pompy ręcznie czy ustawiania pauzy w deszczowe dni, stojąc bezpośrednio przy urządzeniu. Wykorzystane moduły i komponenty Sercem projektu jest mikrokontroler Raspberry Pi Pico, a dokładnie Pico RP2040, programowany w MicroPythonie. Wybrałem go ze względu na dużą elastyczność i dwa niezależne porty I2C, co – jak się później okazało – było zbawieniem przy projektowaniu płytki PCB. Oto pełna lista kluczowych komponentów: Mikrokontroler: Raspberry Pi Pico Wyświetlacz: Ekran OLED 128x64 I2C (oparty na SSD1306) Zegar czasu rzeczywistego (RTC): Moduł DS3231 I2C podobny do tego (ostatecznie okazał się uszkodzony i projekt działa na wewnętrznym RTC Pico) Czujnik: Moduł AHT10 I2C do pomiaru temperatury i wilgotności powietrza ale równie dobrze może być AHT20 Moduł przekaźnika 1-kanałowy Element wykonawczy: Moduł przekaźnika 5V, sterujący pompą Interfejs użytkownika: 4 przyciski typu tact-switch (Góra, Dół, OK, Wstecz) System zasilania: Panel fotowoltaiczny 100W Regulator ładowania PWM 10A z wyjściami USB Akumulator żelowy 12V 18Ah Pompa: Membranowa pompa ciśnieniowa 12V 72W Droga od pomysłu do działającego urządzenia wymagająca. To mój pierwszy tak złożony projekt i nauczyłem się niesamowicie dużo, głównie na własnych błędach. Zaczęło się klasycznie – od prototypu na płytce stykowej. Plątanina kabli była ogromna, ale pozwoliła mi na napisanie i przetestowanie podstawowej wersji oprogramowania. Kod, napisany w MicroPythonie, rozrósł się do sporej maszyny stanów, która zarządza menu, harmonogramami i wszystkimi peryferiami. Kolejnym wyzwaniem było zaprojektowanie własnej płytki PCB w programie KiCad. To był mój debiut. Przejście od schematu do projektu ścieżek na jednej warstwie było jak rozwiązywanie trudnej łamigłówki. Każda ścieżka, która blokowała drogę innej, zmuszała do przemyślenia układu od nowa. Ostatecznie, aby ułatwić sobie życie, wykorzystałem oba porty I2C w Pico, co znacząco uprościło prowadzenie ścieżek. Płytkę wykonałem metodą termotransferu. Efekt końcowy moje ogórki.zip Po wielu wieczorach spędzonych na lutowaniu, debugowaniu i pisaniu kodu, powstało w pełni działające urządzenie zamknięte w szczelnym pojemniku na żywność. Sterownik realizuje wszystkie założone funkcje: Wyświetla aktualny status, czas i odczyty z czujnika. Uruchamia pompę zgodnie z dwoma, w pełni edytowalnymi harmonogramami. Pozwala na ręczne włączenie i wyłączenie pompy. Posiada funkcję pauzy na wybraną liczbę godzin na wypadek deszczu. Wszystkie ustawienia są zapisywane w pamięci Pico i nie giną po zaniku zasilania. W następnym roku na pewno użyję mocniejszej pompy Jestem świadomy, że użyłem dużo gluta ale jak wiecie, bez hot gluta nie ma DIY Zdjęcia z produkcji a w ZIPie finalny filmik
  6. Cześć. O prawie roku pracuję nad demem (https://pl.wikipedia.org/wiki/Demoscena) na Raspberry Pi Pico 2, na potrzeby którego rozwijam silnik graficzny. Projekt bazuje na demach, które w poprzednich dwóch latach napisałem w lua na Pico-8. Projekt jest napisany w C. Mam też kilka dodatkowych tooli napisach w pythonie, np. do zapisania pliku bmp jako array czy do zapisania pliku obj z modelem jako instancję. Feature'y: Renderer 3D Modele podlegają 3 podstawowym transformacjom - translacja, rotacja, skalowanie. Oprócz tego jest texture mapping (jeszcze z dem na Pico-8), zaimplementowałem cieniowanie Gourdauda i zBuffer. Pozycja pikseli na ekranie wyliczana jest użyciem macierzy widoku i perspektywy Arytmetyka stałoprzecinkowa, wektorowa. Coś tam jest też do macierzy, ale i też jakiś czas temu na potrzeby rotacji dodałem funkcje dla kwaternionów. Fabryki do budowania modeli, kamer i źródeł światła. Modele mają materiały, w tej chwili ograniczają się tylko do tekstury i diffuse. Osobna biblioteka do rysowania pikseli na frame bufferze, rysowania spritów na frame bufferze i wysyłanie frame buffera do ekranu. Biblioteki do zarządzania ekranem. Modele, sprity i tekstury są przechowywane w kodzie w const arrayach, żeby jako storage używać pamięci flash. Odtwarzanie muzyki z karty pamięci sd z plików wav. Tutaj było sporo gimnastyki, bo używam modułu, który ma i czytnik i ekran. Do samego grania dźwięku wziąłem kod z pico-extras. Do obsługi systemu plików na sd używam biblioteki FatFs by ChaN. Żeby jakoś tam zgrać czytanie danych z karty z rysowaniem na ekranie używam spinlocków Używam wskaźników do funkcji, żeby potencjalni przyszli użytkownicy mogli wstawiać swój kod, żeby chociażby użyć innego ekranu. Efekty postprocesowe. Na ten moment ze względu na demo mam jako jeden efekt aberrację chromatyczną, barrel distortion i scanline. Funkcja nakładająca efekt może zostać rozszerzona, żeby użyć czegokolwiek. W tej chwili pracuję nad animacją szkieletową 2D. Dodałem już rysowanie spritów i obracanie ich o dowolny kąt. Efektu końcowego na razie nie będę mógł pokazać, bo używam assetów, narysowanych do dema. Części użyte w projekcie: Raspberry Pi Pico 2 - https://botland.com.pl/moduly-i-zestawy-do-raspberry-pi-pico-2/25311-raspberry-pi-pico-2-rp2350-arm-cortex-m33-5056561803951.html Ekran - https://botland.com.pl/raspberry-pi-pico-hat-klawiatury-i-wyswietlacze/19718-ekran-dotykowy-rezystancyjny-lcd-ips-28-320x240px-spi-65k-rgb-do-raspberry-pi-pico-waveshare-19804-5904422347246.html Moduł audio - https://botland.com.pl/pozostale-moduly-do-raspberry-pi-pico/20096-rozszerzenie-audio-2x-glosnik-5w-do-raspberry-pi-pico-waveshare-20167-5904422351847.html Ekspander - https://botland.com.pl/raspberry-pi-pico-hat-ekspandery-wyprowadzen/18872-pico-omnibus-podwojny-ekspander-wyprowadzen-do-raspberry-pi-pico-769894017210.html Niestety tylko daję gifa, bo póki co nie trzymam filmików z projektem na yt. Kodu źródłowego na ten moment nie chcę jeszcze udostępniać, ale jak tylko demo zostanie pokazane w sierpniu na demoparty Xenium to się to zmieni.
  7. Cześć wszystkim! Chciałem się z Wami podzielić pomysłem na kanał YouTube, który planuję stworzyć. Chciałbym dokumentować krok po kroku proces tworzenia mikrokomputera – od zaprojektowania schematu, przez tworzenie systemu, aż po produkcję PCB i składanie gotowego urządzenia. Moim celem jest pokazanie całego procesu, aby inni, którzy interesują się elektroniką i projektowaniem, mogli zobaczyć, jak to wygląda w praktyce. Zanim ruszę z pierwszymi materiałami, chciałem zapytać Was, czy taki pomysł wydaje się ciekawy. Co sądzicie o tworzeniu filmów, które szczegółowo przedstawiają cały proces, w tym projektowanie, lutowanie, programowanie i testowanie mikrokomputera? Myślicie, że to coś, co mogłoby zainteresować społeczność, czy lepiej skupić się na innych tematach? Myślę o krótkich filmach typu shorts, które szybko wprowadzają w temat, a później o pełnych materiałach z dłuższym omówieniem szczegółów. Czekam na Wasze opinie i sugestie!
  8. Cześć wszystkim właśnie rozpoczynam kurs z obsługi raspberry Pi Pico i utknąłem na etapie kompilacji plików w VSC, a mianowicie nie pojawia mi sie "all" pod "build", "debug" i "launch" i nie potrafie poprawnie przejść kompilacji bo wyskakują błędy. wiem, że to dopiero początek przygody a ja już nie ogarniam, ale proszę o pomoc bo bardzo interesuje mnie temat programowania i majsterkowania, a nie chce dać za wygraną z góry dziękuję za pomoc
  9. Chciałbym przedstawić mój projekt, który traktuję jako hobbystyczny, będący w rozwoju od kilku dobrych lat, w zależności od tego na co pozwala mi tzw. "normalne życie", i wszelakie ograniczenia z nim związane. Jestem pasjonatem motoryzacji wszelakiej. Odkąd zrobiłem prawo jazdy, i zderzyłem się z przykrą rzeczywistością polskich warsztatów, i tego jak one traktują klienta, i swoją pracę, zacząłem się interesować kwestiami serwisu, budowy silników, i wszystkiego co z tym związane. Zaczynałem od etapu "otwieram maskę, i nie do końca wiem na co patrzę". Obecnie własnoręcznie buduję silniki, wraz z elektroniką sterującą. Moim pierwszym autem był Ford Escort z silnikiem 1.8D. Stara, wolnossąca jednostka, która nie miała żadnej elektroniki sterującej. Czysta mechanika. Przejechałem tym autem dziesiątki tysięcy kilometrów. Mam zarówno do tego auta jak i tego konkretnego silnika sentyment, pomimo że był wolny, stosunkowo głośny, i problematyczny w zimie. Kilkanaście lat temu wpadłem na pomysł, by "dla sportu" rozebrać ten silnik (kiedy miałem już inne auto oczywiście), i zobaczyć jak to wszystko jest zbudowane od wewnątrz. Miałem wtedy już jakieś doświadczenie z mechaniką silnikową - nie sprawiało mi problemu np. by wymienić rozrząd, itp. Ale jak to ja, stwierdziłem że to za mało - jak już rozbiorę ten silnik, to spróbuję go złożyć na nowo... ulepszając. I tak narodził się mój projekt - zbudowałem sobie hybrydę 1.8D/TD/TDDI (dla fordziarzy dieslowców te skróty coś faktycznie oznaczają! ), a wchodząc głębiej w szczegóły - był to silnik który zachowując zelety pancerności starego 1.8D, wprowadzał jedną, podstawową modyfikację - zmianę sposobu wtrysku paliwa z tzw. "pośredniego" na "bezpośredni". Z tym wiązało się mnóstwo innych rzeczy które trzeba było ogarnąć - np. pompa wtryskowa, wtryskiwacze, turbo, ustawienie tego wszystkiego... No ale zaraz zaraz. Co to ma wszystko wspólnego z tym portalem (bynajmniej nie motoryzacyjnym)? Bo w międzyczasie narodził się pomysł, by do tego silnika (który finalnie wylądował w starej, ale odnowionej blacharsko Fieście), zbudować coś na kształt ECU. Na początku plany były skromne - ot, chciałem mieć ładną wizualizację parametrów silnika. Temperatura, ciśnienie doładowania... Zamiast kilku wskaźników montowanych nie wiadomo gdzie, nie pasujących do auta (miłośnicy tunningu wiedzą o czym piszę), fajnie by było mieć to wszystko na jednym wyświetlaczu. I tak narodziło się to: Na początku był to stosunkowo prosty układ, który głównie odpowiedzialny był za monitorowanie temperatury (chłodziwa/oleju), dolotu, ciśnienia doładowania, temperatury spalin, obrotów silnika, i obciążenia, które w późniejszym etapie wykorzystałem do sterowania turbiną o zmiennej geometrii. Projekt powoli się rozrastał. Pozwolił mi na zestrojenie auta tak, że uzyskałem ok. 170KM. Niestety, z czasem zaczęły mi przeszkadzać ograniczenia - mały rozmiar wyświetlacza, dodatkowo zacząłem myśleć o rezygnacji z mechanicznej pompy wtryskowej, która jest ograniczona w temacie regulacji dawki paliwa, czy kąta wtrysku (przy takiej mocy niestety nieuniknione było dymienie w pewnych sytuacjach). I o ile implementacja nowego wyświetlacza to szczegół praktycznie nie warty wspominania, tak migracja w stronę pompy sterowanej elektronicznie to już wyższy poziom. Pierwsza wersja mojego "ECU" pracowała w oparciu o płytkę ItsyBitsy M0 (z mikrokontrolerem ATSAMD21). To fajna płytka do małych projektów. Jednakże docelowo użyłem tutaj Raspberry pi pico - względem ItsyBitsy jest to spory upgrade - wiecej CPU (dwa rdzenie), więcej pamięci, więcej wszystkiego. Całość pracuje niby pod kontrolą Arduino - piszę niby, bo korzystam raptem z kilku bibliotek (CAN, wyświetlacz), ale powoli tworzę swoistego HALa który umożliwi mi uruchomienie tego kodu pod dowolną platformą. Wyświetlacz był do niedawna częścią sterownika, jednak w momencie rozpoczęcia implementacji pompy VP37, kod odpowiedzialny za wyświetlanie zmigrowałem do osobnego moduły, który czyta wartości wystawiane przez ECU za pomocą magistrali CAN. Być może opowiem o tym module za jakiś czas, bo po niewielkiej modyfikacji można by go zaadoptować w zasadzie do każdego auta z magistralą CAN które wystawia na niej odpowiednie ramki. Co do samego tematu sterowania pompą VP37, to jest to coś, co może zainteresować tutaj więcej osób niż tylko te związane z motoryzacją. Oto ogólny widok na pompę, tak by było wiadomo o czym w ogóle mowa (normalnie są brudne, w kolorze aluminiowym. ) Pod tym czerwonym kapturkiem znajduje się część pompy, która nas najbardziej interesuje. Jest to tzw. elektromagnetyczny nastawnik (ilości paliwa). W praktyce jest to masywna cewka, którą steruje ECU za pomocą PWM. Ogólny koncept wydaje się prosty, ale diabeł, jak to mówią, tkwi w szczegółach. W internecie dostępnych jest sporo filmów które pokazują jak sterować takim nastawnikiem, ja osobiście również coś tam nagrałem: W teorii wydaje się to być proste - ot, generujemy falę prostokątną o określonych parametrach, lub dobranych doświadczalnie, i tyle. Jednak jest to znacznie bardziej skomplikowane w praktyce. Po pierwsze, nastawnik jest elementem bardzo nieliniowym, skłonnym do generowania oscylacji, z racji posiadania sprężyn, których podstawową funkcją jest sprowadzenie nastawnika do pozycji spoczynkowej w momencie gdy np. zostanie odłączone napięcie zasilania (zgaszenie auta). Po drugie - jest to element pracujący w dosyć skrajnym środowisku - jest wypełniony paliwem, pracujący ze zmieniającą się temperaturą w sporych zakresach, narażony na wibracje wszelkiego rodzaju. Do tego dochodzą jeszcze fluktuacje napięcia zasilającego cewkę. No i po trzecie - nie wystarczy go sobie ot tak ustawić "na pałę" i liczyć na to że będzie dobrze. ECU musi wiedzieć w jakim położeniu znajduje się nastawnik, bo na tej podstawie regulowana jest dawka paliwa, co związane jest z przyśpieszeniem, mocą, obrotami jałowymi, itp. Już nie brzmi aż tak prosto. Co przychodzi na myśl w kwestii sterowania? Samą cewką nastawnika steruje się prosto - wystarczy driver na jakimś porządnym mosfecie, z driverem na bramce, którym steruje mikrokontroler. Elementem niezbędnym jest tu mocna dioda Schottky’ego, która służy tutaj do tłumienia przepięć indukowanych w uzwojeniu cewki podczas pracy układu. W przypadku tej cewki ma ona naprawdę sporo do roboty. A od strony programowej? Wiadomo, pierwsze co przychodzi do głowy to nieśmiertelny PID. Oczywiście nie jest to taka "najprostsza" implementacja, u siebie mam np. implementacje różniczkowania z filtrem dolnoprzepustowym o stałej czasowej Tf, metody wykrywające oscylacje, ustawianie parametrów P I D w czasie rzeczywistym, itp. Ale jak wiadomo, regulator PID działa w oparciu o sprzężenie zwrotne, dążąc do minimalizacji wartości błędu między sygnałem zadanym a rzeczywistym. Tylko skąd wziąć w tym przypadku informację o położeniu nastawnika, niezbędną do wyliczenia wartości błędu dla PID? Z jakiegoś powodu Bosch w tych pompach nie zastosował potencjometru, który można by wykorzystać do tego celu (może kwestia trwałości), tylko zastosował zupełnie inny mechanizm. Wygląda on tak: Jest to pierścień z dwoma cewkami. Jak to działa? Wbrew pozorom bardzo prosto: ruch ramienia nastawnika powoduje zmianę indukcyjności cewek. Taki mechanizm jest genialny pod kątem trwałości, coś co w dzisiejszych czasach nie ma zastosowania... Jak to jednak wykorzystać w pratyce, razem z mikrokontrolerem? Z laborek ze szkoły (wow, szkoła się przydała...) przypomniałem sobie że istnieje coś takiego jak generator Hartleya: Układ ten to generator sinusoidy. W połączeniu z cewkami z pompy, generuje on sinusoidę o różnej częstotliwości, oraz amplitudzie. Czyli po wyprostowaniu i odfiltrowaniu przebiegu, mamy już coś co może użyć mikrokontroler (ADC) jako sygnał zwrotny. Oczywiście jest to schemat przykładowy, w praktyce wartości elementów są inne, oraz sam układ jest trochę bardziej skomplikowany. Ogólnie zmodyfikowany lekko PID radzi sobie całkiem nieźle z dryftem napięciowym, temperaturowym, i jest w stanie utrzymać stabilnie nastawnik w zadanym położeniu. Jeszcze odnośnie samego sterownika - bo napisałem o nim parę słów, a w sumie nawet go nie pokazałem Zanim zacznie się krytyka co do wyglądu - jest to cały czas układ rozwojowy, docelowo zaprojektuję porządne PCB i zlecę wykonanie jakiejś firmie. Układ jest wbrew pozorom bardzo stabilny, zarówno od strony mechanicznej, jak i software. W chwili obecnej, by zwiększyć jego stabilność mechaniczną, jest zalany żywicą. Wygląda on w tak: Zbudowałem 2 takie jednostki, jedną do developmentu w domu (części softu które nie wymagają silnika do pracy), i drugą do testów w garażu, gdzie stoi silnik testowy: ...i teraz przystopuję trochę, bo nie wiem czy ten temat jest w ogóle dla was jakkolwiek interesujący, i czy jest sens by o nim pisać dalej, być może bardziej szczegółowo. Ostatecznie jest to również sterowanie silnikiem za pomocą Arduino, tylko takim trochę większym i mocniejszym. Dajcie znać co sądzicie o temacie, jestem otwarty na krytykę, pomysły, pytania, cokolwiek.
  10. Nie wiem czy można to nazwać pełnoprawnym DIY ale dzisiaj zaprezentuję drugie życie robota z kursu budowy robotów. Komentarz dla czepialskich: tak, mogę tego robota nazwać robotem ponieważ jest wyposażony w akcelerometr który jest pewnego rodzaju czujnikiem. Wykorzystałem tą konstrukcję, ponieważ chciałem zrobić coś małego co będzie mogło jeździć po całym domu z kamerką. Najpierw omówimy sobie co było gotowe a później co dodałem albo zmieniłem. Cała konstrukcja, Arduino i shield forbota przez cały czas były na swoim miejscu nic w tej kwestii nie ruszałem (oprócz przylutowania paru kabelków do shielda, i wkręcenia wyższych dystansów pod Arduino). Natomiast ze zmian jest jedna ale za to ważna sprawa jaką jest zasilanie. W oryginalnym robocie całość była zasilana z 6 paluszków AA co daje razem 9 woltów (1,5V * 6 = 9V) . Wady takiego rozwiązania były dwie - brak możliwości ponownego naładowania i zajmowały sporo miejsca. Pozbyłem się problemu i zamieniłem na 2 akumulatorki 18650 co daje 8.4 woltów (4.2V * 2 = 8,4V). Ale ktoś może powiedzieć zaraz zaraz, ale 2 takie akumulatorki 18650 wcale nie zajmują jakoś mniej miejsca i w ogóle to 8.4 V to nie za mało ? I ma rację bo przy 8.4V mogłem jeździć niecałe dwie minuty (to wszystko wina malinki) dlatego dodałem przetwornicę step- up która podnosi napięcie do 10V. Wracając do kwestii zajmowanego miejsca przez baterie to może faktycznie 18650 nie zajmuje mniej miejsca objętościowo ale za to kształtem idealnie wpasowały się pod przestrzeń między podwoziem a Arduino. Swoją drogą, gdybym nie odkrył tego miejsca to ten projekt by nie powstał. To tyle ze zmian teraz czas na dodatki. Najważniejszym dodatkiem jest mój samodzielnie zlutowany shield na shielda, może śmiesznie to brzmi ale tak właśnie jest. Zawiera on: moduł radiowy nRF24l01 który odpowiada za sterowanie wszystkim, akcelerometr MPU6050 który daje możliwość cieszyć się w miarę prostą jazdą do przodu, wyprowadzenia na 2 serwa które pozwalają poruszać kamerą aby uzyskać większy kąt widzenia, tranzystor do którego podpięte są 2 ledy 1w każda. Drugim dodatkiem jest Raspberry Pi 4B razem z kamerką . Tak zdaję sobie sprawę że rpi 4 to overkill do takiego projektu, zajmuje połowę platformy i potrafi zużywać więcej prądu niż cała reszta robota. Ale po prostu nie mam nic innego pod ręką. Teraz powiem kilka słów o poszczególnych funkcjach i podzespołach (jeśli można tak to nazwać). Zasilanie - nie będę się już powtarzał ale dla tych co jeszcze się nie domyślili dopowiem tylko że malinka jest zasilana przez przetwornicę step-down ( 8.4V przetwarza na 5V) Sterowanie - jak już mówiłem za sterowanie odpowiada nRF24l01, jako transmitera używam własnoręcznie zlutowanego pilota którego używałem już w moich poprzednich projektach i o dziwo cały czas jest sprawny. Na razie pilot ma 10 kanałów z czego 8 używam w tym robocie. Krótka rozpiska co obsługuje poszczególny kanał: lewy joystick góra dół - jazda przód tył, lewy joystick lewo prawo - obrót lewo prawo, prawy joystick góra dół - ruch kamerą góra dół, prawy joystick lewo prawo - ruch kamerą lewo prawo, potencjometr - trymer (albo jakoś tak, nie wiem jak to się pisze) do kamery lewo prawo, chodzi o taki minimalny ruch serwem który pomaga ustawić kamerę w miarę prosto, środkowy(pod nrf'em) toggle switch - włącza funkcję w miarę prostej jazdy do przodu, prawy toggle switch - światła on/off, przycisk w lewym joysticku - włącza buzzer (ten wbudowany w forbotowego shielda). Akcelerometr - sprawił mi najwięcej problemów, a właściwie to program którego nie umiałem poprawnie napisać. Okej przyznam się że funkcji przetwarzającej dane z akcelerometru nie napisałem w pełni samodzielnie. Działa to tak że program odczytuje przyspieszenie w osi Z i w zależności od tej danej steruje prędkością poszczególnych silników. Kamera - podłączona do RPI 4B przekazuje obraz przez Wi-Fi w sieci WLAN . Ja siedząc przy komputerze widzę ten obraz z programu VNC. Oczywiście najpierw muszę wywołać jakąś komendę którą się z wami podzielę, może ktoś skorzysta: raspivid -o -t 0 -w 800 -h 400 -rot 180 -fps 30 Ta część też zajęła mi trochę czasu. Chciałem żeby opóźnienie obrazu nie przekraczało 200ms więc przekopywałem internet żeby znaleźć jak streamować obraz za pomocą netcata. Niestety nie udało się znaleźć żadnego właściwego poradnika. Po dłuższym czasie poszukiwań znalazłem tą komendę która pozwoliła mi streamować obraz z kamery na naprawdę sensownym opóźnieniu (postaram się później podesłać filmik w komentarzu). Wady - oczywiście, tak jak wszystko na tym świecie robot ma wady i to nie jedną, a kilka: środek ciężkości - można głównym ciężarem są akumulatorki które są położone z tyłu co znacznie przesuwa środek ciężkości (czerwony - gdzie jest, zielony - gdzie powinien być), Raspberry Pi 4B - zajmuje za dużo miejsca i pobiera za dużo prądu, Zasilanie - pomimo że je zmieniłem to nadal 18650 nie są najlepszym rozwiązaniem. Na końcu zamieszczę jeszcze filmik pokazujący moc akcelerometru, ruch kamery i jazdę po dywanie.
  11. Siemka, kupiłem RPI 3B+ na botlandzie, po włożeniu karty sd z systemem (karta 64GB, format FAT32) ciągle świeci się zielona dioda oraz czerwona. Na innych stronach przeczytałem, że powinna migać. Dodatkowo na monitorze jest po prostu czarny ekran, nic się nie pokazuje ani uruchamia. Dodam jeszcze, że słabo świecą się światełka od portu ethernet. Zgłosić reklamację czy jest jakiś sposób na ogarnięcie tego?
  12. Witam, Szukam czegos do nauki elektroniki/programowania dla dziewczyni zaraz osmio letniej. Natknalem sie na scratch ktory pewnie wdrozymy ale corka chciala tez pobudowac roboty tak natknalem sie na forbota. Szczerze fajnie by bylo jakbyscie pisali od jakiego wieku, co polecacie.. z wstepnego przejrzenia kurs podstaw elektroniki jest za bardzo teoretyczny na ten wiek. Arduino i raspherry pi tez chyba za wczesnie. Zaatanawiam sie nad micro.bit ale tez nie wiem czy to nie za wczesnie dla 7-8 latki... Myslalem o nauce lutowania i budowania tym sposobem czegos i przy okazji uczenia sie troche. Co myslicie o takim pomysle? Czy sa jakies zestawy dla dzieci tego typu? na youtubie mignal mi kanal gdzie ktos z corka 7 letnia lutuje.. Osobiscie nie znam sie na tym wiec bede uczyl sie z corka (programowac umiem, kiedys cos tam polutowalem ale daleko do stwierdzenia ze cos umiem czy moge przekazac jakas wiedze) Z gory dziekuje za sugestie i pozdrawiam
  13. Witam. Problem tak jak w tytule. Nie mogę uruchomić żadnego systemu operacyjnego.(Przedtem działało wszystko poprawnie) Kiedy próbuję go uruchomić wyświetla się tęcza i malinki ale potem brak sygnału tak jakby się wyłączyło. Nie da się uruchomić nawet przez UART. Wszystkie te czynności wykonywałem zgodnie z kursem RPI. Dodaję kilka zdjęć.
  14. Witam wszystkich, Na wstępie dodam, że to mój pierwszy post i przepraszam za błędy. Potrzebuje zbudować dla znajomego serwer dla skanów z drukarki po FTP/smb. Ze względu na budżet bardzo okrojony (500zl...wiadomo i tak go przekroczę bo dyski...) pomyślałem o RPI 4/5. Pliki dość ważne więc byłyby wiec mam pomysł wpięcia dwóch dyskow pod USB. Jeden SSD jako system wraz ze skanami plus kopia różnicowa na ten sam dysk plus dodatkowy HDD z kopia różnicowa plus całościową z kompresją. Problemy są dwa jakie widzę. Czytałem gdzieś że RPI ma problem z mocą na USB i może nie uciągnąć dysku HDD, a drugi to, że ceny RPI tak podskoczyła, że zastanawiam się nad kupnem terminala jakiegoś (tylko jakiego...) które uciągnąć by dwa dyski i może by i RAID jakiś oferował (aczkolwiek niekonieczne bo ze spokojem kopie mogę zrobić inaczej). Problem z terminalami jest taki, że nie znam się na nich by określić jaki e cenie do 400zl( 500 jak warto) byłby najlepszy. Może być nawet taniej ( tym lepiej) terminal są o tyle dobre w porównaniu do dzisiejszych cen RPI, że (chyba) są wydajniejsze i w przyszłości dałoby radę rozszerzyć ze spokojem spektróm działania serwera o inne rzeczy. Na ten moment cena jest dla mnie najważniejsza. To czemu taka kwota mimo że skany są ważne pozostawiam dla siebie gdyż ze względów...biznesowych nie mogę tego zdradzić i niestety na ten moment nie może on sobie pozwolić na jakiegoś NAS np synology. Z góry bardzo dziękuję za wyrozumiałość i porady.
  15. Hej! Robię projekt, który będzie wykorzystywał pomiar odległości pobierany z czujnika i przesyłany do Raspberry Pi Zero W Basic - chodzi o to żeby całość była dość poręczna. Chciałbym uniknąć wykorzystania płytki stykowej w myśl jak największej poręczności rozwiązania, dlatego myślałem o wykorzystaniu czegoś takiego - czy to będzie działać po podłączeniu do pinów GPIO raspa? W sensie czy wystarczy tylko podłączyć te kabelki z zestawu i nie potrzeba nic więcej? Inną opcją może być też czujnik wykrywający ruch o ile ma wąskie ROI fabrycznie lub możliwe do ustawienia. Przyznam, że ideałem byłaby sytuacja, w której czujnik dzieliłby się na transmiter (przyklejony w jednym miejscu) i odbiornik podłączony do raspa, przekazujący mu pomiar. Do tej pory nie udało mi się znaleźć czegoś takiego ale może źle szukam jeśli ktoś wie o czymś takim, to bardzo chętnie przyjmę tipa. Ewentualnie czujnik będący transmiterem przekazujący pomiar przez bluetooth, radiowo albo jakoś inaczej do kontrolera...Ktokolwiek widział, ktokolwiek wie Pozdrawiam
  16. Raspberry Pi jest często używane jako kontroler automatyki domowej. Inteligentne sterowanie roletami i oświetleniem to mały wycinek tego co potrafi malinka z Domoticzem. Na początku warto zacząć od ustawień systemu, podłączenia czujników temperatury (DS18B20) oraz konfiguracji powiadomień. [blog]https://forbot.pl/blog/kurs-raspberry-pi-projekty-domoticz-ds18b20-maile-id27526[/blog]
  17. Dawno już miałem ochotę skombinować sobie stację pogodową i powiesić na ścianie jakiś estetyczny ekran pokazujący jak to tam jest za oknem. Myślałem żeby coś takiego kupić, ale w końcu zbudowałem sam - a w każdym razie ekran, bo prezentowane dane pochodzą z serwisu pogodowego, a nie z mierników. Jest to mój pierwszy projekt elektroniczny. Od razu wyjaśnię, że ikony pogody oraz biedronka i grzybek to rysunki mojej pięcioletniej córki Hardware Wszystko oparte jest na Raspberry Pi Zero W, ekran wybrałem Waveshare trójkolorowy 7.5", z modułem HAT dla Raspberry Pi. Natomiast żona dała mi wyraźnie do zrozumienia, że jeśli to ma wisieć na ścianie w salonie czy w korytarzu, to ma być ładne, więc zbudowałem z listewek drewnianych ramkę (wiem że jest trochę krzywo na łączeniach, ja naprawdę się starałem), a następnie stwierdziłem, że jeśli nałożę tego HATa na Pi, to całość jest o ładnych kilka milimetrów za gruba żeby się zmieścić pod ekranem... więc pozostało mi łączenie przewodami pojedynczych nóżek. Moduł HAT ma też połączenie uniwersalne, i dołączony był przewód ośmiożyłowy. Ekran ma dość krótką taśmę, w zestawie była też przedłużka ale postanowiłem podłączyć moduł do tej taśmy bezpośrednio z myślą że przecież tam w środku jest nadal masa miejsca na moje Pi. No cóż, okazało się to nie takie proste, i ostatecznie Pi jest tak trochę po skosie, utrzymywany na miejscu przez swój kabel zasilający oraz drut łączący go z wiązką przewodów. Tego się nie da opisać, to trzeba zobaczyć, więc załączam zdjęcia. Na szczęście wszystko to jest całkowicie schowane, bo ramka tyłem przylega do ściany. Grubość ramki to 2cm, przestrzeń na elektronikę ma około 1.5cm. (Jeżeli ktoś się zastanawia czemu wszystkie piny Pi są ubabrane cyną, no cóż, to smutna historia. Najpierw własnoręcznie wlutowałem tam złącze czterdziestopinowe (i byłem z siebie bardzo zadowolony, bo nigdy wcześniej czegoś takiego nie lutowałem, a do tego użyłem lutownicy transformatorowej i nic się od tego nie uszkodziło), a dopiero później zbudowałem ramkę, która okazała się za mała, więc je całe wylutowałem wyrywając po jednej nóżce. Nadal transformatorem, i nadal nic się nie uszkodziło, więc właściwie to nadal jestem z siebie zadowolony.) W ostatecznej wersji szczelina na dole, którą wsuwany był ekran, zaklejona jest plasteliną. Plastelina jest też użyta do uszczelnienia ekranu, tak żeby nie miał luzu. Software Oprogramowanie napisane jest całkowicie w języku Ruby, i składa się z następujących części: Dane pobierane są co około 10 minut: Dane o pogodzie pobierane są z openweathermap.com. Darmowy dostęp do API pozwala pobrać prognozę godzinną na 48h oraz dzienną na parę dni, no i sporo parametrów aktualnej pogody, które prawie wszystkie wyświetlam. Dane do kalendarza pobierane są przez protokół ICAL z Kalendarza Google, opis wydarzeń wskazuje na typ, różne typy są różnie oznaczone w kalendarzu (kreskowane linie nad datami albo kropki, czarne lub czerwone). Dodatkowo pobieram informacje o świętach z calendarific. Te dane są cache'owane bo świąt narodowych raczej nie dodają co 10 minut i nie ma sensu tak męczyć tego API. Pobrane dane są porównane z poprzednimi danymi. Jeżeli nie zmienił się żaden istotny parametr to nie ma sensu nic przerysowywać, zwłaszcza że ekran nie ma częściowego przerysowania, tylko cały migocze jak szalony przez kilkanaście sekund. Natomiast jeśli różni się na przykład aktualna ikona pogody czy temperatura, albo to, czy ma za dwie godziny padać, to przerysowuję od razu. Przerysowuję też co najmniej raz na godzinę, żeby zaktualizować wykres. Następnie z danych składam (z użyciem własnej bardzo prostej biblioteki) definicję SVG przedstawiającego cały ekran. Potem używam imagemagick żeby odczytać piksele z tego obrazu. Piksele mapuję na dostępne w ekranie kolory (biały, czarny, szary (tylko jeden) i czerwony), i wysyłam do własnej biblioteki, która montuje bufor w formacie akceptowanym przez ekran. Wysyłam zawartość do ekranu przez SPI. Korzystam przy tym z biblioteki Mike'a McCauley'a, której używam z Rubiego przez FFI. Oprogramowanie ma sporą ilość konfigurowalnych parametrów, takich jak liczba godzin do pokazania na wykresie, gęstość siatki, liczba tygodni w kalendarzu, dane do "galerii" po prawej na dole. Wszystko to, razem z takimi danymi jak na przykład klucze API albo lokalizacja dla której ma być sprawdzana pogoda, siedzi w pliku konfiguracyjnym lokalnie na Pi, albo przez HTTP (co pozwala łatwo zmieniać konfigurację bez logowania się do Pi). Używam gita, edytuję kod na innej maszynie niż ten Pi w ekranie, testuję kod uruchamiając go z parametrami, które powodują wygenerowanie PNG zamiast wysyłania obrazu na fizyczny ekran. Gdy zrobię zmianę, pushuję ją, a potem jedną komendą ustawiam flagę update-code w serwisie na zewnętrznym serwerze (nie będę tu opisywał ze szczegółami). Gdy serwis działający na ekranie następnym razem będzie odświeżać dane i zobaczy flagę update-code, to najpierw zrobi git pull i się zrestartuje. Dzięki temu nie potrzebuję łączyć się bezpośrednio z Pi w ekranie żeby wgrać mu aktualizację kodu. Potencjalny dalszy rozwój Projekt jest zakończony, wisi na ścianie już 4 miesiące i jestem z niego bardzo zadowolony. W międzyczasie dodawałem tylko różne drobne usprawnienia (na przykład dodawałem godziny wschodu i zachodu słońca, a ledwie wczoraj naprawiałem małego buga, który się ujawnił przy zmianie czasu). Natomiast jest możliwe parę większych usprawnień, które może kiedyś zrobię, a może nie. Pobieranie prognozy pogody z innego serwisu, na przykład yr.no. Czasami wydawało mi się, że jest bardziej trafna, chociaż bywało też odwrotnie. Natomiast zawiera mniej parametrów, więc raczej łączyłbym prognozę z dwóch źródeł. No i podaje temperaturę bez części ułamkowych, i musiałbym zaimplementować wygładzanie wykresu. Pobieranie informacji o aktualnej pogodzie z jakichś fizycznych czujników. Dołączenie informacji o aktualnych parametrach wewnątrz pomieszczenia, na przykład temperaturze i wilgotności. Do tego prawdopodobnie zbudowałbym osobne urządzenie oparte na Pi, które takie dane mierzy i wystawia w jakiś sposób, a ramka by je tylko pobierała.
  18. Cześć, właśnie rozpocząłem zakupiony u Was kurs Raspberry Pi i niestety system się nie bootuje, errory na zdjęciach. Proszę o radę, co w takiej sytuacji zrobić. Pozdrawiam, Stefan
  19. Przychodzę z pewnym problemem z którym borykam się już od jakiegoś czasu, związanym z mobilnym robotem. Ma to być robot wyposażony w wiele czujników, w tym: 4 czujniki odległości HC-SR04P, listwa z czujnikami odbiciowymi QTR-8A, IMU ICM-20948, 4 przyciski ("ala czujniki dotyku"), LIDAR, kamera, enkodery kwadraturowe. Do odbierania danych z czujników oraz do sterowania silnikami chcę wykorzystać Arduino Mega lub giga r1(niby jest szybyszy ale nie wykorzystuje się jego potencjału jak ię tworzy kod na arduino ide). Dane z Arduino będą przekazywane poprzez kabel usb do Raspberry Pi 4, na którym będzie ROS, oraz do którego podłączone będą LIDAR i kamera. Mam problem głównie z doborem silników do tego robota z powodu konieczności wyposażenia każdego silnika w enkoder. Wszystkie silniki, na jakie natrafiłem, były wyposażone w enkodery inkrementalne (co wymaga 2 pinów do obsługi jednego enkodera). Z tego, co sprawdziłem, aby obsłużyć enkodery, potrzebne są przerwania a arduino potrzebuję czasu aby wszystkie obsłużyć. Poniżej znajduje się kod, który napisałem, aby pomóc sobie przy doborze silników . Orientacyjna masa robota będzie wynosić około 6 kg(dla 4 kół), a koła, które chcę wykorzystać, mają średnicę 10 cm. Ilość kół wpłynie na moment potrzebny do silnika oraz ilość enkoderów. Ma być to robot autonomiczny a więc jeśli zastosuję 4 silniki, zamierzam użyć kół mecanum; jeśli 2, to zwykłe koła i jedno z przodu swobodne; jeśli 3, to koła omnikierunkowe. Dla 4 zwykłych kół nie znalazłem macierzy. #include <stdio.h> int main() { // Deklaracja zmiennych double V, M, N, X=1.5 /* odwrotnosc sprawnosci */, D, g=9.81, u=0.9 /* wspolczynik tarcia */, a=1 /* przyspieszenie liniowe */, t, O; // Wprowadzanie wartości zmiennych printf("Podaj wartość M: "); // masa scanf("%lf", &M); printf("Podaj wartość N: "); // Ilosc kol scanf("%lf", &N); printf("Podaj wartość D :"); // Srednica kola scanf("%lf", &D); printf("Podaj wartość V: "); // Predkosc liniowa scanf("%lf", &V); // Obliczenia zgodnie z podanymi wzorami t = (X * (((u * M * g) + (M * a)) * D) / (2*N)) * 10.19716; // Wymagany moment(z przelicznkiem z Nm na kgfcm) O = X*(2 * V / D) * 9.5493; // Predkosc obrotowa(z przelicznikiem z rad/s na rpm) // Wyświetlenie wyników printf("Wartość t wynosi: %lf\n", t); printf("Wartość O wynosi: %lf\n", O); return 0; } W kodzie nie uwzględniłem kąta równi pochyłej bo robot ma się poruszać po płaskiej powierzchni.Mam także wątpliwości co do współczynnika tarcia, - czy mam wziąć pod uwagę tarcie toczene, czy statyczne.Jeżeli macie także jakieś porady do innych rzeczy związanych z tym robotem będe wdzięczny za podpowiedź i pomoc.
  20. Dzień dobry, Szybkie pytanie czy karta TP-Link UE300 (RealTek RTL 8153) będzie współpracować z Raspberry Pi 4B? Chciałbym użyć tej karty jako interfejsu WAN przy konfiguracji pfSense.
  21. Cześć wszystkim, Mam problem z identyfikacją wersji GPIO na moim Raspberry Pi. Próbowałem kilku poleceń w terminalu, takich jak "gpio -v" i "gpio readall", ale otrzymuję komunikat o błędzie "-bash: gpio: nie znaleziono polecenia". Czy ktoś mógłby mi pomóc? Byłbym bardzo wdzięczny za wszelką pomoc. Dziękuję
  22. import cv2 import pytesseract import time from pytesseract import Output def extract_license_plate(image_path): image = cv2.imread(image_path) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (5, 5), 0) edges = cv2.Canny(blur, 100, 200) contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours = sorted(contours, key=cv2.contourArea, reverse=True)[:10] plate_text = None for contour in contours: peri = cv2.arcLength(contour, True) approx = cv2.approxPolyDP(contour, 0.018 * peri, True) if len(approx) == 4: x, y, w, h = cv2.boundingRect(approx) roi = image[y:y + h, x:x + w] plate_text = pytesseract.image_to_string(roi, config='--psm 8 --oem 3 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') return ''.join(filter(str.isalnum, plate_text)) return "no text detected" cap=cv2.VideoCapture(0) try: while True: ret, frame = cap.read() if ret: cv2.imwrite('/home/marek/tablica.png',frame) print("Image saved") text = extract_license_plate('/home/marek/tablica.png') else: print("fail") if text is not None: print(f"Extracted Text: {text}") time.sleep(5) except Exception as e: print(f"An error occurred: {e}") finally: cap.release() print("Camera released.") Pracuję nad projektem systemu służącego do automatycznego otwierania bramy, w momencie rozpoznania przez kamerę z Raspberry Pi, numerów tablic rejestracyjnych zapisanych w pliku tekstowym. Jestem dość zielony w jakiekolwiek programy związane z systemami wizyjnymi i mocno posiłkowałem się ChatemGPT 4, wrzuciłem do chatu zdjęcia przypominające docelowy obraz z kamery i kazałem mu pod to napisać program. Program działa prawie idealnie kiedy zczytuje tablice z gotowych zdjęć, jednak gdy zdjęcia pochodzą z kamery i pokazuje przed nią dokładnie to samo zdjęcie tylko wydrukowane, program nie rozpoznaje żadnych znaków. Pytanie gdzie może leżeć problem, czy wpływ na to ma zbyt niska jakość obrazu z kamerki (używam kamery ZeroCam z przejściówka do Raspberry PI 3A+) , potencjalnie zły kąt zdjęcia przed kamerka czy może jakiś błąd w kodzie? Testuje działanie na załączonym obrazku Z góry dziękuje za pomoc, ewentualny namiar do kogoś kto mógłby pomóc :))
  23. mam taki problem. bo w filmach instalacji oprogramowania multimedialnego kodi na youtube widać, że filmy mają taką fajną nakładkę tutaj przypnę link jak to powinno wyglądać. z góry dzięki link do zdjęcia
×
×
  • Utwórz nowe...