Skocz do zawartości

Przeszukaj forum

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

  • 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 5 wyników

  1. Zainspirowany artykułem o komunikacji Raspberry Pi z ESP32 z użyciem Mqqt chciałbym pokazać jak korzystając z JavaFx stworzyć prosty panel kontrolny dla urządzenia pracującego z tymże protokołem. JavaFX pozwala tworzyć aplikacje, które wyglądają bardziej nowocześnie, są równie wydajne, a przy tym można zachować dużo większą czytelność kodu. Od Javy w wersji 8 staje się to rekomendowaną biblioteką tworzenia graficznego interfejsu użytkownika[1]. Do przygotowania projektu będziemy potrzebować Eclipse IDE for Java Developers który znajdziemy tutaj https://www.eclipse.org/downloads/packages/ oraz wtyczki e(fx)clipse którą wyszukujemy i instalujemy poprzez Eclipse Marketplace znajdujący się w zakładce Help trzecia pozycja od dołu. Kiedy nasza instalacja zakończy się uruchamiamy ponownie Eclipsa i tworzymy nowy projekt wybierając File >> New >> Projekt… Po przejściu do ostatniego kroku kreatora nasz projekt pokaże się po lewej stronie. Do budowy projektu potrzebujemy jeszcze biblioteki Eclipse Paho którą znajdziemy pod tym odnośnikiem https://www.eclipse.org/downloads/download.php?file=/paho/releases/1.1.0/Java/plugins/org.eclipse.paho.client.mqttv3_1.1.0.jar Po pobraniu biblioteki dodajemy ją do naszego projektu przechodząc do File >> Properties I w zakładce Libraries w podmenu Java Builid Path wybieramy Add External JARs... i wskazujemy plik pobranej biblioteki. Teraz w naszym wygenerowanym projekcje ustawiamy parametry połączenia, kolejno nieprzechowywanie wiadomości pomiędzy ponownymi połączeniami z serwerem MQTT, czas oczekiwania na wiadomość, nazwę użytkownika i jego hasło. Na koniec tworzymy obiekt połączenia podając adres brokera wraz z portem oraz nazwę naszego klienta. MqttConnectOptions connectOptions = new MqttConnectOptions(); connectOptions.setCleanSession(true); connectOptions.setKeepAliveInterval(120); connectOptions.setUserName("tutaj nazwa użytkownika"); connectOptions.setPassword("tutaj hasło".toCharArray()); MqttClient mqttClient = new MqttClient("tcp://tutaj adres serwera:1883", "SimpleMqqt"); W następnym kroku stworzymy lewy panel który będzie wyświetlał stan czujników przykładowo temperaturę oraz obroty wentylatora oraz prawy panel z przyciskami do sterowania przykładowo oświetleniem zewnętrznym oraz oświetleniem wewnętrznym. Label temperatureLabel = new Label("Temperatura"); Label temperatureValue = new Label("0 \u2103"); Label fanLabel = new Label("Praca Wentylatora"); Label fanValue = new Label("0 %"); VBox leftBox = new VBox(temperatureLabel, temperatureValue, fanLabel, fanValue); leftBox.setAlignment(Pos.BASELINE_RIGHT); leftBox.setBackground(new Background(new BackgroundFill(Color.SEASHELL, null, null))); Label light1Label = new Label("Oświetlenie wnętrze"); Button light1Button = new Button("WYŁ"); Label light2Label = new Label("Oświetlenie zewnętrzne"); Button light2Button = new Button("WYŁ"); VBox rightBox = new VBox(light1Label, light1Button, light2Label, light2Button); rightBox.setAlignment(Pos.BASELINE_RIGHT); rightBox.setBackground(new Background(new BackgroundFill(Color.ALICEBLUE, null, null))); Mając już stworzone panele możemy dodać akcje dla przycisków czyli przesłanie wiadomości WŁ jeżeli przycisk na etykietę WYŁ i odwrotnie. Tutaj mam dwie możliwości tworząc obiekt wiadomości lub poprzez konfigurację bezpośrednią przy nadaniu wiadomości podając nazwę tematu, zawartość wiadomości, QoS, czy powinien zachować wiadomość light1Button.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { //Wysłanie wiadomości bez tworzenia obiektu try { if (((Button) event.getSource()).getText().equals("WYŁ")) { mqttClient.publish("mqtt/control/light1", "WŁ".getBytes(), 0, false); } else { mqttClient.publish("mqtt/control/light1", "WYŁ".getBytes(), 0, false); } } catch (MqttException e) { e.printStackTrace(); } }}); light2Button.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { //Wysłanie wiadomości z wykorzystaniem obiektu try { if (((Button) event.getSource()).getText().equals("WYŁ")) { MqttMessage mqttMessage = new MqttMessage(); mqttMessage.setPayload("WŁ".getBytes()); mqttMessage.setQos(0); mqttClient.publish("mqtt/control/light2",mqttMessage); } else { MqttMessage mqttMessage = new MqttMessage(); mqttMessage.setPayload("WYŁ".getBytes()); mqttMessage.setQos(0); mqttClient.publish("mqtt/control/light2", mqttMessage); } } catch (MqttException e) { e.printStackTrace(); } }}); Możemy sterować oświetleniem ale chcielibyśmy także otrzymywać aktualizację danych z czujników. W tym celu potrzebujemy stworzyć obiekt który pozwoli nam wykonać akcję po otrzymaniu nowej wiadomości. MqttCallback mqttCallback = new MqttCallback() { @Override public void messageArrived(String topic, MqttMessage message) throws Exception { if (topic.equals("mqtt/temperature")) { Platform.runLater(new Runnable() { @Override public void run() { temperatureValue.setText(message.toString() + " \u2103"); }}); } else if (topic.equals("mqtt/fan")) { Platform.runLater(new Runnable() { @Override public void run() { fanValue.setText(message.toString() + " %"); }}); } else if (topic.equals("mqtt/state/light1")) { Platform.runLater(new Runnable() { @Override public void run() { light1Button.setText(message.toString()); }}); } else if (topic.equals("mqtt/state/light2")){ Platform.runLater(new Runnable() { @Override public void run() { light2Button.setText(message.toString()); }}); }} @Override public void deliveryComplete(IMqttDeliveryToken arg0) { // TODO Auto-generated method stub } @Override public void connectionLost(Throwable arg0) { // TODO Auto-generated method stub } }; W metodzie messageArrived dodajemy akcje ustawienia wartości temperatury kiedy otrzymamy wiadomość dla tematu mqtt/temperature , tak samo dla pracy wentylatora oraz akcję zmiany etykiety przycisku sterowania oświetleniem kiedy w temacie mqtt/state/light pojawi zmiana jego stanu. Jako że budowa JavaFx nie pozwala bezpośrednio na zmianę wartości elementów musimy skorzystać z konstrukcji Platform.runLater. Tak przygotowany obiekt wskazujemy jako odbiorcę wiadomości w naszym obiekcie połączenia, łączymy się z brokerem za pomocą obiektu z parametrami połączenia oraz obserwujemy wybrane przez nas tematy. mqttClient.setCallback(mqttCallback); mqttClient.connect(connectOptions); mqttClient.subscribe("mqtt/temperature"); mqttClient.subscribe("mqtt/fan"); mqttClient.subscribe("mqtt/state/light1"); mqttClient.subscribe("mqtt/state/light2"); Do głównego okna aplikacji dodajemy poprzednio stworzone panele. BorderPane root = new BorderPane(); root.setLeft(leftBox); root.setCenter(rightBox); Scene scene = new Scene(root, 400, 400); scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm()); primaryStage.setScene(scene); primaryStage.setTitle("Simple Mqqt Control"); primaryStage.show(); Ostatni krok to dodanie akcji zamknięcia połączenia z naszym serwerem, kiedy zamkniemy okno naszej aplikacji. primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() { @Override public void handle(WindowEvent event) { try { mqttClient.disconnect(); mqttClient.close(); } catch (MqttException e) { e.printStackTrace(); } } }); Nasz klient jest gotowy do użycia, jako że jest to tylko przykład nie powala swoim wyglądem. Jest podzielony na sekcję czujników i sekcję kontroli client.zip [1] https://javastart.pl/baza-wiedzy/frameworki/javafx
  2. 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. Ten wpis brał udział konkursie na najlepszy artykuł o elektronice lub programowaniu. Sprawdź wyniki oraz listę wszystkich prac » Partnerem tej edycji konkursu (marzec 2020) był popularny producent obwodów drukowanych, firma PCBWay. 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
  3. Witam, Od dłuższego czasu próbuje rozwiązać problem z modułem ESP-01 podpiętym pod Arduino Mega. Mianowicie kiedy wysyłam dane przez serwer MQTT do ESP np. z telefonu i wyślę tych danych zbyt dużo w czasie od 1 do 5 sekund, to cały program przestaje reagować na kolejne dane przez najbliższe 20-40 sekund lub następuje ponowne uruchomienie Arduino. Program nie jest jakoś super skomplikowany (ponieważ służył mi tylko do testów ESP) więc myślę, że nie będzie on trudny do zrozumienia. Moduł jest podpięty do Arduino przez konwerter poziomów logicznych. Myślę, że problemem nie będzie połączenie, ponieważ wysyłanie danych działa bez problemu, a kiedy dane są wysyłane do ESP w odstępach 1-2 s to wszystko działa bez problemu. Kod: #include <LiquidCrystal.h> #include <WiFiEsp.h> #include <WiFiEspClient.h> #include <WiFiEspUdp.h> #include <PubSubClient.h> #include <SPI.h> char ssid[] = "My-WiFi"; // your network SSID (name) char pass[] = "1234567890"; // your network password char server[] = "broker.hivemq.com"; // your network password int status = WL_IDLE_STATUS; // the Wifi radio's status // Initialize the Ethernet client object WiFiEspClient espClient; PubSubClient client(espClient); LiquidCrystal lcd(7, 6, 5, 4, 3, 2); void setup() { lcd.begin(16, 2); lcd.clear(); lcd.print("Loading: "); delay(1500); lcd.clear(); // initialize serial for debugging Serial.begin(115200); // initialize serial for ESP module Serial1.begin(115200); // initialize ESP module lcd.setCursor(0, 0); lcd.print("ESP initialize "); lcd.setCursor(0, 1); lcd.print("40%"); WiFi.init(&Serial1); lcd.setCursor(0, 0); lcd.print("Connect to WiFi "); lcd.setCursor(0, 1); lcd.print("65%"); // check for the presence of the shield if (WiFi.status() == WL_NO_SHIELD) { Serial.println("WiFi shield not present"); // don't continue while (true); } // attempt to connect to WiFi network while (status != WL_CONNECTED) { Serial.print("Attempting to connect to WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network status = WiFi.begin(ssid, pass); } lcd.setCursor(0, 0); lcd.print("Connect to MQTT "); lcd.setCursor(0, 1); lcd.print("80%"); Serial.println("You're connected to the network"); //connect to MQTT server client.setServer(server , 1883); client.setCallback(callback); lcd.setCursor(0, 0); lcd.print("Connect to MQTT "); lcd.setCursor(0, 1); lcd.print("100%"); delay(400); lcd.clear(); } //print any message received for subscribed topic void callback(char* topic, byte* payload, unsigned int length) { payload[length] = '\0'; String value = String((char*)payload); Serial.println(value); lcd.clear(); lcd.print(value); if (value == "State" || value == "state") { lcd.clear(); lcd.print("ESP is ready"); client.publish("km/esp/data", "ESP is still ready"); } else { client.publish("km/esp/data", "OK"); } } void loop() { if (!client.connected()) { reconnect(); } client.loop(); delay(250); } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting connection "); // Attempt to connect, just a name to identify the client if (client.connect("AMega")) { Serial.println("connected"); // Once connected, publish an announcement… client.publish("km/esp/data","ESP is ready"); // … and resubscribe client.subscribe("km/esp/input", 0); } else { Serial.print("failed"); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } Z góry dziękuje za pomoc.
  4. 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. Ten wpis brał udział konkursie na najlepszy artykuł o elektronice lub programowaniu. Sprawdź wyniki oraz listę wszystkich prac » Partnerem tej edycji konkursu (marzec 2020) był popularny producent obwodów drukowanych, firma PCBWay. 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.
  5. Większość osób pewnie zauważyła, że na forum znajdziemy kurs obsługi Raspberry Pi oraz jego kontynuację z opisem konkretnych projektów. Jednym z tematów, które mnie zainteresowały jest "inteligenty dom", czyli konfiguracja Domoticza: https://forbot.pl/blog/kurs-raspberry-pi-projekty-domoticz-ds18b20-maile-id27526 Bezpośrednie podłączanie czujników do malinki jest bardzo fajne, ma jednak pewne ograniczenia. Po pierwsze liczba dostępnych pinów może okazać się niewystarczająca. Drugi i poważniejszy problem to konieczność kładzenia kabli - powiedzmy do termometru za oknem, czy w innym pomieszczeniu. To prowadzi nie tylko do plątaniny kabli, kosztów remontu mieszkania, ale i do czysto elektrycznych problemów wynikających z długości przewodów. Spróbowałem więc do Domoticza działającego na Raspberry Pi podłączyć przykładowy czujnik (termometr DS18B20) za pomocą WiFi. Ponieważ ostatnio bardzo spodobała mi się zabawa z układami ESP32 wybrałem moduł z właśnie takim układem. Wybór platformy sprzętowej był prosty, jako serwer Raspberry Pi 3+, czujnik DS18B20 podłączony do modułu z ESP32. Do komunikacji używam WiFi, co chyba nie wymaga komentarza - wspomnę tylko, że moja sieć lokalna używa adresów 168.168.0.x. Trudniej było zdecydować się na odpowiedni protokół komunikacji między ESP32, a serwerem. Ostatnio interesowałem się protokołem MQTT, który jest wspierany przez Domoticz-a, więc postanowiłem go użyć. Jest to prosty protokół przeznaczony do telemetrii, czyli dokładnie tego co staram się uzyskać (więc powinno pójść łatwo). Na szczęście MQTT ma dobre wsparcie zarówno po stronie malinki, jak i ESP32 - nie trzeba więc pisać obsługi tego protokołu od podstaw, można wykorzystać gotowe narzędzia. Do obsługi MQTT po stronie serwera potrzebujemy tzw. broker. W tym celu wystarczy zainstalować na Raspberry Pi dwa pakiety: mosquitto oraz mosquitto-clients. Protokół MQTT opiera się na mechanizmie publikacji/subskrypcji danych. Dane przesyłane są w postaci tak zwanych tematów (ang. topic). ESP32 może więc publikować wyniki pomiarów z czujnika, a Domoticz je subskrybować. Może brzmi to dziwnie, więc na początek mały test. Raspberry Pi ma u mnie adres IP 192.168.0.150. Działa na nim serwer mosquitto na domyślnym porcie 1883. Aby zacząć subskrybować dane wpisuję np. mosquitto_sub -h 192.168.0.150 -v -t "forbot/test" Pierwsza opcja, czyli -h ustala adres serwera (poleceni można uruchomić ze zdalnego komputera), -v zwiększa gadatliwość programu (wyświetla nazwy tematów), a ostatni czyli -t określa nazwę tematu. Teraz z innego terminala, a nawet komputera mogę opublikować testowy komunikat: mosquitto_pub -h 192.168.0.150 -t "forbot/test" -m "Hello world!" Efekt wykonania tych poleceń wygląda następująco: Liczba dostępnych opcji jest znacznie większa, ale to co przetestowałem wystarczy na początek. Teraz mogę przejść do Domoticza i skonfigurować obsługę MQTT. Konfiguracja Domoticza Na początek zainstalowałem i skonfigurowałem Domoticz-a mniej-więcej według kursu. W każdym razie zaczynam bez podłączonych czujników z samą malinką oraz oczywiście mosquitto. Pierwszy krok w stronę MQTT to dodanie odpowiedniego urządzenia (opcja Setup->Hardware). Interfejs Domoticza jest dla mnie straszny, ale chociaż działa. W każdym razie opcje, które muszę wypełnić to: Name - nazwa urządzenia, nieistotna ale coś trzeba wpisać Type: "MQTT Client Gateway with LAN interface" Remote Adress - adres serwera, pewnie zadziała 127.0.0.1, ale ja wpisuję 192.168.0.150 Port: 1883 Teraz wystarczy przycisnąć "Add" i obsługa MQTT została dodana. Od razu ostrzeżenie - to co robię jest delikatnie mówiąc niezbyt bezpieczne. Należałoby dodać obsługę hasła oraz SSL, ale na razie nie będę się tym zajmować. Kolejny krok to dodanie urządzenia typu dummy (manekin?). Ponownie nazwa jest nieistotna, liczy się typ: "Dummy (Does nothing, use for virtual switches only)". Po dodaniu manekina pojawia się on na liście urządzeń. Ale co najważniejsze w kolumnie "Type" jest też przycisk "Create Virtual Sensors" - nie wiem czy tylko mnie interfejs Domoticza doprowadza do furii... ale jak już wspominałem ważne że działa. Naciskam ten jakże intuicyjnie umiejscowiony przycisk i pojawia się tym razem podejrzanie proste okienko dialogowe: Nazwa jak to nazwa, chociaż tym razem już nieco ważniejsza niż wcześniej, ale jak zwykle należy zwrócić uwagę na typa. Zacznę od przełącznika, skoro tak domoticz doradzał. Wybieram więc Switch i naciskam OK. Zgodnie z oczekiwaniem nowo dodane urządzenie będzie widoczne w zakładce Switches: Klikając myszą na ikonę żaróweczki można się takim przyciskiem bawić w nieskończoność - w końcu domoticz uprzedzał, że to nic nie robi... ale okazuje się że niezupełnie. Wracamy do linii poleceń i poznanego już mosquitto_sub. Tym razem uruchamiam nasłuchiwanie wszystkich tematów - w MQTT używany jest w tym celu znak #, coś jak * we wszystkich normalnych przypadkach. mosquitto_sub -h 192.168.0.150 -v -t "#" Na początku nic ciekawego się nie dzieje: Ale skoro wirtualny przycisk też nic nie robi to co szkodzi go przycisnąć: Wirtualna żaróweczka zaczyna świecić, ale co ważniejsze coś otrzymaliśmy przez MQTT: Dla osób nie lubiących oglądać obrazków poniżej kod: domoticz/out { "Battery" : 255, "RSSI" : 12, "description" : "", "dtype" : "Light/Switch", "id" : "00014051", "idx" : 1, "name" : "prztyczek", "nvalue" : 1, "stype" : "Switch", "svalue1" : "0", "switchType" : "On/Off", "unit" : 1 } domoticz/out to nazwa tematu, to co domoticz wysyła domyślnie wędruje właśnie tędy. Cała reszta to informacja o przyciśnięciu przycisku w formacie JSON. Można jeszcze raz nacisnąć przycisk i zobaczyć co się stanie: domoticz/out { "Battery" : 255, "RSSI" : 12, "description" : "", "dtype" : "Light/Switch", "id" : "00014051", "idx" : 1, "name" : "prztyczek", "nvalue" : 0, "stype" : "Switch", "svalue1" : "0", "switchType" : "On/Off", "unit" : 1 } Nie trzeba być szerlokiem, aby zrozumieć jak to działa - pole "nvalue" przesyła informację czy przycisk został włączony, czy wręcz przeciwnie. Teraz wystarczy takie dane sparsować i możemy mieć własny, zdalnie sterowany moduł. To działa bardzo ładnie na ESP32, ale chciałem na razie opisać własny czujnik. Dodawanie czujnika Poprzednio dodałem przycisk, teraz w bardzo podobny sposób dodaję wirtualny termometr. Na początek wracam do listy urządzeń (Setup->Hardware) oraz naciskam magiczny przycisk "Create Virtual Sensors": Tym razem dodaję urządzenie do pomiaru temperatury: Zanim przejdę dalej, warto wyświetlić listę zainstalowanych urządzeń. Znajdziemy ją wybierając Setup->Devices: Najważniejsza jest kolumna idx. Każde urządzenie ma swój identyfikator. W moim przypadku najpierw dodałem przycisk, który otrzymał numer 1 - stąd w kodzie JSON pole idx miało akurat taką wartość. Teraz gdy mam już dwa urządzenia identyfikatory stały się ważniejsze. A jak widać termometr ma idx równe 2. Czas zobaczyć jaką temperaturę wskazuje nowo zakupiony wirtualny termometr: Jak widać nie działa najlepiej. Spróbujmy więc wysłać do niego (o przepraszam - opublikować) jakąś wiadomość. mosquitto_pub -h 192.168.0.150 -t "domoticz/in" -m '{ "idx": 2, "nvalue": 0, "svalue": "3.14" }' Po chwili powinniśmy zobaczyć nasz odczyt z poziomu domoticz-a: Temat do wysyłania danych jest zawsze taki sam, czyli "domoticz/in", parametr "idx" identyfikuje nasz czujnik, a aktualna temperatura przesyłana jest jako napis w polu "svalue". Teraz wiemy już wszystko co konieczne, aby przygotować własny czujnik. Wystarczy na ESP32 połączyć się z WiFi, odczytać temperaturę z podłączonego termometru, a następnie używając MQTT wysłać komunikat o treści: { "idx": <ID_URZADZENIA>, "nvalue": 0, "svalue": "<TEMPERATURA>" } Do przygotowania takiego komunikatu nie potrzebujemy nawet biblioteki z obsługą JSON, wystarczy prosty sprintf. Na koniec jeszcze dwa słowa o parametrach przesyłanych w JSON oraz implementacji kodu na ESP32. Więcej o dostępnych opcja JSON znajdziemy np. tutaj: https://www.domoticz.com/wiki/Domoticz_API/JSON_URL's#Temperature Przy okazji zauważymy, że zamiast MQTT można byłoby użyć zwykłego http. Ja wybrałem MQTT, ale jak zwykle możliwości jest mnóstwo. Program na ESP32 implementowałem w IDF. Zarówno WiFi, jak i protokół MQTT obsługiwany jest przez standardowe biblioteki, przykład dla WiFI znajdziemy tutaj: https://github.com/espressif/esp-idf/tree/master/examples/wifi/getting_started/station, natomiast MQTT: https://github.com/espressif/esp-idf/tree/master/components/mqtt
×
×
  • Utwórz nowe...