Popularny post PrzemekKempe Napisano Luty 4, 2020 Popularny post Udostępnij Napisano Luty 4, 2020 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 1 Link do komentarza Share on other sites More sharing options...
mediakon Luty 5, 2020 Udostępnij Luty 5, 2020 Witaj, bardzo dobry artykuł jednak mam problem z uruchomieniem serwera mosquitto. Mianowicie po instalacji mosquitto (bez node reda) kompiluję program wg. Twojego przykładu z moimi danymi i okazuje się, że musiałem wymienić bibliotekę #include <WiFi.h> na #include <ESP8266WiFi.h>, aby nie pojawiały się błędy odnośnie zmiennej const char* ssid = "Ixxx"; //ZMIENIC na swoje const char* password = "yyyy"; //ZMIENIC na swoje Pojawiało się coś takiego: invalid conversion from 'const char*' to 'char*' [-fpermissive] chodziło o linię z kodem WiFi.begin(ssid, password); Jak zmieniłem na ESP8266WiFi.h to moduł ESP 12E łączy się bez problemu, natomiast nie chce się połączyć z MQTT cały czas mam z tym problem i teraz pytanie co może być nie tak? W tej chwili chodzi mi tylko o uruchomienie MQTT na mojej malince, bo poprzez np. cloudmqtt.com łączę się bez problemu z ESP 12E. (na czystym raspberry lite, wykonane zostały Twoje polecenia dotyczące instalacji mosquitto) Czy masz może jeszcze jakieś sugestie dotyczące uruchomienia w/w serwera? Pozdrawiam, Piotr Link do komentarza Share on other sites More sharing options...
PrzemekKempe Luty 6, 2020 Autor tematu Udostępnij Luty 6, 2020 10 godzin temu, mediakon napisał: Pojawiało się coś takiego: invalid conversion from 'const char*' to 'char*' [-fpermissive] chodziło o linię z kodem WiFi.begin(ssid, password); Aby uniknąć tego błędu musisz usunąć słowo const. 10 godzin temu, mediakon napisał: Jak zmieniłem na ESP8266WiFi.h to moduł ESP 12E łączy się bez problemu, natomiast nie chce się połączyć z MQTT cały czas mam z tym problem i teraz pytanie co może być nie tak? Jeśli łączysz się z zewnętrznym serwerem to musisz zmienić adres IP na jego nazwę. Jeśli jest problem w sieci lokalnej upewnij się co do adresu IP Raspberry. Jeśli to nie daje rezultatu spróbuj zrobić restart, dalej komendy: sudo systemctl disable mosquitto.service sudo apt-get install --reinstall mosquitto sudo systemctl enable mosquitto.service sudo reboot now Jeśli to nie pomoże to wklej proszę logi z konsoli ESP. 2 Link do komentarza Share on other sites More sharing options...
mediakon Luty 6, 2020 Udostępnij Luty 6, 2020 Dziękuję za odpowiedź o poświęcony czas. Logi wkleję jak będę przed komputerem, natomiast Raspberry i jego moquitto działa bez problemu tylko na raspberry (lokalnie). Otwierając dwa okna Putty (ssh) można przesyłać wiadomości via mqtt. Może laickie pytanie, czy raspberry ma przydzieloną nazwę np. raspberrypi.local ( jeszcze nie próbowałem dziś o tym czytałem )? Wygląda to tak jakby ESP (arduino) nie widział IP maliny jako serwera MQTT czyli np. 192.168.1.9 w moim przypadku. IP maliny jest poprawne takie widnieje na routerze i tak się łącze po ssh do niej. Jeszcze jedno pytanie mi się nasuwa czy router INEA nie blokuje portu 1883... Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
PrzemekKempe Luty 6, 2020 Autor tematu Udostępnij Luty 6, 2020 O routerze ciężko jest mi się jednoznacznie wypowiedzieć, ponieważ nie znam tego dostawcy internetu. Możesz spróbować uruchomić router przez telefon (funkcja hotspot/tethering) i wtedy przypisać odpowiednie dane. Link do komentarza Share on other sites More sharing options...
mediakon Luty 6, 2020 Udostępnij Luty 6, 2020 W chwili kiedy używam biblioteki WiFi.h (najnowsza wersja) dostaję taki komunikat w konsoli 21:04:12.901 -> ets Jan 8 2013,rst cause:4, boot mode:(3,6) 21:04:12.901 -> 21:04:12.901 -> wdt reset 21:04:12.901 -> load 0x4010f000, len 1392, room 16 21:04:12.901 -> tail 0 21:04:12.901 -> chksum 0xd0 21:04:12.901 -> csum 0xd0 21:04:12.901 -> v3d128e5c 21:04:12.901 -> ~ld 21:04:12.970 -> 21:04:12.970 -> Laczenie z INEA-xxd2.4Ghz Link do komentarza Share on other sites More sharing options...
PrzemekKempe Luty 6, 2020 Autor tematu Udostępnij Luty 6, 2020 Jeśli po tym komunikacie nic nie następuje to znaczy, że problem jest w połączeniu z routerem. Skoro tak to albo jest problem z zasięgiem lub czymś innym po stronie niezależnej od programu albo jest problem z biblioteką. Spróbowałbym połączyć to z innym routerem (np przy pomocy udostępniania przez telefon). Link do komentarza Share on other sites More sharing options...
mediakon Luty 6, 2020 Udostępnij Luty 6, 2020 Poszukam inny router i sprawdzę. ps. na malinie właśnie ustawiłem stałe IP za pomocą DHCP i też to nic nie dało 😉 no nic walczę dalej. Link do komentarza Share on other sites More sharing options...
mediakon Luty 6, 2020 Udostępnij Luty 6, 2020 (edytowany) Inny router i działa 😉 jeszcze raz dziękuję za pomoc. ps. na library wifi.h ciągle ten sam błąd co wyżej. Edytowano Luty 6, 2020 przez mediakon 2 Link do komentarza Share on other sites More sharing options...
PrzemekKempe Luty 6, 2020 Autor tematu Udostępnij Luty 6, 2020 1 godzinę temu, mediakon napisał: ps. na library wifi.h ciągle ten sam błąd co wyżej. Prawdopodobnie jest to kwestia użytej płytki. Jak pisałem w artykule, mają one swoje "dziwactwa" więc jakoś szczególnie mnie to nie dziwi. Na tym etapie jednak zmiana biblioteki nic nie zmienia, bo używana jest tylko do nawiązania i utrzymania połączenia. Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »