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 - roboty
    • Projekty - DIY
    • Projekty - DIY (początkujący)
    • Projekty - w budowie (worklogi)
    • Wiadomości
  • Pozostałe
    • Oprogramowanie CAD
    • Druk 3D
    • Napędy
    • Mechanika
    • Zawody/Konkursy/Wydarzenia
    • Sprzedam/Kupię/Zamienię/Praca
    • Inne
  • Ogólne
    • Ogłoszenia organizacyjne
    • Dyskusje o FORBOT.pl
    • Na luzie
    • Kosz

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


Znaleziono 74 wyników

  1. Cześć, jestem czytelnikiem Forbota od dłuższego czasu interesuje się elektroniką ale tylko hobbystycznie przez co mam wiedzę znikomą w wielu tematach - proszę o wyrozumiałość Robiłem kilka przymiarek to automatyki domowej zanim odkryłem że są „gotowe” rozwiązania takie jak: Supla, HomeAssistant, OpenHab, Domoticz i inne. Szukałem porównania, możliwości skalowalność i nie znalazłem odpowiedzi na pytanie który system by sprostał tematowi jaki mam, a jest ono dość proste: - Arduino (kilka sztuk) - komunikacja z Arduino tylko LAN (moduł Ethernet lub Serial + moduł Wifi) - Arduino jako klient, przekażniki czujniki sterowane przewodowo przez Arduino - serwerze własny z Linuxem (offline !) jak Domoticz, OpenHab itp. Teraz mam „zrobiony” od podstaw taki system bardzo prosty i działa dobrze ale ciągle rozbudowuje go o kolejne dodatki i tak się zastanawiam - jak było wiele razy powtarzane żeby nie wyważać otwartych drzwi - lepiej pomóc już działającej społeczności niż samemu ją tworzyć od nowa. Nie oczekuje gotowego rozwiązania tylko wskazania drogi którą pójść czy rozwijać swój projekt? czy jest rozwiąznie które wyżej wymienione wymagania ogarnie? Z Domoticzem przez chwilę było dobrze ale nie po kablu. Jeżeli będzie zainteresowanie tematem mogę rozpisać co teraz zostało zrobione i jak to działa teraz, może mam dobry pomysł tylko go trzeba opakować sensowniej i nie pakować się w gotowe (ogromne programowo) rozwiązania. Dziękuję za przeczytanie.
  2. Mam problem z VNC a natomiast od VNC dostaje komunikat "Cannot currlently show the desktop"
  3. Witam! Mam problem z kompilacją OBS'a na raspberry pi3b+. Robie dokładnie to co w tym poradniku: https://obsproject.com/forum/threads/obs-raspberry-pi-build-instructions.115739/#post-437594 I podczas kompilacji malinka zacina się na dobre. Czy da się coś z tym zrobić? Może jest jakiś inny program do streamowania na YT który działałby na raspberry?
  4. 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]
  5. Ten wpis bierze udział w konkursie na najlepszy artykuł o elektronice lub programowaniu, którego partnerem jest firma PCBWay (popularny producent prototypów PCB). W puli nagród karty podarunkowe Allegro o wartości 2300 zł. Sprawdź więcej informacji na temat konkursu » Stacja pogodowa z użyciem czujnika BME680 Stacja pogodowa to jeden z najpopularniejszych projektów IoT, którym fani elektroniki zaczynają swoją przygodę z Raspberry Pi, sensorami, przesyłaniem danych oraz ich wizualizacją. W tym artykule przyjrzymy się monitorowaniu temperatury, wilgotności, ciśnienia barometrycznego i jakości powietrza za pomocą uniwersalnego czujnika, który łączy się bezpośrednio z Raspberry Pi bez dodatkowych komponentów. Dużym plusem tej aplikacji jest to, że nie wymaga ona dużego doświadczenia w elektronice i programowaniu a wprowadza wiele przydatnych zagadnień. W tym projekcie dodatkowo wdrożymy bazę danych do przechowywania odczytów wraz z interfejsem graficznym Grafana, aby zobaczyć aktualne odczyty. W aplikacji używam adresu IP: 192.168.12.16, który oznacza adres mojego Raspberry Pi. Do poprawnego działania na malince czytelnika, należy go zmienić w plikach źródłowych oraz przy konfiguracji Grafany. Podłączenie BME680 do Raspberry Pi Pierwszym krokiem do uruchomienia aplikacji jest podłączenie czujnika do naszej Raspberry Pi. W zależności od producenta płytki, możemy komunikować się przez protokół SPI lub I2C. W tej aplikacji została wykorzystana płytka z pimoroni.com, która wspiera tylko protokół I2C. Czujnik jest połączony z Raspberry Pi przy użyciu czterech przewodów: Raspberry | BME680 ---------------------------------- 3V3 | 2-6V SDA1 I2C | SCA SCL1 I2C | SCL Ground | GND Specyficzną cechą tej płytki jest to, że została specjalnie zaprojektowana do wykorzystania wraz z magistralą I/O Raspberry Pi. Czujnik możemy podłączyć bez dodatkowych przewodów. Rys. 1. Bezpośrednie połączenie czujnika Jedyną wadą tego układu jest fakt, że czujnik zbiera pomiary blisko SoC-a co zmienia wskazania temperatury i wilgotności. Lepszym rozwiązaniem jest przedłużenie płytki przewodami i ustawienie sensora w bardziej przystępnym miejscu. Rys. 2. Połączenie przy użyciu przewodów Konfiguracja I2C na Raspberry Pi Przed uruchomieniem programów i instalacją potrzebnych narzędzi, musimy sprawdzić ustawienia konfiguracyjne portu I2C. Konfigurację przeprowadzamy przez wybranie z menu konfiguracyjnego lub przez komendę raspi-config: Rys. 3. Wybór z menu konfiguracyjnego Przechodzimy w Interfacing Options i wybieramy I2C: Rys. 4. Wybór interfejsu I potwierdzamy włączenie interfejsu naciskając Enter na opcji Yes: Rys. 5. Zatwierdzenie włączenia interfejsu I2C Poprawność połączenia należy sprawdzić w terminalu przy użyciu komendy: $>: sudo i2cdetect -y 1 W odpowiedzi otrzymamy tabelę adresów interfejsu I2C. Widoczny numer 76 oznacza, że czujnik został połączony i wykryty z adresem 0x76. Po tym zabiegu sprzętowa konfiguracja dobiegła końca i możemy zająć się potrzebnym oprogramowaniem. 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- 76 -- Pliki źródłowe Producent czujnika BME680 udostępnia przygotowane API na githubie. Na podstawie dokumentacji został stworzony kontroler obsługujący połączenie między Raspberry Pi a czujnikiem. Wysyłanie danych z pomiarów do brokera MQTT zostało zaimplementowane w języku C przy użyciu biblioteki paho.mqtt. Całości została połączona w pliku main.c. Dla wygody użytkownika został stworzony plik makefile do szybkiej kompilacji. Przed zbudowaniem aplikacji musimy dodać biblioteki służące do wysyłania danych do brokera MQTT. W repozytorium z plikami źródłowymi znajduje się także plik forwarder.py który został napisany do komunikacji między brokerem a bazą danych. Instalacja MQTT Protokół MQTT zapewnia lekką metodę przesyłania komunikatów przy użyciu modelu publikowania i subskrypcji. Dzięki temu nadaje się do transmisji wiadomości z urządzeń takich jak czujniki o niskiej mocy lub urządzenia mobilne jak smartfon lub mikrokontroler. Do zbudowania projektu wraz z klientem protokołu MQTT musimy pobrać bibliotekę z git-a i ją zainstalować. W tym celu wykonujemy sześć komend w terminalu: $>: git clone https://github.com/eclipse/paho.mqtt.c.git $>: cd paho.mqtt.c $>: git checkout v1.3.1 $>: cmake -Bbuild -H. -DPAHO_WITH_SSL=ON -DPAHO_ENABLE_TESTING=OFF $>: sudo cmake --build build/ --target install $>: sudo ldconfig Po zakończonej instalacji bibliotek możemy zająć się brokerem MQTT. Broker działa jak serwer, który otrzymuje dane na dany temat z różnych urządzeń. Klienci mogą subskrybować dane tematy oraz publikować wiadomości w różnych tematach. Instalacja dystrybucji Eclipse Mosquitto odbywa się przez wykonanie polecenia: $>: sudo apt install mosquitto mosquitto-clients Teraz mamy gotowe całe środowisko i możemy przystąpić do pierwszego uruchomienia aplikacji. W pierwszej kolejności otwieramy nowa konsolę i uruchamiamy broker MQTT za pomocą instrukcji: $>: mosquitto -v Gdy broker nasłuchuje w tle, możemy uruchomić aplikację stacji pogodowej. W innym terminalu, w katalogu application wykonujemy komendę: $>: make Następnie uruchamiamy aplikację WeatherStation: $>: ./WeatherStation 5 1000 logs.txt Argumenty w tej komendzie oznaczają: Pierwsza liczba oznacza przerwę między kolejnymi pomiarami w sekundach, Druga liczba oznacza ilość pomiarów, Trzeci argument to nazwa pliku z logami. Instalacja i konfiguracja InfluxDB W naszym przykładzie używamy InfluxDB do przechowywania danych, ponieważ są one zoptymalizowane pod kątem danych szeregów czasowych. Oczywiście możliwa byłaby również praca z innymi bazami danych, takimi jak MariaDB lub mongoDB, ale InfluxDB działa bezpośrednio z Grafaną. Pierwszą rzeczą do zrobienia jest instalacja InfluxDB na Raspberry Pi. Instalacja jest dość łatwa, wystarczy wykonać dwa następujące polecenia w terminalu: $>: sudo apt install influxdb $>: sudo apt install influxdb-client Po udanej instalacji uruchamiamy InfluxDB i kontrolujemy bieżący status za pomocą następujących poleceń: $>: sudo service influxdb start $>: sudo service influxdb status Obecny status InfluxDB powinien być aktywny: Rys. 6. Status aplikacji InfluxDB Po instalacji InfluxDB musimy wprowadzić jedną zmianę w konfiguracji, aby włączyć punkt końcowy HTTP. Jest to konieczne, ponieważ chcemy zapisać dane od subskrybenta MQTT do istniejącej bazy danych. Aby zmienić konfigurację, użyjemy następującej instrukcji: $>: sudo nano /etc/influxdb/influxdb.conf W pliku konfiguracyjnym przewijamy w dół za pomocą klawisza strzałki na klawiaturze do części [http] konfiguracji. Usuwamy zaznaczenie pierwszego ustawienia, usuwając znak "#" w trzech liniach, tak jak na poniższym rysunku. Klikamy "Ctrl+O", zatwierdzamy zmiany a następnie klikamy "Ctrl+X", aby wyjść z edytora tekstu nano. Rys. 7. Zmiany w pliku konfiguracyjnym InfluxDB Po każdej zmianie konfiguracji InfluxDB musi zostać ponownie uruchomiony, aby zmiany w konfiguracji były aktywne. Uruchomimy ponownie InfluxDB za pomocą następującego polecenia. $>: sudo service influxdb restart Konfiguracja jest zakończona i możemy przejść do stworzenia bazy danych, w której przechowywane są wszystkie pomiary oraz użytkownik, który zapisuje dane MQTT do bazy danych. Najpierw uruchomimy InfluxDB za pomocą następującego polecenia w terminalu Raspberry Pi: $>: influx Teraz stworzymy nową bazę danych o dowolnej nazwie. Jako nazwę wybieram „weather_stations”. Zbudujemy bazę danych poleceniem: > CREATE DATABASE weather_stations Baza danych została utworzona, a teraz tworzymy nowego użytkownika i dajemy mu prawo dostępu do utworzonej wcześniej bazy danych. Wybieram mqtt jako nazwę użytkownika i hasło. > CREATE USER mqtt WITH PASSWORD 'mqtt' > GRANT ALL ON weather_stations TO mqtt InfluxDB został zainstalowany i skonfigurowany. Stworzyliśmy bazę danych i użytkownika. Następnym krokiem jest upewnienie się, że baza danych jest wypełniona komunikatami MQTT. Przesyłanie pomiarów do bazy danych Teraz, gdy influxdb działa, musimy napisać mały skrypt, który przekazuje dane z brokera do InfluxDB. Do tego zadania został wykorzystany python, która przy użyciu biblioteki paho mqtt, zapisuje pomiary przychodzące do brokera w bazie danych. Plik został nazwany forwarder.py i można go znaleźć w katalogu głównym WeatherStation. Program rozpoczyna swoje działanie od połączenia się z brokerem o zadanym adresie IP oraz z bazą danych weather_stations w InfluxDB. Tak stworzony klient subskrybuje do zadanych tematów i nasłuchuje na wiadomości w tych tematach. Jeżeli otrzyma pomiary przez broker to wywołuje funkcje (callback), który formatuje dane i wysyła do bazy. Program działa w nieskończonej pętli i należy go wyłączyć po zakończeniu pracy. Program uruchamiamy poleceniem: $>: python forwarder.py Instalacja i konfiguracja Grafana To już ostatni krok w tworzeniu naszej stacji pogodowej. Do zainstalowania Grafany musimy najpierw sprawdzić najnowszą wersję w przeglądarce: https://github.com/grafana/grafana/releases. W tej chwili najnowsza jest wersja 6.6.0. Numer wersji umieszczamy w komendzie do pobrania i zainstalowania grafany: $>: wget https://dl.grafana.com/oss/release/grafana_6.6.0_armhf.deb $>: sudo dpkg -i grafana_6.6.0_armhf.deb $>: sudo apt-get update $>: sudo apt-get install grafana Po instalacji możemy uruchomić serwer grafana komendą w terminalu: $:> sudo service grafana-server start Dostęp do Grafany uzyskujemy na porcie 3000. Wystarczy wpisać w przeglądarce kombinację adresu IP Raspberry Pi i portu. W tym przypadku jest to 192.168.12.16:3000. Rys. 8. Widok po uruchomieniu Grafany w przeglądarce Przy pierwszym uruchomieniu wyskakuje nam okno logowania: Domyślna nazwa użytkownika i hasło to admin. Podczas pierwszego logowania możemy zmienić hasło. Teraz czas na wybranie źródła danych. Wybieramy InfluxDB. Najważniejsze pola to nazwa źródła, URL, nazwa bazy danych z której korzystamy oraz nazwa i hasło użytkownika. Zapisujemy ustawienia i przechodzimy do tworzenia panelu. Rys. 9. Źródło danych oraz widok konfiguracji panelu Tworzenie wizualizacji pulpitu nawigacyjnego odbywa się przez kliknięcie przycisku "Add panel" na górnym pasku oraz zdefiniowaniu zapytania SQL. Grafana ma ogromną ilość ustawień, ale to temat na inny artykuł. Rys. 10. Przykładowy panel w Grafanie Każdemu czytelnikowi polecam zapoznać się samemu z Grafaną. W razie pytań lub problemów, skorzystaj z sekcji komentarzy poniżej, a ja odpowiem na twoje pytania tak szybko, jak to możliwe. W załączniku został dołączony plik GrafanaWeatherStationJson, który zawiera informację o powyższym panelu. Podsumowanie W tym samouczku przeszliśmy przez całe konfiguracje stacji pogodowej od sprzętowego połączenia czujnika, przez broker MQTT aż do wizualizacji w Grafanie. Na koniec chciałbym dodać, że aplikacja została stworzona przy użyciu sprzętu firmy Dekimo Experts Delft jako część wewnętrznego projektu. WeatherStation.zip
  6. Mam w domu licznik prądu starego typu. Kiedy rachunki za prąd wzrosły powyżej 150 zł / mieś stwierdziłem, że czas na poszukiwanie przyczyn tego stanu rzeczy. Zacząłem od chińskiego watomierza, który doprowadził mnie do amplitunera Technics który w trybie standby zżera 30W. Byłem jednak ciekaw ile pobiera cały system monitoringu, lampy ogrodowe, NAS i kocioł itp. w rozkładzie godzinowym. Rozważałem zmianę taryfy z G11 na G12 lub G12W. Potrzebowałem danych. Ręczne spisywanie stanów licznika jest nużące i nudne. Przyszedł czas na emeocv - Electric meter with OpenCV. To darmowa biblioteka udostępniona na github. Pozwala na odczyt licznik na podstawie analizy zdjęć i zapis do RRD (Round Robin Database). Program napisany jest w C++ i korzysta ze znanej biblioteki OpenCV. Uruchomienie odczytów zajęło mi sporo czasu i nie dawało satysfakcjonujących wyników z uwagi na potrzebę dostosowania wielu zmiennych i rekalibracji po nawet delikatnej zmianie położenia kamerki. Przyszedł czas na instalację IDE pod C++ i wydanie własnej wersji programu. Krótka lista ficzerów: analiza zdjęć licznika dostarczanych z kamerki trening algorytmu poprzez ręczną klasyfikację przykładowego materiału zapis danych do CSV wewnętrzna kontrola jakości danych możliwość zapisu zdjęć do plików i późniejszą analizę statystyki Przejdźmy do rzeczy. Potrzebujesz: Raspberry PI (Zero, Zero W, testowałem też na RPI4b) z kartą pamięci. Alternatywnie: wystarczy dowolny komputer z pochodną Debiana (np. Ubuntu albo Linux Mint) oraz telefon komórkowy z Androidem. Kamerki (ja korzystałem z ArduCam OV5647 5Mpx) Uchwytu do kamerki - ja skorzystałem z połamanego uchwytu do telefonu (można kupić na allegro za 5-10 zł) Źródła światła (np.Lampka LED za mniej niż 5 zł) - musiałem dodać do niej rezystor bo świeciła zbyt mocno ja potrzebowałem hub'a USB żeby zasilić lampkę i malinkę z jednego zasilacza (koszt ok 10zł) Kolorowych karteczek samoprzylepnych Aplikacji Emeocv2 (moja własna wersja aplikacji wspomnianej powyżej) Dobrego nastroju i trochę czasu Wersja dla Raspberry PI Przygotowanie sprzętu: zamocuj kamerkę na statyw lub uchwyt, podłącz do malinki, ustaw światło tak aby niezależnie od światła dziennego licznik był równomiernie oświetlony. Ważne żeby nie świecić na wprost na szybkę licznika, bo pojawią się silne refleksy które utrudnią odczyt. Potem przyklej do licznika dwa kolorowe (najlepiej niebieskie) markery z karteczek samoprzylepnych (jeśli będą odpadać - użyj taśmy dwustronnej). Dzięki nim pogram bedzie w stanie ustalić obszar na którym znajdują się cyfry do analizy. Na zdjęciu poniżej widać przykładowy setup. Nie jest to za piękne ale to nie dzieło sztuki Instalacja: 1. Zainstaluj czystego Raspbiana na swoje malince 2. Podłącz kamerkę do Raspberry PI i włącz poprzez komendę raspi-config 3. Połącz się z RPI przez SSH (lub VNC) i pobierz Emeocv2 z https://github.com/wof2/emeocv2 4. Wejdź do katalogu głównego Emeocv2 i uruchom: ./debian_ubuntu_dependencies.sh Skrypt pobierze potrzebne zależności (przede wszystkim OpenCV) 5. Zbuduj make RELEASE=true 6. Wejdź do katalogu Release chmod +x emeocv 7. Zrób trochę zdjęć z kamerki aplikacją raspistill i zapisz pliki .png do wybranego katalogu. Hint: jeśli twój licznik znajduje się w pomieszczeniu gdzie zmieniają się warunki oświetlenia to jak będziesz wygładzał parametry najlepiej skorzystaj z trybu timelapse żeby zebrać zdjęcia z całej doby (np. co 15 min.). Najlepiej rób zdjęcia w rozdzielności nie większej niż 800x600. 8. Uruchom aplikację w trybie 'adjust' (najlepiej przeczytaj help do komendy - opal ją bez parametrów: ./emeocv) wskazując katalog w którym zapisałeś wcześniej zdjęcia. Pewnie analiza zakończy się błędem - musisz dostosować kilka parametrów - w katalogu Release edytuj plik config.yml. Najważniejsze parametry to: rotationDegrees: 0 #obraca obraz przed analizą cannyThreshold1: 120 # dolna granica dla algorytmu znajdowania konturów dostosuj metodą prób i błędów. Możesz zapisywać plik yml w trakcie analizy w trybie 'adjust' - co zdjęcie konfiguracja wczytywana jest ponownie. cannyThreshold2: 260 # górna granica znajdowania konturów. digitYAlignment: 20 # maksymalne różnie z położeniu kolejnych cyfr w osi Y mierzone w pikselach. counterMarkerHLOW: 85 # kolor markera (karteczki) w skali HSL (poczytaj w necie). Domyślne wartości ustawione są na detekcję niebieskiego. Wartość H (Hue) min. counterMarkerHHI: 110 # jak wyżej tylko max counterMarkerSLOW: 120 # wartość minimalnego nasycenia (Saturation) counterMarkerVLOW: 120 # minimalne V (Value) koloru karteczki. maxImageHeight: 600 # automatyczne przeskalowanie w dół - ustaw jeśli karmisz program dużymi obrazkami. digitCount: 7 # Łączna liczba cyfr na liczniku (łącznie z tą po przecinku) 9. Kiedy będziesz miał satysfakcjonujące wyniki z wcześniej zapisanych zdjęć to pora na trening naszego algorytmu. Uruchom emeocv z opcją -l (Learn). Teraz program będzie pokazywał serię zdjęć i pytał cię o klasyfikację zdjęć poszczególnych cyfr do skali 0-9. Potrzebujesz z grubsza tyle samo próbek dla każdej z cyfr. Możesz skorzystać z opcji emeocv -p żeby pokazać statystyki nauki. ./emeocv -p OCR stats: Trained responses: 1094 Trained responses histogram: Digit '0'->167 Digit '1'->184 Digit '2'->152 Digit '3'->148 Digit '4'->64 Digit '5'->60 Digit '6'->60 Digit '7'->112 Digit '8'->73 Digit '9'->74 10. Pora na automatyczne rozpoznanie cyfr na całym zbiorze zdjęć i pokazanie wyników ./emeocv -t -i obrazki/ -vDEBUG -s 10 11. Jeśli wyniki są ok to produkcyjnie odpalamy robienie zdjęć (np. co 2 minuty), analizę i wyplucie wyników do CSV. Służy do tego opcja -w (Write). Dla kamerki raspberry PI polecam wykorzystanie operacji -k, która pobiera zdjęcia z wyniku działania komendy w pliku config.yml. Domyślnie jest to raspistill czyli miniprogram na raspbianie do robienia zdjęć: cliCaptureCommand: raspistill -w 800 -h 600 -n -o Teoretycznie możesz tu nawet wsadzić pobieranie zdjęć z innego urządzenia. Alternatywnie użyj operacji -c (czyli Camera, podaj nr kamery np. -c0). Opcja wykorzystuje API openCV do odczytu z kamery. Mnie się ta opcja nie sprawdziła bo zdjęcia wychodziły albo za ciemne, albo poszczególne odczyty bardzo różniły się od siebie. 12. Wyniki będą się pojawiać w pliku emeocv.csv w katalogu Release. Patrz w logi emeocv.log i nie przejmuj się jeśli po kilkunastu przeanalizowanych zdjęciach plik jest pusty. Program cache'uje wyniki z ostatnich chyba 12 wyników i dopiero kiedy uzyska sensowną niemalejącą serię odczytów to dokonuje zapisu do pliku. Plik CSV możesz potem wciągnąć gdzie chcesz np. do arkuszy Google. Skorzystaj z mojego. Więcej informacji znajdziesz na https://github.com/wof2/emeocv2 Wersja z wykorzystaniem telefonu komórkowego - wkrótce
  7. Cześć Wam, A więc od początku Zbudowałem platformę robota z Raspberry Pi Zero na pokładzie. Do RPi podłączyłem płytkę PiMotor z L293DNE na pokładzie. Silniki zasilałem 4 bateriami NIMH co dawało z grubsza 5 V na wejściu do L293D. Niestety na mostku przez straty napięcia na silnikach napięcie wynosiło 3 V, przez co trochę brakowało mocy; optimum to 4.5V dla silników ( DAGU DG01D). Generalnie robocik jeździł. Ale... wpadłem na pomysł, aby podłączyć baterię LiPo 7.4 V 2S 20C /40C burst, (1100 mAh) licząc na optymalniejsze napięcie pracy silników. W zamian... usłyszałem huk, ujrzałem dym i ogień na układzie L293D oraz rozerwaną przetwornicę step-down TS2596 Ponieważ nie mam dużego doświadczenia z LiPO, chciałbym Was podpytać, co poszło "nie tak"? Polarność podłączona na 100% OK. Czyżby na układ poszedł jakiś potężny prąd z LiPO? Niby dlaczego? Będę wdzięczy za odpowiedź. Poniżej zdjęcia z "eksperymentu" P.S. RPi przeżyło ten szok!
  8. MQTT jest popularnym, bo prostym w obsłudze protokołem komunikacji. Najłatwiej jest porównać to do systemu YouTube: są subskrybenci i nadawcy. Nadawca może mieć wielu subskrybentów ale też jedno urządzenie może słuchać wielu nadawców (co - trochę jak w prawdziwym życiu - nie zawsze kończy się dobrze). Cała architektura wygląda w ogólnym przypadku w następujący sposób: W tym artykule zajmiemy się przygotowaniem środowiska oraz wysłaniem “hello world”. Zakładam, że na Raspberry jest zainstalowany raspbian. Jeśli nie to koniecznie sięgnij do odpowiedniego poradnika na Forbocie. Na Raspberry możesz pracować zdalnie lub lokalnie, to nijak nie wpływa na działanie systemu. Konfiguracja serwera W charakterze serwera posłuży nam Raspberry Pi. W zasadzie każdy model powinien się sprawdzić, ale zalecane jest użycie przynajmniej drugiej wersji. Aby wszystko działało jak trzeba potrzebujemy pakietu Mosquitto. Wydajemy następujące komendy: aktualizacja systemu: sudo apt-get update && sudo apt-get upgrade -y instalacja mosquitto: sudo apt-get install mosquitto -y automatyczne uruchomienie przy starcie: sudo systemctl enable mosquitto.service I… to już. Serwer został zainstalowany. Teraz jeszcze tylko restart i możemy przejść dalej. Potrzebujemy jeszcze dwa urządzenia, które będziemy ze sobą komunikować. Pierwszym z nich będzie Raspberry Pi. Będzie na nim uruchomiona usługa Node-Red dzięki której będziemy mogli w łatwy sposób odczytywać dane i sterować urządzeniami wykonawczymi. Drugie urządzenie to ESP32. Przy jego pomocy będziemy sterować diodą, która potwierdzi poprawne przejście przez instalację. Node-Red Do instalacji potrzebujemy następującej komendy: sudo apt-get install nodered -y Po skończeniu instalacji możemy dodać automatyczne uruchamianie przy starcie: sudo systemctl enable nodered.service Aby wyłączyć automatyczny start wpisujemy: sudo systemctl disable nodered.service Uruchamiamy działanie serwisu poprzez komendę: sudo node-red-start Potrzebujemy teraz poznać IP maliny (jeśli pracujemy lokalnie). Wykonujemy to poprzez: ifconfig Jeśli przechodzisz przez ten artykuł tylko “dla zajawki” to możesz poprzestać na tej komendzie. Jeśli jednak stawiasz to “na stałe” to musisz zrobić jeszcze jedną rzecz, z którą nie bardzo mogę pomóc. Należy ustawić statyczne IP dla maliny. Robi się to na routerze, w panelu administracyjnym. Ze względu na mnogość rozwiązań różnych producentów routerów musisz poszukać odpowiedni poradnik w internecie. Jak wspomniałem, jest to tylko dla osób, które stawiają serwer na stałe. Po instalacji Node-Red przechodzimy do przeglądarki. W pasku na adres url wpisujemy adres IP z portem 1880. Czyli pracując lokalnie na Raspberry wpiszemy: 127.0.0.1:1880 natomiast pracując zdalnie wpiszemy ip:1880. W moim przypadku jest to 192.168.100.194:1880. Powinniśmy dostać taki obraz: Klikamy na trzy paski w prawym górnym rogu i wybieramy opcję “Manage palette”: W oknie dialogowym przechodzimy do zakładki install i wpisujemy dashboard. Wybieramy drugą opcję z góry: Po zatwierdzeniu instalacji czekamy, aż proces się skończy. Ta wtyczka umożliwia nam utworzenie graficznego interfejsu użytkownika. Po zakończeniu instalacji zamykamy okno dialogowe i z listy po lewej stronie wybieramy opcje oraz je łączymy. Wybieramy opcje MQTT (obie) z sekcji network oraz z sekcji dashboard wybieramy switch oraz show notification. Łączymy ze sobą te punkty wg następującego schematu: Następnie dwa razy klikamy w pierwszy obiekt mqtt. Klikamy w ikonkę z ołówkiem która otworzy nam dodatkowy panel. W otrzymanym polu edycji wpisujemy tylko localhost, klikamy Add. Dalej, w polu Topic wpisujemy esp32/message i ustawiamy QoS jako 1. Podobne kroki wykonujemy dla drugiego punktu z mqtt przy czym serwer powinien zostać uzupełniony automatycznie, w polu Topic wpisujemy esp32/gpio, ustawiamy QoS jako 1 i retain jako false. Ostatni punkt w konfiguracji Node-Red to ustawienie przełącznika. Wchodzimy w jego okno dialogowe, dodajemy nową grupę (Klikamy w ołówek koło pola “Group”) znowu klikamy ołówek dalej Add i znowu Add. W ustawieniach schodzimy trochę niżej i ustawiamy On Payload jako typ number (pierwsza rozwijana ikonka) i wpisujemy 1 oraz ustawiamy Off Payload jako number i wpisujemy 0. Klikamy Deploy w prawym górnym rogu i trzymamy kciuki. Po zapisaniu zmian otwieramy nowe okno przeglądarki i wpisujemy ip:1880/ui. Pozostała część adresu zostanie uzupełniona automatycznie. Mając tak przygotowane środowisko przechodzimy do ostatniego punktu czyli modułu ESP32. ESP32 Programować będziemy w Arduino IDE. Aby jednak móc to zrobić musimy przygotować środowisko. Nie będę się zagłębiał w ten temat bo jest wiele dobrych poradników o tym w internecie (np.: tutaj) Dodatkowo w managerze bibliotek instalujemy bibliotekę PubSubClient oraz ESPMQTTClient. W fizycznym podłączeniu warto jest sprawdzić najpierw pinout naszej płytki w internecie oraz ewentualnie zmienić numer pinu w kodzie. Następnie wybieramy odpowiednią płytkę, wgrywamy przykładowy szkic i… nie działa. Po pierwsze dlatego, że należy zmienić ssid (czyli nazwy sieci, do której jest podłączone też raspberry pi), hasło oraz adres IP serwera na adres maliny. Po drugie dlatego, że często są problemy z tymi płytkami (o tym w kolejnym akapicie). Jeśli jednak udało się wszystko wgrać powinniśmy dostać wiadomość w panelu sterowania oraz możemy sterować diodą przez przełącznik. Kod testowy prezentuje się następująco: #include <WiFi.h> #include <PubSubClient.h> const char* ssid = "Nazwa wifi"; //ZMIENIC na swoje const char* password = "haslo do wifi"; //ZMIENIC na swoje const char* mqtt_server = "IP Raspberry Pi"; //ZMIENIC na swoje const char* deviceName = "ESP32"; //poki co nie trzeba zmieniac //ale przy wiekszej ilosci urzaden kazde musi miec swoja nazwe const char* startMessageTopic = "esp32/message"; //temat do wyslania wiadomosci const char* pinTopic = "esp32/gpio"; //temat do odbioru wiadomosci const int ledPin = 27; //numer pinu diody, ZMIENIC JESLI TRZEBA WiFiClient espClient; PubSubClient client(espClient); void reconnect() { bool ctd = false; //funkcja jest wywolywana jesli utracono polaczenie z serwerem Serial.println("Rozlaczono!"); while(!ctd) { Serial.print("Laczenie z serwerem..."); if(client.connect(deviceName)) { ctd = true; Serial.println("Polaczono!"); } else { Serial.print("."); delay(1000); } } } void odbiorWiadomosci(String temat, byte* zawartosc, unsigned int dlugosc) { String pomoc; Serial.println("Odebrano wiadomosc:"); Serial.print("\tTemat: "); Serial.println(temat); Serial.print("\tTresc: \""); for(int i=0; i<dlugosc; i++) { Serial.print((char)zawartosc[i]); pomoc += (char)zawartosc[i]; } Serial.println("\""); if(temat == pinTopic) { if(pomoc == "1") { digitalWrite(ledPin, HIGH); Serial.println("LED1: ON"); } else if(pomoc == "0") { digitalWrite(ledPin, LOW); Serial.println("LED1: OFF"); } else Serial.println("Nieznana komenda, nie wiem co mam z tym zrobic"); } } void ustawienieWifi() { delay(10); Serial.println(); Serial.print("Laczenie z "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Polaczona z wifi.\nESP otrzymalo adres IP: "); Serial.println(WiFi.localIP()); } void setup() { Serial.begin(115200); pinMode(ledPin,OUTPUT); ustawienieWifi(); //polaczenie z wifi delay(1000); client.setServer(mqtt_server, 1883); //ustawienie serwera mqtt client.connect(deviceName); //polaczenie z podana nazwa client.subscribe(pinTopic); //ustawienie nasluchiwania w podanym temacie client.setCallback(odbiorWiadomosci); //ustawienie funkcji do odbioru wiadomosci client.publish(startMessageTopic, "Hello from ESP32"); //wyslanie pierwszej wiadomosci } void loop() { if (!client.connected()) //jesli klient zostal rozlaczony { reconnect(); //polacz ponownie client.publish(startMessageTopic, "Hello from ESP32"); //wysliij wiadomoc powitalna } if(!client.loop()) client.connect(deviceName); //upewnienie sie, ze klient jest stale podlaczony } Jako, że jest to pierwszy kontakt z tym protokołem i programem pozwolę sobie nie zagłębiać się w szczegóły. Starałem się wszystko opisać w komentarzach kodu. Dodatkowo dużo rzeczy jest wyświetlanych w konsoli, więc warto tam zajrzeć. Problemy, problemy, problemy Często zdarza się tak, że płytki z rodziny ESP nie współpracują ze wszystkimi komputerami. W moim przypadku na 4 komputery bez problemu mogę podłączyć się z dwóch. Z jednego muszę używać programatora FTDI a jeden (najnowszy) działa trochę jak ślepy koń: nie widzi przeszkód (a w zasadzie nie widzi płytek). Jeśli natomiast są problemy przy wygrywaniu można spróbować wybrać inną płytkę w ustawieniach IDE lub pomajstrować z ustawieniami wybranej płytki (znowu odsyłam do internetu, źródeł trochę jest). Osobiście pracowałem na płytce Esp32 Wroom, a wgrywanie działało przy ustawieniach dla płytki LOLIN D32. Ten wpis bierze udział w konkursie na najlepszy artykuł o elektronice lub programowaniu, którego partnerem jest firma PCBWay (popularny producent prototypów PCB). W puli nagród karty podarunkowe Allegro o wartości 2300 zł. Sprawdź więcej informacji na temat konkursu »
  9. Stawiam Pi-Hole na Raspberry Pi Zero W i postanowiłem w ramach ćwiczeń własnoręcznie stworzyć adapter USB w oparciu o dostępne na rynku rozwiązania. Znajdzie się ktoś, kto rzuci okiem, czy płytka jest zaprojektowana zgodnie ze sztuką? Poniżej załączam materiały, na których się opierałem podczas projektowania.
  10. Cześć wszystkim. To mój pierwszy temat na tym forum, Więc przy okazji witam wszystkich Pokaże wam dzisiaj bardzo prosty sposób wykorzystania Raspberry Pi jako konsoli do gier, ja osobiście dzięki temu projektowi zacząłem interesować się elektroniką. O ile sama elektronika nie jest tutaj zbyt zaawansowana to będziemy potrzebować minimalnych umiejętności posługiwania się elektronarzędziami. Zaczynamy. Na początku potrzebujemy Raspberry Pi, Ja osobiście użyłem Raspberry Pi 3 B+ ponieważ pozwala nam zagrać w gry z lepszą grafiką, nawet niektóre tytuły z PSP, jak i w miarę wygodnie korzystać z przeglądarki internetowej. Możecie jednak bez problemu korzystać ze słabszych wersji. Oprogramowanie naszej konsoli znajdziecie w tym linku Retropie możecie też użyć podobnej wersji oferującej praktycznie to samo z tego linku Recalbox Jednak w tym poradniku skupię się na tej pierwszej. Porównanie obu znajdziecie na Youtube. Na temat instalacji samego oprogramowania nie będę pisał bo jest to dość proste i wszystko znajdziecie w tym linku instalacja Powiem jedynie żeby oprócz konsoli nie zapomnieć o możliwości przejścia do Rasbiana, znajdziecie też filmy jak uruchomić dodatkowe konsole i wgrać kodi. O ile tutaj wszystko jest jasne, to trudniejsza częścią jest zabudowa naszej konsoli. Osobiście użyłem Starego automatu który znalazłem na śmietnisku .Nie była to maszyna do gier arcade, a tak zwany jednoręki bandyta, taki jak jak na zdjęciu numer 2 (niestety nie mam zdjęcia jak wyglądał przed). Jednak nie każdy ma do takiego dostęp dlatego wrzucam wymiary mojej, byście mogli wyciąć taką np ze sklejki i poskładać samemu. Jeśli jest to dla was za duży kawał mebla to znajdziecie w na Youtube czy w Google projekty trochę bardziej poręcznych, ale już nie robiących takiego wrażenia. Jako że ja swoją przerabiałem musiałem najpierw zrobić w naklejce na szybie wycięcie na monitor (17cali od starego komputera) i pozbyć się pozostałych w środku resztek starego systemu. Później musimy zamontować przyciski i joystick, są w pełni kompatybilne z konsolą. W moim przypadku zostawiłem 2 działające przyciski Start i Payout z oryginału. Mała rada by przedni panel zrobić otwierany, w przypadku drobnych modyfikacji nie musimy odsuwać szafy od ściany. Trzeba zadbać teraz o audio, u mnie sprawę załatwia mała wieża podłączona pod Raspberry, z oddzielnym wyjściem aux by podłączyć telefon. Otwory na głośniki należy wyciąć w płycie. Nie zapomnij o wnetylatorach i otworach wentylacyjnych. Ponieważ w zamkniętej obudowie potrafi się zrobić gorąco. Ładnie pochowaj, wyprowadź kable i zamontuj raspberry. W przednim panelu zamontowałem atrapę komputera dla wyglądu. Wyprowadź też kable usb by można było podłączyć pady. Ja schowałem je w miejscu na wypłatę monet. W schowku na dole jest szuflada na różne rzeczy jak i mała schładzarka do napojów. Do tego użyłem podobnego zestawu zestawu chłodzącego. Daję radę, ale bardziej do podtrzymywania zimnej temperatury, max udało mi się osiągnąć 13 stopni dlatego polecam użyć większego, trochę droższego zestawu. Schładzarkę należy czymś wyłożyć by zapewnić izolację i w miarę szczelnie zamknąć by nie uciekała nam temperatura. Ja użyłem starej karimaty ale są na pewno lepsze sposoby. Naszą szafę dobrze jest wyłożyć matami głuszącymi dla cichej pracy. Na końcu montujemy Ledy. Projekt można rozwijać o np. licznik monet, panel dotykowy i co tylko przyjdzie do głowy. W przyszłości mam zamiar poprawić lodówkę by działała lepiej, zmienić monitor i dodać trochę więcej przycisków. Mam nadzieję że projekt wam się podoba. Czekam na wasze sprzęty grające.
  11. O mnie Witam, Jestem Maciej - pracuje jako software architect (nie mam wykształcenia elektronicznego dlatego proszę o wyrozumiałość jeżeli chodzi o połączenia i rozwiązania - z tego też powodu w projekcie nie daje gotowego przepisu na zasilanie ) i żeby do końca nie zgnuśnieć po godzinach tworzę platformę RemoteMe. W platformie chodzi głównie o ułatwienie sterowaniem urządzeniami IoT poprzez internet - bez konieczności posiadania VPNa, publicznego IP. Po stronie RemoteMe tworzycie strony internetowe ( RemoteMe posiada hosting na Wasze pliki ) + zestaw bilbiotek (Javascript, RasbeprryPi (python), Arduino ESP ) które w łatwy sposób pozwolą na komunikowanie się z Waszymi urządzeniami. Co do protokołu to opracowałem własny (bardziej jest to konwencja przesyłu paczek niż protokół jako taki ) (działa przez sockety, websockety, wywoływania RESTowe) - umożliwia on przesył wiadomości do określonego urządzenia, i coś w rodzaju topic- subscribera ( u mnie się to nazwa"variables" zmienne ) Wasze urządzenia rejestrują się w RemoteMe po zarejestrowaniu, możecie do nich wysyłać komendy przez stronę internetową albo z innych urządzeń. Jednym z ostatnich featerów są "Out of the box projects" - polega to na tym, że jednym kliknięciem importujecie projekt na Wasze konto - oczywiście możecie potem wszytko zmieniać wedle własnych pomysłów - właśnie ostatnim takim projektem jest Samochód RaspberryPi z kamerką o którym w tym kursie. Projekt jest częściowo openSourcowy - bilbioteki Javascript, Python, api Restowe są openSource - sam kod serwera i program na RasbeprryPi jest zamknięty. Platformę tworzę sam - po godzinach i udostępniam za darmo O kursie Ten kurs – przedstawia budowę samochodu sterowanego przez przeglądarkę z wyświetlaniem obrazu z kamerki. Jest to dość specyficzny kurs (jak pisałem wyżej ) – całość oprogramowanie jest już zrobiona, a dodanie plików do własnego konta w RemoteMe sprowadza się do paru kliknięć. Po tak dodanym projekcie można własnoręcznie i dowolnie edytować wszystkie pliki źródłowe (strona WWW skrypt pythonowy) – zwłaszcza, że same pliki projektu nie są skomplikowane, a kod jest dość czytelny i samo opisujący się (mam przynajmniej taką nadzieję ) Na dole kursu opisana jest bardziej szczegółowo zasada działania samochodu. Jeżeli nie jesteście zainteresowani samą platformą RemoteMe to i tak myślę, że w kursie znajdziecie garść pomysłów na podobny projekt Kurs właściwy Na filmie działanie + krok po kroku wszystko z tego kursu. W poprzednim kursie pokazałem jak sterować pozycją kamerki i przechwytywać obraz na przeglądarkę tutaj i sterowanie kamerką tutaj . Teraz rozbudujemy ten projekt i zbudujemy samochód z napędem na 4 koła ( sterowany podobnie jak czołg – żeby skręcić prawa para kół musi się kręcić z inną prędkością niż lewa). Taki efekt otrzymamy na wideo też całość kursu – można zaglądnąć, gdy gdzieś utkniecie Części RaspberryPi z wifi ( np zeroW) link Podwozie z silnikami link Sterownik serwomechanizmów na I2C link Kamera do Rpi + taśma jeżeli potrzebna link Dwa SerwoMechanizmy kompatybilne z uchwytem kamerki kamery link Uchwyt na kamerkę z serwami link Mostek H TB6612FNG link Zasialnie – np akumlatory podłączone do przetwornicy – żeby uzyskać odpowiednie napięcie link Połączenia RaspberryPI steruje serwami poprzez moduł PWM i napędem przez ustawianie stanu pinów na mostku oraz dostarczając sygnału PWM poprzez ten sam moduł, który wysyła sygnał do serwomechanizmów. (Dzięki modułowi do generowanie sygnału PWM nie musimy tych sygnałów generować przez samo RaspberryPi – co jest dość problematyczne, poprostu przez I2C przesyłamy odpowiednie instrukcje do sterownika serw (poprzez bibliotekę pythonową dostarczoną przez adafruit), a ten generuje odpowiedni sygnał PWM dla serwo mechanizmów i do mostka H) Schemat połączeń: Poprzez magistrale I2C RPi steruje kontrolerem serwo mechanizmów, dwa ostanie wyprowadzenia kontrolera są podłączone do mostka H, gdzie wykorzystując sygnał PWM ustawiamy prędkość silników. Do mostka H są również podłączone piny RPi które stanami wysokim i niskim będą określać kierunek obrotu silników napędowych – po szczegóły odsyłam do dokumentacji układu TB6612FNG, równie dobrze można użyć mostka L298N lub podobnego. Zaprojektowałem płytkę PCB, którą możecie użyć pliki eagle,gerber itd tutaj plik pcb.zip Schemat płytki pokrywa się ze schematem powyżej. Wyprowadzenia płytki: Wejście sygnału PWM z kanałów 15 i 14 modułu PWM Wejście zasilania silników do poruszania się Zasilanie układów (PWM, RPi) koniecznie dokładne +5V Wyjście silników napędu, pierwsze dwa wyjścia do jednej pary silników kolejne dwa do drugiej Zasilanie serw i w tym przypadku silników napędu w moim przypadku ~6V (należy sprawdzić w specyfikacji serw i silników, jakie maksymalne napięcie można podłączyć) ZWORKA gdy zepniemy dwa piny napięcie z 5 będzie podawane też do zasilania silników napędu ZWORKA gdy jest podłączona zasilane jest RaspberryPI z połączenia 3 przed podłączeniem zworki należy dokładnie sprawdzić napięcia, żeby nie uszkodzić Najdroższego komponentu czyli właśnie malinki Wlutowujemy kabelki, bo nie będziemy korzystali z konwertera stanów Wlutowujemy kabelki, bo nie będziemy korzystali z konwertera stanów Oczywiście jest jeszcze potrzebne odpowiednie zasilanie, w moim przypadku 6v jako napięcie silników napędu i serw, oraz 5v dla RasbeprryPi i kontrolerów. Poniżej kilka zdjęć poglądowych całości samochodu: Programowanie Przed utworzeniem projektu skonfigurujcie kamerkę i komunikacje I2C używając raspi-config opisane tutaj. Ten projekt jest jednym z gotowych projektów, które możecie prosto zaimplementować kilkoma kliknięciami: KLIK - po zalogowaniu otworzy się projekt. Przejdźcie do zakładki “Build It” i podążajcie krokami, na końcu klik w “Build Project” i otrzymacie: Po kliknięciu “Get QR” pokaże się kod QR, który możecie zeskanować smartfonem, lub po prostu otworzyć stronę przyciskiem “Open” w przeglądarce na komputerze. Narazie nie radzę zmieniać pozycji kamery dopóki nie ustawimy pozycji serw – w niektórych przypadkach możecie uszkodzić swoje serwomechanizmy. Samochód powinien jeździć jak na filmie – może się zdarzyć, że skręca w złą stronę albo serwa są źle skalibrowane, poniżej w omawianiu kodu napisałem jak to naprawić. Omówienie tego, co się stało Jak zauważyliście, tworzenie projektu było mocno zautomatyzowane. Dlatego omówię teraz, co się dokładnie wydarzyło i jak modyfikować Wasz projekt. Przede wszystkim utworzyły się dwie zmienne (zakładka variables): Zmienna cameraPos przesyła pozycje kamery, drive pozycje joysticka. Obie są typem “Small int x2” oznacza to, że wartoscią zmiennej są dwie liczby integer. Strona internetowa zmienia nasze zmienne, a skrypt pythonowy te zmiany rejestruje i odpowiednio reaguje (jak rozwiniemy zmienne zobaczymy, że urządzeniem nasłuchującym na zmiany jest właśnie skrypt pythonowy). Zobaczmy jak wygląda kod Pythonowy (więcej o zmiennych tutaj) Python Skrypt pythonowy został automatycznie wgrany. Oczywiście możemy go podejrzeć i modyfikować ( żeby stworzyć nowy skrypt pythonowy np dla innych projektów zobacz tutaj) . Z informacji jakie teraz są Ci potrzebne to skrypt pythonowy to kolejne urządzenie w remoteMe jest zarządzalne przez skrypt (uruchomiony przez ./runme.sh) , do tego urządzenia możemy wysłać wiadomości, urządzenie reaguje też na zmiany zmiennych, które obserwuje i może te zmienne zmieniać. Żeby otworzyć skrypt pythonowy kliknij python.py i wybierz Edit : Wygląda on następująco. Poniżej omówię ciekawsze fragmenty import logging import socket import math import struct import sys import os os.chdir(sys.argv[1]) sys.path.append('../base') import remoteme import Adafruit_PCA9685 import time import RPi.GPIO as GPIO motorAIn1 = 25 # GPIO25 motorAIn2 = 8 # GPIO8 motorBIn1 = 24 # 24 motorBIn2 = 23 # 23 motors = [[motorAIn1, motorAIn2], [motorBIn1, motorBIn2]] motorsPWM = [14, 15] pwm = None; def motorForward(motorId): GPIO.output(motors[motorId][0], GPIO.LOW) GPIO.output(motors[motorId][1], GPIO.HIGH) def motorBackward(motorId): GPIO.output(motors[motorId][0], GPIO.HIGH) GPIO.output(motors[motorId][1], GPIO.LOW) def motorSoftStop(motorId): GPIO.output(motors[motorId][0], GPIO.LOW) GPIO.output(motors[motorId][1], GPIO.LOW) def setMotor(motorId, speed): if speed == 0: motorSoftStop(motorId) elif speed > 0: motorForward(motorId) elif speed < 0: motorBackward(motorId) speed=-speed logger.info("set speed {} for motor {} ".format(speed,motorId)) pwm.set_pwm(motorsPWM[motorId], 0, int(speed)) def onCameraPosChange(i1, i2): global pwm logger.info("on camera change {} , {}".format(i1, i2)) pwm.set_pwm(1, 0, i1) pwm.set_pwm(0, 0, i2) pass def onDriveChange(x, y): logger.info("on drive change x {} , y {}".format(x, y)) global pwm left=y right=y left+=x right-=x delta=(left+right)/2 left+=delta right+=delta # when your car doesnt drive as suppose try to swich right and left variable below # or remove add minuses next to 2 # another way is to switch cables conencted to motors setMotor(0, 2*left) setMotor(1, 2*right) pass def setupPWM(): global pwm pwm = Adafruit_PCA9685.PCA9685() pwm.set_pwm_freq(80) def setupPins(): global GPIO GPIO.setmode(GPIO.BCM) # Broadcom pin-numbering scheme for motor in motors: for pinId in motor: GPIO.setup(pinId, GPIO.OUT) try: logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', datefmt='%d.%m %H:%M', filename="logs.log") logger = logging.getLogger('application') setupPWM() setupPins() remoteMe = remoteme.RemoteMe() remoteMe.startRemoteMe(sys.argv) remoteMe.getVariables().observeSmallInteger2("cameraPos" ,onCameraPosChange); remoteMe.getVariables().observeSmallInteger2("drive" ,onDriveChange); remoteMe.wait() finally: pass Sterowanie silnikami: def motorForward(motorId): GPIO.output(motors[motorId][0], GPIO.LOW) GPIO.output(motors[motorId][1], GPIO.HIGH) def motorBackward(motorId): GPIO.output(motors[motorId][0], GPIO.HIGH) GPIO.output(motors[motorId][1], GPIO.LOW) def motorSoftStop(motorId): GPIO.output(motors[motorId][0], GPIO.LOW) GPIO.output(motors[motorId][1], GPIO.LOW) def setMotor(motorId, speed): if speed == 0: motorSoftStop(motorId) elif speed > 0: motorForward(motorId) elif speed < 0: motorBackward(motorId) speed=-speed logger.info("set speed {} for motor {} ".format(speed,motorId)) pwm.set_pwm(motorsPWM[motorId], 0, int(speed)) Funkcja setMotor dla motorId 1 lub 2 ustawia prędkość speed (może być ujemna). poprostu najperw na odpowiednich pinach ustawiamy odpowiednio stany (ruch do przodu do tyłu, hamowanie), a następnie w zależności od prędkości ustawiamy odpowiednio wypełnienie PWM korzystając ze sterownika serw. def onCameraPosChange(x, y): global pwm logger.info("on camera change {} , {}".format(x, y)) pwm.set_pwm(1, 0, x) pwm.set_pwm(0, 0, y) pass Funkcja setMotor dla motorId 1 lub 2 ustawia prędkość speed (może być ujemna). poprostu najperw na odpowiednich pinach ustawiamy odpowiednio stany (ruch do przodu do tyłu, hamowanie), a następnie w zależności od prędkości ustawiamy odpowiednio wypełnienie PWM korzystając ze sterownika serw. def onDriveChange(x, y): logger.info("on drive change x {} , y {}".format(x, y)) global pwm left=y right=y left+=x right-=x delta=(left+right)/2 left+=delta right+=delta # when your car doesnt drive as suppose try to swich right and left variable below # or remove add minuses next to 2 # another way is to switch cables conencted to motors setMotor(0, 2*left) setMotor(1, 2*right) pass Powyższa funkcja zostanie wywołana jak zmieni się zmienna drive – np po zmianie joysticka na stronie. x,y to po prostu współrzędne wychylenia joysticka (1024,1024) oznacza wychylenie maksymalnie do góry i w prawo. Na podstawie tych zmiennych wyliczamy prędkość lewej i prawej strony samochodu. Jeżeli samochód skręca, zamiast jechać do przodu, jedzie do tyłu zamiast do przodu: setMotor(0, Y2*left) setMotor(1, X2*right) Dajcie minusy w różnych kombinacjach (w miejsca X i Y) do czasu, aż samochód jedzie do przodu – gdy joystick jest wychylony do góry. (będzie to odpowiadać zamianą miejscami przewodów lewej strony dla miejsca Y i prawej strony dla miejsca X). Następnie, jeżeli prawa i lewa strony są zamienione (samochód skręca w złą stronę ), w funkcji powyżej zamieńcie left i right miejscami. def setupPWM(): global pwm pwm = Adafruit_PCA9685.PCA9685() pwm.set_pwm_freq(80) def setupPins(): global GPIO GPIO.setmode(GPIO.BCM) # Broadcom pin-numbering scheme for motor in motors: for pinId in motor: GPIO.setup(pinId, GPIO.OUT) Po prostu ustawiamy odpowiednie piny (te do sterowania mostkiem H) na wyjścia. I tworzymy obiekt do kontrolowania sterowania serw. (Uwaga żeby sterownik serw działał prawidłowo musimy włączyć komunikacje I2C używając raspi-config więcej tutaj ) remoteMe.startRemoteMe(sys.argv) remoteMe.getVariables().observeSmallInteger2("cameraPos" ,onCameraPosChange); remoteMe.getVariables().observeSmallInteger2("drive" ,onDriveChange); remoteMe.wait() Ustawienie RemoteMe i ustawienie jakie funkcję mają zostać wywołane, gdy zmienne do sterowania kamery i napędu zostaną zmienione. To tyle w samym skrypcie pythonowym, jak widzicie, nie jest on zbyt skomplikowany, po więcej informacji zapraszam tutaj Strona WWW Tak naprawdę zostały stworzone dwie strony WWW — jedna do kalibracji druga — strona do sterowania samochodem i wyświetlania obrazu z kamerki. Otwórzmy stronę do kalibracji: Otworzy się strona internetowa z dwoma suwakami. Ustawmy górny i dolny na środkową pozycję – kamera się poruszy- górny suwak powinien poruszać kamerę w osi x, dolny y. Jeżeli się tak nie dzieje – zamieńcie miejscami przewody serwomechanizmu. Następnie za pomocą suwaków ustalcie maksymalne wychylenie osi x i osi y dla mnie jest to: x : 298 – 830 i centralna pozycja. Ważne, żeby centralna pozycja byłą dokładnie pomiędzy przedziałem u mnie ((298+830) /2 = 564) y: 223 – 723 i podobnie centralna pozycja kamery w osi y powinna być w środku przedziału Zapiszmy liczby gdzieś w notatniku i otwórzmy do edycji stronę do sterowania samochodem: <camera autoConnect="true" showInfo="true" class="cameraView"></camera> <connectionstatus webSocket="true" directConnection="false" camera="true"></connectionstatus> <variable component="cameraMouseTrack" type="SMALL_INTEGER_2" style="display:block" name="cameraPos" xMin="298" xMax="830" invertX="true" yMin="223" yMax="723" invertY="true" requiredMouseDown="true" reset="true" onlyDirect="true"></variable> <div class="joystickButtons"> <div class="buttons"> <variable class="gyroscope" component="gyroscope" type="SMALL_INTEGER_2" name="cameraPos" label="Gyroscope Camera" orientationSupport="true" xMin="298" xMax="830" xRange="19" invertX="true" yMin="223" yMax="723" yRange="20" invertY="false" onlyDirect="true"></variable> <variable class="gyroscope" component="gyroscope" type="SMALL_INTEGER_2" name="drive" label="Gyroscope Drive" xMin="-512" xMax="512" xRange="19" invertX="false" yMin="-512" yMax="512" yRange="20" invertY="false" onlyDirect="true"></variable> <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect gyroscope" onClick="toggleFullScreen()">fullscreen </button> </div> <div class="joystickParent"> <variable class="joystick" component="joystick_simple" type="SMALL_INTEGER_2" name="drive" xRange="1024" yRange="1024" onlyDirect="true"></variable> </div> <div style="clear: both;"/> </div> Są to automatyczne komponenty do sterowania samochodem i wyświetlaniem obrazu wideo. Strona, którą otworzyliście zawiera już wszystkie komponenty potrzebne do sterowania waszym samochodem. Jedyne co trzeba zrobić to zmienić zakres ruchów serwo mechanizmów. xMin,xMax,yMin,yMax, zamieńcie na wartości jakie otrzymaliście na poprzedniej stronie z suwakami. Jeżeli chcecie stworzyć własną stronę ze swoimi komponentami najlepiej utworzyć ją od początku pokazane tutaj – pozwoli Wam to dodawać komponenty w przy pomocy kreatora, gdzie ustalicie potrzebne parametry, albo po prostu edytować źródła tej już utworzonej strony – wcześniej warto utworzyć kopię, gdyby coś poszło nie tak (albo skasować pliki i utworzyć projekt jeszcze raz – wtedy nie zapomnijcie wcześniej wykasować też zmienne) Po zmianie wartości x/y/Min/Max możemy otworzyć naszą stronę np w smartfonie, klikamy na index.html, ale tym razem wybieramy opcje get anymous link Następnie, klikamy ikonkę kodu QR, a kod, który się pojawi skanujemy smarfonem. Oczywiście sterowanie działa również poprzez internet – nie tylko w sieci lokalnej, jednak w niektórych przypadkach jest potrzebna dodatkowa konfiguracja więcej o niej tutaj Trochę szczegółów technicznych ( nie obowiązkowe ) RemoteMe serwuję stronę WWW do sterowania Waszym samochodem ( a dodatkowo Was loguje na Wasze konto – stąd token w linku otwieranym przez smartfon ) i uczestniczy w negocjowaniu tworzenia połączenia WebRTC. Połączenie webRTC jest to połączenie bezpośrednie (RaspberryPi – przeglądarka ( w niektórych przypadkach np za NATem jest potrzebny dodatkowo stun sewer)). Po stworzeniu połączenia webRTC stan zmiennych nie jest w ogóle wysyłany do remoteMe (bo pole “onlyDirect” w komponentach jest ustawione na true). Protokołem webRTC przesyłany jest też obraz, a że webRTC tworzy połaczenie point to point opóźnienie jest znikome. Program na RaspberryPi który odpalacie poleceniem ./runme.sh tworzy połączenie websocketowe z platformą RemoteMe oraz zarządza skryptem pythonowym (wysyła do niego wiadomości, przesyła wiadomości ze skryptu dalej do platformy etc ). Działanie skryptu pythonowego jest możliwe dzięki dodatkowym bilbiotekom RemoteMe (znajdują sie w folderze leafDevices/base/ ). Sama strona internetowa po websocketach łączy się do platformy RemoteMe (pozwalają na to skrypty javascriptowe zaimportowane w headerze pliku index.html ze ścieżek /libs/). Ułatwiają i ustanawiają komunikacje z platformą RemoteMe. Same komponenty wstawione w index.html typu : <variable component="**" W funkcjach pliku remoteMeComponents.js są zastępowane na “standardowe” i “bootstrapowe” komponenty htmlowe, dodatkowo do komponentów przypinane są eventy reagujące na akcje użytkownika i wysyłające odpowiednie komunikaty do skryptu pythonowego. Można podejrzeć jak remoteMeComponents.js zamienia i tworzy nowe komponenty – może to być interesujące gdy macie potrzebę stworzenia własnych komponentów, które RemoteMe nie pozwala dodać z kreatora. W większości przypadków akcje Waszych komponentów będą wykonywać zapis zmiennych w postaci RemoteMe.getInstance().getVariables() .setSmallInteger2("cameraPos",123,456,true); która wyśle do skryptu pythonowego informacje o zmianie zmiennej, podobnie sterujemy silnikami ustawiając odpowiednią zmienną. Podsumowanie Tworząc tej projekt chciałem pokazać Wam jak w łatwy sposób sterować Waszym samochodem z widokiem FPV. Projekt można rozbudowywać, lub zmieniać np, gdy korzystanie z innego mostka H niż ja. Zachęcam zatem do eksperymentowania ze źródłami projektu . Gdy jest to Wasz pierwszy projekt, zachęcam do zrobienia na początek projektu z mrugającą diodą i poczytanie dokumentacji na www.remoteme.org Pozdrawiam, Maciej
  12. Zainteresowałem się funkcjami alternatywnymi GPIO w Raspberry Pi, w 4 wersji jest tego dość sporo i można tu znaleźć 6 UARTów - gdzie najwyraźniej do użycia jest maksymalnie 5. Tu pierwsze pytanie, dlaczego na tych samych wyprowadzeniach jest UART 0 i 1, są to 14/15 dla lini TX/RX i 16/17 dla CTS /RTS. Jeżeli spojrzeć na GPIO 0/1 to tu rozumiem dlaczego są 2 kanały I2C - jeden z nich służy do rozpoznawania HATów, więc pewnie kanał 6 można wykorzystać do czegoś innego. Podobne pytanie do linii interfejsu kart SD, dlaczego są 2 kanały na tych samych GPIO? 21-27. Drugie pytanie dla bardziej obeznanych, do czego służą funkcje np na GPIO 16/17 FL0 i FL1, albo dla lini 26/27 TE0 i TE1? Pytanie to pojawiło się już kilka razy w na forum Raspberry ale nie pojawiała się żadna odpowiedź: AVE Output/Input raspi-gpio - FL0/FL1? Datasheet Raspberry Pi 4
  13. Idea działania Komora jonizacyjna, to urządzenie składające się z dwóch elektrod do których doprowadzane jest stałe napięcie, co powoduje powstanie pola elektrycznego w jej środku. Gdy kwant promieniowania "uderzy" w atom gazu znajdującego się w komorze, "rozbija" go na dwa jony (dodatni i ujemny), które są przyciągane do elektrod (dodatni do ujemnej i vice versa). Mierząc prąd płynący między dodatnią, a ujemną elektrodą, będzie on proporcjonalny do ilości tych jonów, zaś to będzie proporcjonalne do mierzonego promieniowania. Utrudnieniem jest, że wspomniane prądy są małe, więc wymagają dużego wzmocnienia, co zaś wymaga m.in. starannego filtrowania zasilania, oraz ekranowania, by urządzenie się nie wzbudzało. Poniżej znajduje się schemat blokowy prezentowanego rozwiązania. Część elektroniczna Pierwotnie do wytworzenia napięcia polaryzującego, miałem w planach użycie przetwornicy, jednak okazało się, że napięcie 12V z baterii jest wystarczające. Sygnał z komory trafia do wzmacniacza transimpedancyjnego, w pętli sprzężenia znajdują się szeregowo dwa rezystory o wartości aż 50G. Połączenie owych rezystorów, elektrody komory jonizacyjnej i nóżki wzmacniacza musi być wykonane w powietrzu, by uniknąć pasożytniczych rezystancji. Poniżej znajduje się render w KiCADie, oraz rzeczywiste urządzenie (wiem, fotka jest dość niskiej jakości). Część programistyczna Sygnał analogowy trafia do przetwornika ADC, i jest zbierany przez procek - tu użyłem dość mało popularnego STM8. Zaskoczeniem było dla mnie, że GCC nie obsługuje tych procesorów, zaś poświęcony im SDCC nie umie wycinać z binarki funkcji, które nie są używane! Do komunikacji z hardwarem użyłem stdperiph. Komunikacja z światem zewnętrznym jest jednokierunkowa (urządzenie wysyła pomiary co kilka sekund) za pomocą UARTa. Założeniem było, by urządzenie można było pozostawić same sobie i zdalnie je flashować, czy też pobierać z niego dane. W skrócie, wolę programować leżąc w łóżku, niż garbiąc się nad stołem pełnym kabli :) Zostało to zrealizowane przez dodanie Raspberry Pi, do której podpięty jest zarówno programator, jak i przelotka UART/USB. Soft na procka napisałem w C. Pobieranie danych po stronie maliny jest wykonywane przez skrypt w Pythonie, dane są wizualizowane skryptem w R. Użyłem R, mimo, że Python też ma biblioteki do tworzenia wykresów, bo bardzo podobają mi się wykresy w R. Dokumentacja powstała w LATEXie. Całość dostępna jest na GitHubie - zapraszam do odwiedzenia Wyniki Poniżej znajdują się dane pomiarowe zebrane za pomocą urządzenia.
  14. Cześć To mój pierwszy wpis na forum, rok temu zaczęłam studia na politechnice, naukę rozpoczęłam od mikrokontrolerow AVR. Dziś już wiem, że chce kontynuować naukę polegajac na raspberry niestety nie mam o nich kompletnie żadnej wiedzy. Mam plan wykonać projekt obrony pracy w oparciu o ten minikomputer dlatego chciałabym przez najbliższy rok poznać go dość dobrze ☺moim planem jest stworzenie programu zaawansowanego graficznie który będzie się otwierał automatycznie po uruchomieniu malinki. Zaawansowany graficznie czyli program wspierający obsługę wysokiej rozdzielczosci animacji. Stosowanie wlasnych obiektow takich jak progres bar, przyciski itp. ( nie chce korzystac z default'owych ze wzgledu na bardzo nieatrakcyjny wyglad ). Wiem tez ze konieczna bedzie wspolpraca malinki z UARTem. ponieważ wielu z Was ma wielkie doświadczenie proszę na początek o poradę w kilku kwestiach: 1. Czy lepiej kupić mailnke wersji 4 czy 3 ? Pomijając koszty, osobiście myślę że lepiej kupić bardziej przyszlosciowa płytkę wiec skłaniam się ku najnowszej wersji. Niestety większość informacji na forach dotyczy wersji 3 i obawiam się czy oby na pewno wszystkie informacje będą kompatybilne z najnowszym projektem. 2. Jaki system operacyjny zastosować do swojego projektu i jakie są ich plusy /minusy. Początkowo myślałam o windowsie chociaż Internet mówi tylko o wadach tego systemu. Szkoda bo dość dobrze radzę sobie w Visual studio i znam ten system dość dobrze. Mimo wszystko chętnie uczę się nowych rzeczy wiec jeśli waszym zdaniem Windows się nie nadaje to proszę mówić o tym wprost 3. Najważniejsze... w jakim programie / środowisku należy pisać programy na raspberry Tak aby idealnie nadawały się do mojego projektu. Jak wspomnialam wcześniej dobrze czuje się w Visual studio, mam też trochę wiedzy na temat języka C, C#. Może da się to jakoś wykorzystać? z góry dziękuję za waszą pomoc i jestem wdzięczna za zaangażowanie
  15. Czujnik poprawnie wykrywa odległości na dystansie 6 - 100 cm. Przy przeszkodzie znajdującej się 2-5 cm od czujnika, otrzymywana wartość utrzymuje się na 6cm. Czy ktoś spotkał się kiedyś z podobnym problemem ? Czujnik: https://botland.com.pl/pl/ultradzwiekowe-czujniki-odleglosci/1420-ultradzwiekowy-czujnik-odleglosci-hc-sr04-2-200cm-5903351241366.html Sposób podłączenia: https://tutorials-raspberrypi.com/raspberry-pi-ultrasonic-sensor-hc-sr04/ Kod programu: import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO_TRIGGER = 2 GPIO_ECHO = 3 GPIO.setup(GPIO_TRIGGER, GPIO.OUT) GPIO.setup(GPIO_ECHO, GPIO.IN) def distance(): GPIO.output(GPIO_TRIGGER, False) time.sleep(0.1) GPIO.output(GPIO_TRIGGER, True) time.sleep(0.00001) GPIO.output(GPIO_TRIGGER, False) while GPIO.input(GPIO_ECHO) == 0: pulse_start = time.time() while GPIO.input(GPIO_ECHO) == 1: pulse_end = time.time() pulse_duration = pulse_end - pulse_start distance = round(pulse_duration * 17150, 2) return distance if __name__ == '__main__': try: while True: dist = distance() print(dist) except KeyboardInterrupt: print("Measurement stopped by User") GPIO.cleanup()
  16. Stacja meteorologiczna służy do przeprowadza dokładnych pomiarów pogody oraz sprawdzania jakości powietrza. Urządzenie pobiera dane z czujników, następnie zapisuje je do bazy danych po czym zostają wyświetlone na stronie internetowej. Całe urządzenie zostało zamknięte w obudowie wydrukowanej w drukarce 3D. Czujniki zainstalowane w urządzeniu pobierają dokładne dane pogodowe. Stacja posiada zaawansowaną metodę pomiaru prędkości wiatru przy użyciu ultradźwiękowych czujników ruchu. Stacja działa na Raspberry PI 3+, obsługuje również starsze modele (z wbudowanym wifi) oraz na Raspberry PI ZERO (W). System operacyjny to Linux wersja Raspbian STRETCH LITE bez interfejsu graficznego. Kod źródłowy czujników został napisany w Python’ie. Dane z czujników zapisywane są przy użyciu Raspberry PI do bazy danych MySQL. Następnie zostają wyświetlone w aplikacji internetowej, która napisana została w PHP. Urządzenie wymaga połączenia z Internetem. Aktualnie wykorzystywane jest połączenie poprzez WIFI. Komunikacja pomiędzy urządzeniem a administratorem przeprowadzana jest poprzez protokół SSH i FTP. Stacja jest zbudowana w taki sposób, żeby użytkownik mógł w łatwy sposób ją obsługiwać. Aby włączyć stację należy podłączyć ją do prądu. Działanie urządzenia zostanie zasygnalizowane świeceniem diody (czerwonej) oraz miganiem diody zielonej, która świeci przy wysyłaniu danych do bazy. Oprócz graficznego przedstawienia danych aplikacja posiada skrypty do obliczenia m. in. wschodu i zachodu słońca w danej lokalizacji. Oprogramowania posiada opcje, w których m. in. możemy ustawić czas pomiaru pogody i zapisu do bazy danych. Jest to ważne ponieważ możemy sami ustalać jak często stacja ma sprawdzać stan pogody Projekt obudowy Obudowa została zaprojektowana w programie FreeCAD. Składa się ona z 9 elementów. Została wydrukowana w drukarce 3D – Anet A8 (moja własna drukarka). Materiał wykorzystany podczas druku to PLA, temperatura druku 205°C. Łączny czas druku wynosi 19 godzin, zużywa 174 gram materiału przy wysokości warstwy 0.2mm. Projekt obudowy został wykonany w taki sposób, aby urządzenie było odporne na deszcz i wiatr. Opływowość stacji pozwala na wykonywania dokładnych pomiarów prędkości wiatru. Na samej górze stacji zamontowany został czujnik opadów deszczu oraz czujnik natężenia światła. Następnie pod nimi umieszczone są ultradźwiękowe czujniki prędkości wiatru. Kolejny element to obudowa chroniąca RB PI i elektronikę. Obudowa posiada specjalne mocowanie na RP PI, które sztywno trzyma urządzenie. Następnym elementem jest rdzeń, do którego przymocowane są pozostałe czujniki. Obudowę zamyka podstawka, w której znajduję się główny przewód zasilający oraz diody sygnalizujące działanie. Czujniki Urządzenie w czasie rzeczywistym pobiera dane z 7 czujników, następnie są one w odpowiedni sposób przekazywane do modułu detektorów i mikrokontrolerów, które zwracają dane do Raspberry PI. Lista czujników: Czujnik opadów Czujnik pomiaru opadów atmosferycznych składa się z dwóch części: sondy pomiarowej „YL-83” oraz modułu detektora „LM393”, który posiada wyjście analogowe umożliwiające pomiar deszczu. Moduł zasilany jest napięciem 5V. Czujnik natężenia światła Czujnik światła bazuje na fotorezystorze „GL5537-1”. Jest to opornik fotoelektryczny, który zmienia swoją rezystancję pod wpływem padającego światła. Prędkość wiatru Pomiar prędkości wiatru bazuje na ultradźwiękowym czujniku odległości „HC-SR04”. Ultradźwiękowy pomiar prędkości polega na zmierzeniu różnicy czasu przejścia impulsów ultradźwiękowych propagujących w kierunku przeciwnym do kierunku przepływu. Temperatura i wilgotność Do wykonywania pomiaru temperatury i wilgotności powietrza został wykorzystany popularny moduł „DHT11”. Moduł składa się z czujnika oraz niezbędnego do poprawnego działania układu: rezystora i kondensatora filtrującego napięcie zasilania. Ciśnienie Moduł z cyfrowym barometrem „BMP180” wykonuje pomiar ciśnienia w zakresie od 200hPa do 1100hPa. Układ komunikuje się przy użyciu interfejsu IC2, co zapewnia wysoką dokładność i stabilność wykonywanych pomiarów. Jakoś powietrza Moduł jakości powietrza „MQ-135” wykrywa w atmosferze: benzen, amoniak (NH3) oraz dwutlenek węgla (CO2). Inne: Przetwornik A/C i C/A 8-bitowy I2C Głównym układem przetwarzania danych w tej pracy jest przetwornik PCF8591. Moduł posiada czterokanałowy przetwornik analogowo-cyfrowy działający w oparciu o 8-bitowy systemem akwizycji danych. Komunikacja opiera się na szeregowej wysyłce danych za pomocą dwukierunkowej magistrali I2C.
  17. Zaczynam z Raspberry Pi zakupiłem wersję 4b 4gb ramu chciałbym się dowiedzieć: (pytanie może i głupie ale może uchronić przed ewentualnym uszkodzeniem) -Jak unikać uszkodzeń (różnych typów) -Jak zadbać o malinkę -Czego nie powinniśmy robić Mile widziane historie kiedy zepsuło wam się Raspberry Pi chodzi o warunki coś podpięliście źle czy coś
  18. Cześć, kupiłem w Botland: 1) Raspberry Pi 3B+ oraz: 2) oryginalną kamerkę Raspberry Pi Camera HD v2 8MPx mając nadzieje, że bezproblemowo uda mi się uruchomić kamerkę na malince, okazało się, że nic bardziej mylnego. Zainstalowałem najnowszego Raspbina, włączyłem kamerkę, a nagrywanie nie działa?! Zarówno Komenda: $ raspivid -o - jak i komenda: $ raspistill -o - zwracają te same komunikaty o błędach: mmal: mmal_vc_component_enable: failed to enable component: ENOSPC mmal: camera component couldn't be enabled mmal: main: Failed to create camera component mmal: Failed to run camera app. Please check for firmware updates Przeczytałem tuzin artykułów próbujących rozwiązać ten problem, ale żaden nie okazał się pomocny. Na sam początek polecano sprawdzić czy system wykrywa kamerkę: $ vcgencmd get_camera supported=1 detected=1 więc wykrywa. Potem polecono zwiększyć pamięć GPU z 128 MB (domyślna) do 256 MB co zrobiłem, poniżej sprawdzenie: $ vcgencmd get_mem gpu gpu=256M ale kamerka wciąż nie działa. W końcu zaktualizowałem system (czyli paczki): $ uname -a Linux raspberrypi 4.19.80-v7+ #1274 SMP Mon Oct 21 16:23:10 BST 2019 armv7l GNU/Linux a potem firmware za pomocą komendy: # sudo rpi-update co również nie przyniosło żadnej poprawy. Dlatego podejrzewam, że: 1) kamerka jest zepsuta, ale to jest nówka kupiona w Botland? 2) taśma łącząca kamerę z RPi jest zepsuta, ale to też nówka z Botland 3) jakiś nieznany proces cały czas korzysta z kamery W niektórych artykułach pisano, że z kamery może korzystać w danej chwili tylko jeden proces. Zazwyczaj ludzie orientowali się, że mają włączonego jakiegoś demona co korzysta z kamery i po wyłączeniu tego demona, od razu mogli korzystać z kamerki (raspivid & raspistill). Wyświetliłem drzewko procesów pracujących w Raspbianie, ale nie byłem w stanie dostrzec ani jednego procesu, który z nawy wskazywałby, że może korzystać z kamerki. Przypomnę, że to jest świeża instalacja Raspbiana, więc nie instalowałem tam żadnych demonów do kamery. Poniżej wrzucam listing procesów: $ pstre -p systemd(1)-+-alsactl(333) |-avahi-daemon(354)---avahi-daemon(388) |-bluealsa(721)-+-{bluealsa}(726) | `-{bluealsa}(727) |-bluetoothd(711) |-cron(336) |-dbus-daemon(372) |-dhcpcd(400) |-hciattach(706) |-lightdm(453)-+-Xorg(480)-+-{Xorg}(494) | | |-{Xorg}(495) | | |-{Xorg}(496) | | |-{Xorg}(497) | | `-{Xorg}(500) | |-lightdm(506)-+-lxsession(528)-+-lxpanel(594)-+-lxterminal(848)-+-bash(858)---sudo(863)---su(868)---bash+ | | | | | |-bash(883) | | | | | |-{lxterminal}(849) | | | | | |-{lxterminal}(850) | | | | | |-{lxterminal}(851) | | | | | |-{lxterminal}(852) | | | | | |-{lxterminal}(856) | | | | | `-{lxterminal}(857) | | | | |-{lxpanel}(625) | | | | |-{lxpanel}(626) | | | | `-{lxpanel}(801) | | | |-lxpolkit(591)-+-{lxpolkit}(606) | | | | `-{lxpolkit}(607) | | | |-openbox(586) | | | |-pcmanfm(596)-+-{pcmanfm}(622) | | | | `-{pcmanfm}(623) | | | |-ssh-agent(561) | | | |-{lxsession}(569) | | | `-{lxsession}(570) | | |-{lightdm}(509) | | `-{lightdm}(510) | |-{lightdm}(466) | `-{lightdm}(469) |-login(481)---bash(646) |-menu-cached(715)-+-{menu-cached}(717) | `-{menu-cached}(718) |-mount.ntfs(829) |-mount.ntfs(843) |-polkitd(442)-+-{polkitd}(445) | `-{polkitd}(448) |-rngd(346)-+-{rngd}(348) | |-{rngd}(349) | `-{rngd}(350) |-rsyslogd(362)-+-{rsyslogd}(404) | |-{rsyslogd}(405) | `-{rsyslogd}(406) |-ssh-agent(603) |-systemd(514)-+-(sd-pam)(517) | |-dbus-daemon(537) | |-gvfs-afc-volume(735)-+-{gvfs-afc-volume}(736) | | |-{gvfs-afc-volume}(737) | | `-{gvfs-afc-volume}(739) | |-gvfs-goa-volume(750)-+-{gvfs-goa-volume}(751) | | `-{gvfs-goa-volume}(752) | |-gvfs-gphoto2-vo(740)-+-{gvfs-gphoto2-vo}(741) | | `-{gvfs-gphoto2-vo}(743) | |-gvfs-mtp-volume(744)-+-{gvfs-mtp-volume}(747) | | `-{gvfs-mtp-volume}(749) | |-gvfs-udisks2-vo(731)-+-{gvfs-udisks2-vo}(732) | | `-{gvfs-udisks2-vo}(733) | |-gvfsd(571)-+-gvfsd-trash(799)-+-{gvfsd-trash}(803) | | | `-{gvfsd-trash}(804) | | |-{gvfsd}(572) | | `-{gvfsd}(573) | |-gvfsd-fuse(576)-+-{gvfsd-fuse}(587) | | |-{gvfsd-fuse}(588) | | |-{gvfsd-fuse}(589) | | |-{gvfsd-fuse}(592) | | `-{gvfsd-fuse}(598) | `-gvfsd-metadata(835)-+-{gvfsd-metadata}(837) | `-{gvfsd-metadata}(838) |-systemd-journal(125) |-systemd-logind(326) |-systemd-timesyn(288)---{systemd-timesyn}(325) |-systemd-udevd(146) |-thd(371) |-udisksd(343)-+-{udisksd}(407) | |-{udisksd}(435) | |-{udisksd}(482) | `-{udisksd}(492) |-wpa_supplicant(377) `-wpa_supplicant(455) Na sam koniec rzuciłem jeszcze okiem w logi kernela szukając informacji dotyczących kamery (szukałem ciągu znaków vid), znalazłem tylko takie wpisy świadczące raczej o tym, że kamera została wykryta: dmesg | grep -i vid [ 5.213247] videodev: Linux video capture interface: v2.00 ... [ 5.213247] bcm2835-codec bcm2835-codec: Device registered as /dev/video10 [ 5.882880] bcm2835-codec bcm2835-codec: Loaded V4L2 decode [ 5.888860] bcm2835-codec bcm2835-codec: Device registered as /dev/video11 [ 5.889013] bcm2835-codec bcm2835-codec: Loaded V4L2 encode [ 5.898020] bcm2835-codec bcm2835-codec: Device registered as /dev/video12 [ 5.898082] bcm2835-codec bcm2835-codec: Loaded V4L2 isp [ 5.899817] bcm2835-v4l2: scene mode selected 0, was 0 [ 5.900240] bcm2835-v4l2: V4L2 device registered as video0 - stills mode > 1280x720 [ 5.905487] bcm2835-v4l2: Broadcom 2835 MMAL video capture ver 0.0.2 loaded. Proszę bardziej doświadczonych kolegów o pomoc w uruchomieniu kamerki, bo jedyne co mi teraz przychodzi do głowy to zgłosić reklamacje kamerki do Botland. Pozdrawiam, Wojciech
  19. Tak to jest, jak się najpierw ustala nazwę, a potem dopiero traktuje jako akronim i szuka jakiegoś sensownego określenia Ale jeśli ktoś czytał "Cieplarnię" Aldissa powinien już w tym momencie domyślać się, do czego służy SMARDZ (a jeśli nie to warto przeczytać). Kilka słów wyjaśnienia: bardzo lubię Arduino Pro Mini (choćby ze względu na cenę klonów i brak jakichkolwiek niepotrzebnych wodotrysków - ot, po prostu atmega z kwarcem i pinami na zgrabnej płytce). Niestety - o ile programowanie różnych mniej lub bardziej stacjonarnych urządzeń typu automatyka domowa jest całkiem wygodne (o ile się zadba o odpowiedni konwerter) - o tyle przy robotach, które jeżdżą, szwendają się po podłodze i ogólnie starają się usilnie zerwać wszystkie możliwe kable, sprawa staje się bardziej skomplikowana. Próbowałem jakichś wariackich rozwiązań na ESP8266 (coś w stylu "Serial over IP"), ale rezultaty były raczej mało interesujące. Postanowiłem więc przestać bawić się w oszczędzanie i użyć Raspberry Pi Zero W. Rozwiązanie (oprócz tego że działa bezproblemowo) ma jeszcze jedną zaletę: wszystkie pliki trzymane są na karcie pamięci malinki, układ katalogów zgodny jest z oryginalnym układem Arduino, a do komunikacji z malinką możemy użyć dowolnego komputera z zainstalowanym jakimś klientem SSH (np. PuTTY). I tu uwaga: mimo że opisuję dość dokładnie jak takie coś można sobie zrobić - zakładam u potencjalnego użytkownika podstawową wiedzę na temat Linuksa, Arduino i ogólnie elektroniki. Tak że proszę - bez pytań typu "a jak się przegrywa pliki na RPi" i "po co tam Arduino IDE jeśli go nie używam" Jak zwykle postanowiłem użyć elementów "wyciągniętych z szuflady". Co prawda jest mało prawdopodobne, aby wiele osób miało w szufladzie jakieś niepotrzebne malinki, ale ponieważ wymagania SMARDZa są bardzo małe, można po prostu na chwilę wyjąć ją z innego urządzenia. Nawet zakup RPi specjalnie do tego celu nie będzie niepotrzebnym wydatkiem - albo posłuży do programowania, albo znajdzie zastosowanie w innym urządzeniu (np. kamerze, serwerze octoprinta co tam sobie wymyślimy). Co do wymagań - potrzeba niewiele. Wystarczy stały adres IP w domowej sieci WiFi, dostępny interfejs Serial na ttyS0 i wolny pin BCM17. Co do malinki - można kupić wersję z wlutowanymi pinami, ale to chyba szczyt lenistwa, SMARDZ jest przeznaczony dla osób, które potrafią się lutownicą posługiwać i wlutowanie czterdziestopinowego gniazda nie powinno stanowić problemu. Zaoszczędzić też możemy na karcie SD, wcale nie musimy kupować najdroższej, wystarczy taka za kilkanaście złotych. Potrzebny będzie jeszcze konwerter napięć i jakieś drobne elementy montażowe. Tak więc mamy już malinkę (z pinami). Zakładam, że większość z tych, którzy chcieliby sobie coś takiego zrobić ma jakiś zasilacz (wystarczy mocniejsza ładowarka od komórki) - ja trafiłem w Tesco ostatnio ładowarkę 2.5A za niecałą dychę przy okazji kupowania jakichś bułeczek Instalacja jest prosta, chociaż trochę potrwa. Należy zacząć od skonfigurowania systemu tak, aby otrzymywał stały adres IP w sieci wewnętrznej. Ponieważ sposobów na to jest wiele i wybór ściśle zależy od warunków technicznych - odsyłam do oficjalnych instrukcji konfiguracji RPi. Potrzeba również, aby malinka miała dostęp do Internetu. Również pamiętajmy, że będzie nam potrzebny UART, czyli konfigurujemy malinkę tak, aby UART był aktywny, ale konsola serial wyłączona. W tym celu łączymy się z malinką przez SSH, wydajemy polecenie: sudo raspi-config i kolejno: Wybieramy punkt "Interfacing options" Z nastpnego menu wybieramy "Serial" Na pytanie "Would you like a login shell to be accessible over serial?" odpowiadamy "Nie" Na pytanie "Would you like the serial port hardware to be enabled?" odpowiadamy "Tak" Jako że najprawdopodobniej konfigurować to będziemy w trybie headless (nie bardzo sobie wyobrażam po co komu graficzne środowisko na komputerze bez podłączonego monitora - ale może ktoś ma takie upodobania) - na komputerze z którego przeprowadzamy instalację potrzebny będzie jeszcze vncviewer. I tu znów odsyłam do materiałów dotyczących używanego systemu operacyjnego - w przypadku Ubuntu czy Debiana najprostszy będzie xtightvncviewer. Oczywiście, jeśli mamy graficzne środowisko i podłączony monitor możemy z tego skorzystać! Zaczynamy od instalacji najpotrzebniejszych programów. Jeśli używamy otoczenia graficznego, wystarczy WiringPi i pyserial: sudo apt install wiringpi python-serial Jeśli instalujemy w trybie headless, potrzebne będą dodatkowe programy: sudo apt install wiringpi python-serial x11vnc xserver-xorg-video-dummy Teraz musimy zainstalować Arduino IDE. Tu znów w przypadku graficznego środowiska postępujemy zgodnie z oficjalnymi instrukcjami - Arduino IDE należy co najmniej raz uruchomić! Zajmijmy się więc wersją headless. Należy do katalogu domowego wgrać najnowszą wersję Arduiono IDE dla Linuxa ARM 32-bity (w chwili pisania jest to wersja 1.8.9) i rozpakować poleceniem: tar -xJf arduino-1.8.9-linuxarm.tar.xz Utworzony zostanie katalog arduino-1.8.9 zawierający wszystko, co potrzebne do pracy. Teraz należałoby uruchomić Arduino IDE - niestety, bez grafiki się nie da... trzeba więc nieco oszukać Javę żeby myślała, że wszystko jest w porządku. Najprostszym sposobem jest uruchomienie IDE w symulowanym środowisku graficznym. W tym celu wydajemy polecenie: xvfb-run arduinio-1.8.9/arduino i po odczekaniu dłuższej chwili (IDE musi wystartować, a tego nie widać) zatrzymanie programu przez ctrl-c. Powinny zostać utworzone katalogi ~/Arduino zawierający katalog libraries oraz ~/.arduino15 z (między innymi) plikiem preferences.txt. Jednak lepiej jest widzieć co się dzieje, poza tym nie wszyscy lubią zabawy z zipami i ściąganie bibliotek z githuba, w większości przypadków użycie okienkowego interfejsu jest po prostu wygodniejsze. A więc aby ujrzeć (teraz i następnym razem) interfejs Arduino IDE należy postąpić nieco inaczej. Wydajemy kolejno polecenia: Xvfb -display :20 & x11vnc -display :20 & DISPLAY=:20 arduino-1.8.9/arduino a na komputerze na którym pracujemy uruchamiamy przeglądarkę VNC i łączymy się z naszą malinką. Należy pamiętać, że x11vnc uruchomiony w ten sposób pozwala tylko na jedną sesję! Teraz po prostu po pokazaniu się właściwego interfejsu IDE możemy go zamknąć, a na konsoli malinki wydać polecenie: killall Xvfb Spowoduje to wyłączenie graficznego środowiska oraz serwera VNC. Tak więc nasza malinka jest już gotowa, możemy przystąpić do instalacji plików SMARDZa. Tu już jest to wręcz trywialne. Z załącznika do posta (smardz.zip) trzeba wyciągnąć plik smardz.tgz, przegrać go na naszą malinkę do katalogu domowego i rozpakować poleceniem: tar -xzf smardz.tgz Powinien zostać utworzony katalog bin, a w nim pliki wykonywalne: ardureset arducomp.py ardupload.py arduserial.py Możemy teraz sprawdzić, czy wersja Arduino IDE w pliku ardupload.py zgadza się z wersją zainstalowaną, ew. poprawić linijkę: aversion='1.8.9' zgodnie z zainstalowaną wersją Arduino IDE. Należy pamiętać, że w przypadku wgrania nowej wersji IDE trzeba będzie tę linijkę poprawić ponownie! Jeśli nie stosujemy malinki do innych celów lub żaden zainstalowany program nie używa pinu BCM17 możemy do /etc/rc.local dopisać: /usr/bin/gpio -g mode 17 output /usr/bin/gpio -g write 17 1 Jeśli tego nie zrobimy, może okazać się konieczne wydanie polecenia ardureset zaraz po uruchomieniu systemu. Mamy więc wszystko zainstalowane... ale jakoś to trzeba z naszym Arduino połączyć! Tu już wszystko zależy od inwencji użytkownika. Schemat połączeń będzie oczywiście podobny w każdym przypadku, zworka w obwodzie zasilania jest opcjonalna i służy do rozdzielenia zasilanie, jeśli chcemy oddzielnie zasilać Arduino i SMARDZa. Połączenia między Arduino a RPi powinny przechodzić poprzez konwerter napięć (wykorzystane trzy z czterech par), a więc sprowadzą się do: DTR/1 - GPIO17/11 TxD/2 - RxD/10 RxD/3 - TxD/8 Ja w swoim rozwiązaniu użyłem kawałka dwustronnej płytki uniwersalnej, gniazda zostały wycięte z jednej 40-pinowej pojedynczej listwy żeńskiej, ale to już zależy od własnych potrzeb i możliwości, każdy ma inne. Pozostaje jeszcze kwestia obudowy. Początkowo użyłem wersji z Thingiverse (nota bene bardzo wygodnej), postanowiłem jednak nieco ją zmodyfikować. Pliki STL oraz SCAD w załączniku! No i pora na testy. Potrzebne jest Arduino Pro Mini z wlutowanymi kątowymi pinami do programowania (ja stosuję zawsze pięć). Podłączamy Arduino do SMARDZa, podłączamy zasilanie do RPi, powinna zaświecić się dioda zasilania w Arduino. Teraz łączymy się przez SSH z naszą malinką. Potrzebny jest jakiś dowolny szkic (np. blink) umieszczony w katalogu Arduino (możemy go przegrać choćby z ~/arduino-1.8.9/examples/01.Basics/Blink). Wchodzimy do katalogu Arduino/Blink: cd ~/Arduino/Blink i wydajemy polecenie arducomp.py Program powinien się skompilować, zostać przesłany na Arduino i po chwili powinniśmy zobaczyć migającą diodę. Kolej na użycie monitora serial. W tym celu otwieramy drugie połączenie z malinką i wpisujemy polecenie arduserial.py Powinniśmy zobaczyć ekran monitora. Obsługa jest intuicyjna, wspomnę tylko że wpisanie czegokolwiek jest możliwe tylko przy aktywnym monitorze (przełączanym klawiszem F2), a prędkości przełącza się klawiszami kursora po wciśnięciu F3 przy nieaktywnym monitorze. Na pierwszej konsoli musimy skompilować jakiś program używający seriala. Jeśli nie macie nic takiego pod ręką, przygotowałem taki bardzo krótki test pozwalający sprawdzić zarówno nadawanie, jak i odbiór: void setup(void) { Serial.begin(9600); Serial.println("Program wystartował"); } void loop() { if (Serial.available()) { Serial.println((int)Serial.read()); } } Jeśli wszystko będzie w porządku - możemy już zająć się prawdziwą pracą z naszym robotem. Należy tylko zadbać o to, aby piny interfejsu Arduino zwrócone były w stronę umożliwiającą podłączenie SMARDZa bez konieczności użycia dodatkowych kabli: ...a następnie przystąpić do programowania i monitorowania naszego robota (robot na zdjęciu jest wersją próbną w trakcie powstawania, zrzut ekranu monitora pochodzi z tego właśnie robota). Wszystkie pliki potrzebne do odtworzenia SMARDZa w załączniku: smardz.zip Jak zwykle w przypadku pytań pozostaję do dyspozycji.
  20. Witam Od około półtora roku interesuję się sztuczną inteligencją, zwłaszcza zastosowaną w robotyce. Jest to dla mnie niezwykle ciekawy temat Kilka miesięcy temu zacząłem pracować nad moim prywatnym projektem, który cały czas jest w fazie rozwoju. Pewne elementy, takie jak uczenie się poprzez rozmowę z człowiekiem są gotowe, więc postanowiłem nagrać poniższe filmy: AgeBot podłączony jest do internetu. Platforma to gotowa konstrukcja - AlphaBot-PI. Użyłem jej, aby szybciej skupić się na oprogramowaniu. W ostatnim czasie domykałem widoczne na filmach możliwości robota i w międzyczasie zacząłem pracę nad wykorzystaniem kamery (aktualny stan to ~30%). W bliskiej przyszłości platformę mam zamiar wymienić na coś bardziej zaawansowanego lub zbudować swoją, ponieważ ta zaczyna mnie powoli ograniczać (pod względem hardware'u). Jej specyfikacja dostępna jest w internecie (np. na stronie firmy Waveshare), więc nie będę kopiował Jak już zauważyliście - używam Raspberry PI. Oprogramowanie na malinkę napisałem w C++, pozostała część to C++ oraz Python. Systemem jest Raspbian. Do zautomatyzowania instalacji niektórych zależności w systemie (akurat w przypadku samej malinki) używam narzędzia Ansible, a o te krytyczne dla działania aplikacji dba manager pakietów (apt, buduję paczki .deb). Do przetwarzania tekstu użyłem biblioteki Tensorflow, natomiast w procesie uczenia się, robotowi asystuje wnioskowanie. Kamera i przetwarzanie obrazu otworzy wiele nowych drzwi, ułatwi również pracę przy kolejnej domenie - planowaniu zadań. Sam robot jest stosunkowo małą częścią projektu, ale o tym... w przyszłości Każdy feedback mile widziany Pozdrawiam PS: W ciągu kilku dni napiszę posta z trochę bardziej szczegółowymi informacjami odnośnie przetwarzania tekstu - czatowania z robotem
  21. Już słyszę głosy: O, staremu ethanakowi coś się chyba pokręciło... Post jest o jakimś Kedrigernie w dziale DIY - a na zdjęciu mamy coś przypominającego robota z dumnym napisem "Ciapek"... Spieszę z wyjaśnieniami. To nie pomyłka. Post jest na temat serwera mowy Kedrigern, a Ciapek to żaden robot. Po prostu dość trudno zrobić zdjęcie programu, poza tym wypadałoby raczej pokazać ów program w działaniu - a ten wymaga jednak czegoś co będzie gadać (czyli jakiejś bardziej fikuśnej obudowy na głośnik). A ponieważ ostatnio zapatrzyłem się w rysunki Daniela Mroza... cóż, Ciapek z ludzkimi dłońmi, stopami i uszkami wyszedł tak jak wyszedł Zacznę możę od opisu elektroniki (jako że jest to najprostsze, a użytkownik może sobie ją skomponować z zupełnie innych elementów). Sercem całego układu jest Raspberry Pi. Można zastosować dowolny model (chociaż ze starymi, krótkimi GPIO mogą być lekkie problemy), ja użyłem w swoim egzemplarzu Raspberry Pi Zero W. Oprócz tego potzebny jest jakikolwiek układ odtwarzania dźwięku. "Duże" (pełnpowymiarowe) malinki jak popularny 3B+ mają już wyprowadzone wyjście audio, potrzebny jest tylko jakiś niewielki wzmacniacz. Dla wersji Zero potrzebny jest jednak układ zewnętrzny. Prawdopodobnie doskonale spisałby się opisywany ostatnio moduł z wyjściem audio do Raspberry Pi Zero, ja zastosowałem jednak moduł i2s. Jest on dość wygodny w użyciu jako że zawiera w sobie wzmacniacz mono o całkiem sporej (do 3 W) mocy, poza tym początkujący elektronicy nie muszą się martwić o jakieś dziwne masy audio, filtrowane zasilania i tym podobne dziwactwa interesujące tylko "analogowców" - moduł podłącza się pięcioma przewodami do malinki, z drugiej strony dwoma do głośnika i już gra Ponieważ nasz "robocik" musi potrafić poruszać ustami, zastosowałem najprostsze (i najprawdopodobniej najtańsze) rozwiązanie - czyli matrycę LED 8x8 ze sterownikiem, na której rysowane będą kształty ust. Od razu uprzedzę pytanie: owszem, próbowałem zrobić bardziej skomplikowany mechanizm używający serw. Niestety - oprócz trudności mechanicznych (te są do przezwyciężenia) natrafiłem na rzecz, której nie da się przeskoczyć: prędkość serwa. Typowe serwo potrzebuje 0.1 sekundy na przekręcenie orczyka o 60° - a nawet zakładając, że owe 60° wystarczy (w co osobiście wątpię), jest to co najmniej dwa razy za wolno (przy czym owe "dwa" mogłoby się w rzeczywistych układach rozrosnąć do trzech czy czterech). Będę jeszcze próbować rozwiązania z solenoidami - jeśli mi się uda to opublikuję wyniki. Ale może w międzyczasie ktoś inny napisze moduł "solenoid"? Zresztą - chciałem, aby każdy mógł sobie w domu wypróbować Kedrigerna ponosząc jak najmniejsze koszty, a opisywany układ można (mając RPi z wyjściem audio) zmontować kosztem klikunastu złotych (matryca) bez żadnych płytek - po prostu łącząc matrycę przewodami z GPIO malinki. Jako głośnika użyłem leżącego gdzieś w szufladzie zakurzonego głośniczka od starego telefonu z sekretarką, pasować jednak będzie dowolny pod warunkiem dopasowania mocy głośnika do posiadanego wzmacniacza. I to cała wielce skomplikowana elektronika. Jak widać na zdjęciu - nie ma tam nic skomplikowanego. Przejdę więc do opisu programu. Kilka lat temu udało mi się zmusić Mbrolę do w miarę prawidłowego gadania po polsku (do tego stopnia, że można ją było wykorzystać np. do tworzenia audiobooków). System TTS Milena (tak się nazywa ten "zmuszacz" do Mbroli - czyli bardziej fachowo NLP) bardzo dobrze sprawdził się na pecetowym Linuksie, wersja na Windows była raczej ciekawostką ale również działała - postanowiłem więc przystosować ją do malinki. Po przezwyciężeniu pewnych trudności z kompilacją (np. "char" dla architerktury Intel to w GCC domyślnie signed, w ARM z jakichś przyczyn unsigned) okazało się, że co prawda Milena działa, ale "rozruch" ma straszliwie powolny. Nic dziwnego - pliki tekstowe słowników wymowy i translacji fonetycznej muszą być kompilowane przy załadowaniu programu, a malinka ze swoją wolniutką kartą pamięci i nieszczególnie silnym procesorkiem potrzebuje zbyt dużo czasu, zanim wydobędzie z siebie jakieś zdanie. Postanowiłem więc zrobić inaczej: serwer wczytuje wszystkie pliki raz przy starcie systemu, a prosty program klienta przekazuje mu tylko treść komunikatów. Takie rozwiązanie ma również inne zalety: uruchomiony na sockecie TCP serwer może być na zupełnie innej fizycznej maszynie niż klient. I w ten sposób powstał program Kedrigern (nazwany na cześć pewnego czarodzieja, który postanowił odczarować księżniczkę z zaklęcia odbierającego głos). Jak mi to wyszło - oceńcie sami. Oto filmik ukazujący Kedrigerna w działaniu: Nie będę tu rozpisywał się o wszystkich zasadach działania i możliwościach Kedrigerna i Mileny (to w końcu ma byc post na forum a nie książka z dokumentacją), zacznę więc od instalacji Kedrigerna na malince. Wszystkie konieczne komponenty (z wyjątkiem głosu pl1) są w załączonym pliku tgz. Rozpakujmy go w dowolnym katalogu (np. w głównym katalogu użytkownika malinki) i instalujemy mbrolę wraz z polskim głosem: sudo dpkg -i mbrola3.0.1h_armhf.deb sudo apt install mbrola-pl1 Teraz możemy zainstalować Milenę. I tu uwaga: jeśli ktoś miał starszą wersję Mileny niż 0.2.92 musi ją przeinstalować na tę właśnie wersję - inaczej nie będzie działać moduł ruchu ust Kedrigerna! sudo dpkg -i milena*.deb Po zainstalowaniu wszystkiego powinno działać już polecenie milena_say, czyli musimy wypróbować: milena_say dzień dobry kolego I znów uwaga: jeśli wyjściem audio jest HDMI, polecenie może nie działać prawidłowo! Należy spróbować dodać parametr -d opóżniający generację mowy do czasu "załapania" HDMI, czyli najprościej: milena_say -d 2000 dzień dobry kolego Niestety, przy użyciu wyjścia HDMI mogą pojawić się problemy z późniejszym działaniem Kedrigerna, ale po pierwsze nie jest to miejsce na omawianie problemów z audio, po drugie wcale nie czuję się mistrzem w tym zakresie i prawdopodobnie ktoś tu wie lepiej ode mnie jak tym problemom zaradzić. W każdym razie mając uruchomiona Milenę i Mbrolę możemy przystąpić do instalacji Kedrigerna. Zaczynamy od instalacji serwera, czyli sudo dpkg -i kedrigern_0.2.0-1_armhf.deb Jeśli mamy podłąćzoną matrycę LED (8x8, MAX7219) możemy użyć jej jako wyświetlacz ust: sudo dpkg -i kedrigern-matrix_0.2.0-1_armhf.deb No i oczywiście coś co pozwoli nam korzystać z serwera, czyli: sudo dpkg -i libkedrigern_0.1.2-1_armhf.deb Teraz możemy sprawdzić, co potrafi nasz serwer: kedrigern -h lub (jeśli mamy zainstalowany moduł matrix) kedrigern -M matrix -h W odpowiedzi dostaniemy wykaz opcji, z którymi możemy uruchomić serwer. Aby je przetestować, należy otworzyć drugi terminal; w pierwszym uruchamiamy serwer poleceniem "kedrigern" z różnymi opcjami, w drugim testujemy poleceniem kdr-say. Po ustaleniu opcji należy zedytować plik /etc/default/kedrigern i w nim ustawić domyślne parametry. Po przetestowaniu poleceniem kedrigern -C /etc/default/kedrigern możemy już uruchomić nasz serwer w tle: sudo systemctl start kedrigern Jeśli chcemy, aby serwer startował od razu przy starcie systemu, należy wydać polecenie: sudo systemctl enable kedrigern Do komunikacji z serwerem służą polecenia kdr-say, kdr-stop i kdr-speaking. Moduł matrix pozwala na wyświetlanie ust zsynchronizowane z głosem syntezatora. Oto przykładowe obrazy ust dla różnych fonemów: Fonem A Fonem I Fonem O Fonem U Fonemy M, P i B Wybrałem do pokazania kilka najbardziej charakterystycznych kształtów. Jeśli komuś nie odpowiadają stworzone przeze mnie kształty może w prosty sposób dorobić własne lub poprawić moje na bazie pliku /usr/share/kedrigern/demo.shape i podłączyć go do Kedrigerna, np. za pomocą opcji "-m matrix:shape" lub wprowadzając odpowiednie zmiany w pliku konfiguracyjnym. Protokół komunikacyjny jest bardzo prosty. Nie wnikając w szczegóły - załączony moduł w Pythonie (działa w wersji 2 i 3 Pythona) pozwala na sterowanie serwerem, a jednocześnie stanowi przykład sposobu komunikacji. I to wszystko... A nie, nie wszystko. Bo zaraz ktoś powie że to tylko zabawka, że komu potrzebne gadające roboty... Przede wszystkim: Kedrigern może generować komunikaty diagnostyczne w czasie testowania/programowania robota. Jakie to ma znacze nie nie muszę chyba mówić nikomu, kto choć raz ustawiał np. regulatory silników czy zakres ruchu serw w warunkach polowych. Poza robotyką może być bardzo dobrym rozwiązaniem do urządzeń typu headless - ja np. stosuję podobne (poprzednika Kedrigerna) rozwiązanie do obsługi sterownika pieca CO (podanie np. godzin nieobecności w mieszkaniu) czy jako wygodnego interfejsu do wpisywania wyników pomiaru ciśnienia krwi i poziomu cukru z małej przenośnej klawiaturki. A to już nie są zabawki A w ogóle przypominam, że Roomba też gada (tyle że Ciapek ładniej) Zdaję sobie sprawę z tego, że opis jest bardzo pobieżny. Z chęcią odpowiem na wszystkie pytania - o ile kogoś to będzie interesować... W każdym razie wypróbowanie Kedrigerna nawet bez modułu ust posiadacza RPi z wyjściem audio nic nie kosztuje, a może się przyda? Kody źródłowe Mileny i Kedrigerna są dostępne na stronie http://milena.polip.com A, i ostatnie wyjaśnienie: Ciapek to mały troll, wychowanek czarodzieja Kedrigerna w książce Johna Morressy'ego "Głos dla księżniczki". Nawet trochę podobny Przy okazji: @Treker, czemu pliki zip są cacy a tgz są be? kedrigern.zip pykedrigern.zip
  22. Cześć! Chciałbym zlecić wykonanie oprogramowania pod fajny projekt. Prototyp urządzenia jest na Śląsku, stąd niestety potrzebna jest osoba z tego regionu. Temat obejmuje kilka składników. Chodzi o system składający się z: - aplikacji klienckiej która zarządza automatyką (zawór, przepływomierz) na podstawie danych z karty rfid, komunikując się z serwerem SQL - docelowo uruchamiana na Raspberry Pi - aplikacji zarządzającej kartami rfid (tworzenie / edycja kart / wybór asortymentu dla aplikacji klienckiej), przy użyciu interfejsu z ekranem dotykowym, komunikując się z serwerem SQL - docelowo uruchamiana na Raspberry Pi - baza SQL przechowująca dane dotyczące kart klientów, dostępnego asortymentu do sprzedaży oraz dane dotyczące samej sprzedaży - docelowo uruchamiana na komputerze PC z Linuxem - front-end do SQL - pozwalający na przyjazny dostęp do bazy SQL celem edycji asortymentu, wyciągania danych dotyczących sprzedaży, edycji kart klientów, etc. Wykorzystane będą komputery RaspberryPi pracujące na OS Raspbian z elementami automatyki (czytnik RFID na SPI, elektrozawór sterowany sygnałem z RPi, przepływomierz generujący impulsy zliczane przez RPi) do której istnieją gotowe biblioteki, Wybór dystrybucji oraz serwera SQL - na ten moment do podjęcia, najlepiej żeby to było jakieś popularne środowisko. Front-end do SQL - najprościej będzie napisać w PHP, Oprogramowania na RPi do wyboru Python lub Java - programy mają mieć graficzny interfejs, aplikacja kliencka tylko wyświetla odpowiednią zawartość, aplikacja zarządzająca musi pozwalać na interakcję z operatorem. To zarys tematu, szczegóły do dogadania osobiście.
  23. Witam i wielka prośba o pomoc. Planuję przetestować współpracę mojej malinki (Pi 2 B) z kamerą podłączoną przez USB. Znalazłem wiele pozytywnych informacji nt. programu fswebcam, ale niestety utknąłem na samym początku tj. na jego instalacji. Mianowicie polecenie sudo apt-get install fswebcam informuje o problemach z repozytorium http://mirrordirector.raspbian.org W związku z tym znalazłem źródło na GitHub i próbowałem postępować zgodnie ze wskazówką autora (Philip Heron). Dodam, że pobrane pliki w formie ZIP rozpakowałem i cały folder fswebcam-master umieściłem w /home/pi. Następnie z poziomu folderu fswebcam-master wprowadziłem polecenie ./configure --prefix=/usr Niestety tym razem dowiedziałem się, że -bash: ./configure: Permission denied Próba wpisania przed tym "sudo" zmienia tyle, że sudo: ./configure: command not found Wprawdzie nie jest to czysty system, ale zbyt wiele modyfikacji nie wprowadzałem i działam na standardowym koncie "pi". Próbowałem jeszcze kilku innym możliwości włącznie z przypisaniem do /usr dodatkowych uprawnień, wszystko bez pozytywnego rezultatu. Wielka prośba o pomoc, niestety ja dopiero zaczynam i moja wiedza pozostawia jeszcze wiele do życzenia ;-)
  24. AJAX umożliwia przekazywanie danych pomiędzy klientem a serwerem WWW bez konieczności przeładowania strony. Dodając do tego timer w JavaScript możemy uzyskać świeże dane na stronie generowanej przez ESP8266. Na początek stwórzmy w PHP najprostszą stronę WWW prezentującą aktualną godzinę pobieraną z serwera (nie "JavaScriptovy" czas z przeglądarki - w końcu docelowo chcemy pobierać dane z czujników podłączonych do "serwera WWW" postawionego na ESP8266): <? if ($_REQUEST["time"]) { echo date("G:i:s"); exit; } ?> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>AJAX test</title> </head> <body> <span id="time"></span> <script> myTimer(); var myVar = setInterval(myTimer, 1000); function myTimer() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("time").innerHTML = this.responseText; } }; xhttp.open("GET", "test.php?time=1", true); xhttp.send(); } </script> </body> </html> Timer co sekundę przywołuje funkcję myTimer(); var myVar = setInterval(myTimer, 1000); a ta pobiera zawartość podstrony test.php?time=1 i wstawia ją do elementu o nazwie "time" (document.getElementById("time").innerHTML = this.responseText;). Mamy tu tylko jeden przekazywany parametr. Co zrobić, by aktualizować kilka różnych wartości? Przywykłem do podstrony przekazującej parametry rozdzielone znakiem ; (odczyt1;odczyt2;odczyt3). Dzięki JavaScriptowej funkcji split możemy podzielić taki ciąg znaków na tablice, a potem przydzielić jej części do elementów SPAN o określonym ID. <? if ($_REQUEST["time"]) { echo date("d.m.y;G:i:s"); exit; } ?> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>AJAX test</title> </head> <body> Date: <span id="date"></span><br> Time: <span id="time"></span> <script> myTimer(); var myVar = setInterval(myTimer, 1000); function myTimer() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var str = this.responseText; var values = str.split(";"); document.getElementById("date").innerHTML = values[0]; document.getElementById("time").innerHTML = values[1]; } }; xhttp.open("GET", "test.php?time=1", true); xhttp.send(); } </script> </body> </html> Działa! PHP po zainstalowania serwera np NGINX możemy uruchomić na Raspberry Pi. W połączeniu (komenda system()) z zewnętrznym skryptem Python lub programem w C korzystającym z WiringPi otrzymamy stronę z odczytami czujników hostowaną na Raspberry Pi! Spróbujmy wreszcie zaprogramować mikrokontroler ESP8266. Podłączmy najpierw czujnik BME280. /* I2C D4 - SCL D3 - SDA */ #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <Wire.h> #include <Adafruit_Sensor.h> #include <Adafruit_BME280.h> char* ssid = "Weather"; //const char *password = ""; ESP8266WebServer server(80); Adafruit_BME280 bme; void setup() { Serial.begin(9600); Wire.begin(D3, D4); Wire.setClock(100000); if (!bme.begin(0x76)) //changed from default I2C adress 0x77 { Serial.println("Nie odnaleziono czujnika BMP085 / BMP180"); while (1) { } } IPAddress apIP(192, 168, 1, 1); WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); // WiFi.softAP(ssid, password); WiFi.softAP(ssid); server.on("/", handleRoot); server.on("/sensors", handleSensors); server.begin(); } void loop() { server.handleClient(); } void handleRoot() { String content = "<html> <head><title>Weather</title></head><body>"; content += "<DIV style=\"display:table; font-size: large;\"><DIV style=\"border-style: solid;\">BME280:<BR>Temperature: <span id=\"tempBME\"></span>C<br>Humidity: <span id=\"humBME\"></span>%<br>Pressure: <span id=\"presBME\"></span>Pa<br></DIV>"; content += "<script>myTimer();var myVar = setInterval(myTimer, 1000);function myTimer() {var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var str = this.responseText; var values = str.split(\";\"); document.getElementById(\"tempBME\").innerHTML = values[0]; document.getElementById(\"humBME\").innerHTML = values[1]; document.getElementById(\"presBME\").innerHTML = values[2];} }; xhttp.open(\"GET\", \"sensors\", true); xhttp.send();}</script>"; content += "</body></html>"; server.send(200, "text/html", content); } void handleSensors() { String content = String(bme.readTemperature()) + ";" + String(bme.readHumidity()) + ";" + String((int)bme.readPressure()) + ";"; server.send(200, "text/html", content); } Rozdzielanie danych przecinkiem czy średnikiem nie jest sposobem "zbyt profesjonalnym". Przy dużej ilości zmiennych łatwo też o pomyłkę. Dlatego lepiej wtedy stosować bardziej odpowiednie formaty danych: JSON czy XML. Ze względu na "bliskość" JSON z JavaScript skupię się tylko na nim. Gotowa biblioteka ArduinoJson wygeneruje dane za nas. Więcej informacji znajdziemy w rozdziale Serialize with ArduinoJson dokumentacji technicznej. /* I2C D4 - SCL D3 - SDA */ #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <Wire.h> #include <Adafruit_Sensor.h> #include <Adafruit_BME280.h> #include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson char* ssid = "Weather"; //const char *password = ""; ESP8266WebServer server(80); Adafruit_BME280 bme; void setup() { Serial.begin(9600); Wire.begin(D3, D4); Wire.setClock(100000); if (!bme.begin(0x76)) //changed from default I2C adress 0x77 { Serial.println("Nie odnaleziono czujnika BMP085 / BMP180"); while (1) { } } IPAddress apIP(192, 168, 1, 1); WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); // WiFi.softAP(ssid, password); WiFi.softAP(ssid); server.on("/", handleRoot); server.on("/sensors", handleSensors); server.begin(); } void loop() { server.handleClient(); } void handleRoot() { String content = "<html> <head><title>Weather</title></head><body>"; content += "<DIV style=\"display:table; font-size: large;\"><DIV style=\"border-style: solid;\">BME280:<BR>Temperature: <span id=\"tempBME\"></span>C<br>Humidity: <span id=\"humBME\"></span>%<br>Pressure: <span id=\"presBME\"></span>Pa<br></DIV>"; content += "<script>myTimer();var myVar = setInterval(myTimer, 1000);function myTimer() {var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var str = this.responseText; var values = JSON.parse(str); document.getElementById(\"tempBME\").innerHTML = values.temp; document.getElementById(\"humBME\").innerHTML = values.hum; document.getElementById(\"presBME\").innerHTML = values.press;} }; xhttp.open(\"GET\", \"sensors\", true); xhttp.send();}</script>"; content += "</body></html>"; server.send(200, "text/html", content); } void handleSensors() { String content; StaticJsonBuffer<400> jsonBuffer; JsonObject& root = jsonBuffer.createObject(); root["temp"] = bme.readTemperature(); root["hum"] = bme.readHumidity(); root["press"] = (int)bme.readPressure(); root.printTo(content); server.send(200, "text/html", content); } Strona prezentować się będzie tak samo jak poprzednio. Zyskamy za to wygodny i czytelny sposób dopisywania nowych danych root["temp"] = bme.readTemperature(); oraz ich odczytywania w kodzie źródłowym strony: document.getElementById(\"tempBME\").innerHTML = values.temp; Nie przejmujemy się już numeracją elementów długiej tablicy. Sytuację możemy też odwrócić tworząc stronę WWW, której formularz sterować będzie pracą naszego fizycznego urządzenia. Oczywiście nadal niekonieczne będzie przeładowanie strony, by wysłać dane. #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> char* ssid = "Weather"; //const char *password = ""; int ledValue = 0; ESP8266WebServer server(80); void setup() { Serial.begin(9600); IPAddress apIP(192, 168, 1, 1); WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); // WiFi.softAP(ssid, password); WiFi.softAP(ssid); server.on("/", handleRoot); server.begin(); pinMode(D1, OUTPUT); analogWriteRange(100); //http://esp8266.github.io/Arduino/versions/2.0.0/doc/reference.html analogWriteFreq(500); } void loop() { server.handleClient(); analogWrite(D1, ledValue); } void handleRoot() { if (server.hasArg("ledVal") && server.arg("ledVal").toInt() >= 0 && server.arg("ledVal").toInt() <= 100) { ledValue = server.arg("ledVal").toInt(); Serial.print("ledVal "); Serial.println(ledValue); server.send(200, "text/html", ""); return; } //https://www.w3schools.com/howto/howto_js_rangeslider.asp //https://stackoverflow.com/questions/9713058/send-post-data-using-xmlhttprequest String content = "<!DOCTYPE html>" "<html>" "<head>" "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" "<title>Luminosity setter</title>" "<style>" ".slidecontainer {" "width: 1024px;" "margin: 0 auto;" "text-align: center;" "}" ".slider {" " -webkit-appearance: none;" " width: 100%;" " height: 25px;" " background: #d3d3d3;" " outline: none;" " opacity: 0.7;" " -webkit-transition: .2s;" " transition: opacity .2s;" // " margin-left: 20px;" // " margin-right: 20px;" "}" ".slider:hover {" " opacity: 1;" "}" ".slider::-webkit-slider-thumb {" " -webkit-appearance: none;" " appearance: none;" " width: 25px;" " height: 25px;" " background: #4CAF50;" " cursor: pointer;" "}" ".slider::-moz-range-thumb {" " width: 25px;" " height: 25px;" " background: #4CAF50;" " cursor: pointer;" "}" "</style>" "</head>" "<body>" "<div class=\"slidecontainer\">" " <input type=\"range\" min=\"0\" max=\"100\" value=\"" + String(ledValue) + "\" class=\"slider\" id=\"myRange\">" " <p>Value: <span id=\"demo\"></span>%</p>" "</div>" "<script>" "document.getElementById(\"demo\").innerHTML = document.getElementById(\"myRange\").value;" "document.getElementById(\"myRange\").oninput = function() {" " document.getElementById(\"demo\").innerHTML = this.value;" "var data = new FormData();" "data.append('ledVal', this.value);" "var xhr = new XMLHttpRequest();" "xhr.open('POST', '/', true);" "xhr.onload = function () {" " console.log(this.responseText);" "};" "xhr.send(data);" "}" "</script>" "</body>" "</html>"; server.send(200, "text/html", content); } W tym przypadku przesunięcie suwaka na stronie sterującej wywoła natychmiastową zmianę jasności diody LED podłączonej odpowiednim rezystorem do pinu D1.
  25. Mam do sprzedania kartę dźwiękową do Raspberry Pi, którą właśnie wygrałem w konkursie organizowanym przez czasopisma The MagPi. Jest to karta HiFiBerry z dodatkowym 24-bitowym przetwornikiem A/C. Dokładnie taka jak tutaj: https://botland.com.pl/pl/raspberry-pi-karty-dzwiekowe-i-hifiberry/13374-hifiberry-dac-adc-karta-dzwiekowa-do-raspberry-pi-4b3b32ba-4260439550583.html Karta jest oryginalnie zapakowana, nie mam zamiaru jej nawet wyjmować z pudełeczka. Cena jaka mnie interesuje to 180 zł + koszty wysyłki, czyli ok. 2/3 ceny sklepowej. Jestem otwarty na propozycje zainteresowanych zakupem.
×
×
  • Utwórz nowe...