Wprowadzanie
Tym razem pokaże Wam jak zrobić notifikator.
Urządzenie można podłączyć np do systemu IFTTT i reagować odpowiednio gdy pojawi się nowy mail. Poprzez app.remoteme.org wygenerujemy link po wywołaniu którego do naszego arduino zostaną wysłane bajty z informacją jaki efekt wyświetlić.
Co będzie potrzebne
- NodeMCU, WemOS lub coś podobnego
- Dwa pierścienie LED z diodami WS2812B (ja użyłem pierścienie z 16-toma diodami)
- DFRobotDFPlayerMini – czyli odtwarzacz mp3. Nasze pliki są zapisane na karcie SD. Do moduły poprzez Serial’a wysyłamy komendy – np zagraj utwór pierwszy
- Głośnik
- Karta SD
- Konwerter stanów logicznych – ja użyłem tego, wynika to z tego, że odtwarzacz pracuje na napięciu 5V a nasze aruino na 3.3V
- Umiejętność wytrawienia prostej płytki PCB
Wieża
- tektura – dwie różne grubości
- kalka techniczna
- folia aluminiowa
Budowa wieży
Powyżej plan wieży w rzucie bocznym (moja przygoda z rysunkiem technicznym zakończyła się w podstawówce ), wymiary podane w milimetrach.
Zasada działania
- pierścień ledów rzucający światło na 2.
- Kalka techniczna – półprzeźroczysty materiał.
- stożek ścięty, wykonany z tektury i oklejony folią aluminiową, żeby ładnie odbijał światło ledów które następnie przechodzi przez 2, na rysunku 3′ siatka do wycięcia
- rurka z kartonu – trzyma wieże pionowo, a w środku poprowadzone są podłączenia diód
- Wysokość zależy od was ja u siebie mam 85mm
- Podstawka – wymiary dowolne u mnie identyczne jak na planie, w niej musi się zmieścić arduino głośnik odtwarzacz mp3 i konwerter stanów
Rysunek powyżej powinien rozwiać wszelkie wątpliwości jeżeli chodzi o budowę
I widok całości.
Widok od dołu wraz z podłączeniami.
Wybaczcie brak poszczególnych kroków budowy, ale w czasie budowanie wieży nie sądziłem, że zrobię ten kurs.
Najlepiej wszystkie poziome elementu wykonać z grubszej tektury.
Schemat połączeń
Odtwarzacz mp3 jest zasilany napięciem 5V i komunikuje się z arduino poprzez TX/RX , potrzebny jest konwerter stanów logicznych ponieważ samo arduino pracuje na napięciu 3.3V. Sterowanie Pierścieniami led również jest podłączone do arduino (D5,D6) poprzez konwerter stanów logicznych.
W repozytorium znajduję się rownież plik Eagle do wytrawienia płytki
Uwaga: Jeżeli zdecydujecie się wlutować NodeMCU bezpośrednio w płytkę warto usunąć rozlaną masę spod anteny i w obrębie 15mm pod nią (albo jeszcze lepiej przesunąć nodeMCU tak żeby antena wystawała poza obrys płytki), Pozwoli to wyeliminować interferencje.
gotowa płytka:
Proponuje nie wlutowywać na stałe arduino i odtwarzacza mp3 tylko użyć żeńskich goldpinów
Zasada działania
Nasze arduino łączy się do systemu app.remoteme.org używając websocketów ( są gotowe bibliotek) przez to połączenie wysyłane są wiadomości 5 bajtowe:
- pierwszy bajt efekt świetlny dla górnego pierścienia led
- drugi bajt efekt świetlny dla dolnego pierścienia led
- numer pliku mp3 do odtworzenia
- ilość sekund jak długi ma być efekt świetlny i odtwarzane mp3
- czy mp3 ma być odtworzone raz czy w pętli
kod źródłowy
Cały kod źródłowy dla arduino znajduje się tutaj
w plikach SingleRing.cpp i SingleRing.h znajduje się klasa do sterowania efektami pierścieni ledowych. Proponuje zacząć od przeglądnięcia funkcji setMode(int m):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
void SingleRing::setMode(int m) { switch (m) { case 0:setConfiguration(0, 0, 50, 0, 5, 1); break;//off =0 case 1:setConfiguration(6, 0, 50, 0, 0, 20); break;//solid standard green case 2:setConfiguration(6, 0, 0, 50, 0, 20); break;//solid standard blue case 3:setConfiguration(6, 50, 0, 0, 0, 20); break;//solid standard red case 4:setConfiguration(6, 50, 10, 0, 0, 20); break;//solid standard orange case 5:setConfiguration(1, 0, 100, 0, 5, 2); break;//police clockwise green case 6:setConfiguration(1, 0, 100, 0, 5, -2); break;// police revert green case 7:setConfiguration(1, 0, 0, 100, 5, 2); break;//police clockwise blue case 8:setConfiguration(1, 0, 0, 100, 5, -2); break;// police revert blue case 9:setConfiguration(1, 100, 0, 0, 5, 2); break;//police standard red case 10:setConfiguration(1, 100, 0, 0, 5, -2); break;// police revert red case 11:setConfiguration(1, 100, 20, 0, 5, 2); break;//police standard orange case 12:setConfiguration(1, 100, 20, 0, 5, -2); break;// police revert orange case 13:setConfiguration(2, 0, 0, 50, 8, 10); break;//cross standard blue case 14:setConfiguration(2, 0, 0, 50, 8, -10); break;// cross revert blue case 15:setConfiguration(5, 0, 50, 0, 0, 20); break;//blink standard green case 16:setConfiguration(5, 0, 50, 0, 0, -20); break;// blink odwyrtka green case 17:setConfiguration(5, 0, 0, 50, 0, 20); break;//blink standard blue case 18:setConfiguration(5, 0, 0, 50, 0, -20); break;// blink revert blue case 19:setConfiguration(5, 50, 0, 0, 0, 20); break;//blink standard red case 20:setConfiguration(5, 50, 0, 0, 0, -20); break;// blink revert red case 21:setConfiguration(5, 50, 10, 0, 0, 20); break;//blink standard orange case 22:setConfiguration(5, 50, 10, 0, 0, -20); break;// blink revert orange default: setConfiguration(0, 0, 50, 0, 5, 1); break;//off =0 } } |
w zależności od podanego parametru pierścień będzie wyświetlał dany efekt. Możecie dopisać własny efekt wołając funkcję setConfiguration z nowymi parametrami (zmiana koloru, prędkość wyświetlania) dodając nowy mode, albo dopisać całkiem nowy efekt – albo dać mi znać w komentarzach jeżeli mi się spodoba doimplementuje ;)
arduino.ino:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
#include "Arduino.h" #include "SoftwareSerial.h" #include "DFRobotDFPlayerMini.h" #include <ArduinoHttpClient.h> #include <RemoteMe.h> #include <ESP8266WiFi.h> #include "SingleRing.h" #include <ArduinoHttpClient.h> #include <RemoteMe.h> #include <ESP8266WiFi.h> #include <ESP8266WiFiMulti.h> #define WIFI_NAME "" #define WIFI_PASSWORD "" #define DEVICE_ID 205 #define DEVICE_NAME "siren" #define TOKEN "" #define DIODES_COUNT 16 SingleRing top = SingleRing(DIODES_COUNT, D5); SingleRing bottom = SingleRing(DIODES_COUNT, D6); SoftwareSerial mySoftwareSerial(D4, D3); // RX, TX DFRobotDFPlayerMini myDFPlayer; RemoteMe& remoteMe = RemoteMe::getInstance(TOKEN, DEVICE_ID); ESP8266WiFiMulti WiFiMulti; void setup() { mySoftwareSerial.begin(9600); Serial.begin(115200); if (!myDFPlayer.begin(mySoftwareSerial)) { //Use softwareSerial to communicate with mp3. Serial.println(F("Unable to begin:")); Serial.println(F("1.Please recheck the connection!")); Serial.println(F("2.Please insert the SD card!")); while (true); } Serial.println(F("DFPlayer Mini online.")); myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms myDFPlayer.volume(30); myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); WiFiMulti.addAP(WIFI_NAME, WIFI_PASSWORD); while (WiFiMulti.run() != WL_CONNECTED) { delay(100); } remoteMe.setUserMessageListener(onUserMessage); remoteMe.setupTwoWayCommunication(); remoteMe.sendRegisterDeviceMessage(DEVICE_NAME); top.setup(); bottom.setup(); top.clear(); bottom.clear(); } boolean turnedOff = true; unsigned long turnOffMillis = 0; void onUserMessage(uint16_t senderDeviceId, uint16_t dataSize, uint8_t *data) { uint16_t pos = 0; uint8_t bottomMode = RemoteMeMessagesUtils::getUint8(data, pos); uint8_t topMode = RemoteMeMessagesUtils::getUint8(data, pos); uint8_t trackNumber = RemoteMeMessagesUtils::getUint8(data, pos); uint8_t time = RemoteMeMessagesUtils::getUint8(data, pos); uint8_t mode = RemoteMeMessagesUtils::getUint8(data, pos); bottom.setMode(bottomMode); top.setMode(topMode); if (mode == 1) { myDFPlayer.loop(trackNumber); } else { myDFPlayer.play(trackNumber); } turnedOff = false; turnOffMillis = millis() + 1000 * time; } void loop() { remoteMe.loop(); top.loop(); bottom.loop(); if (turnOffMillis<millis()) { if (!turnedOff) { top.clear(); bottom.clear(); myDFPlayer.stop(); turnedOff = true; } } } |
omówienie:
1 2 3 4 5 |
#define WIFI_NAME "" #define WIFI_PASSWORD "" #define DEVICE_ID 205 #define DEVICE_NAME "notificator" #define TOKEN "" |
musimy uzupełnić dane dotyczące naszego połączenia. Szczegółowy opis tutaj wraz z instrukcją jak zarejestrować się w remoteme.org i wygenerować token
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
void onUserMessage(uint16_t senderDeviceId, uint16_t dataSize, uint8_t *data) { uint16_t pos = 0; uint8_t bottomMode = RemoteMeMessagesUtils::getUint8(data, pos); uint8_t topMode = RemoteMeMessagesUtils::getUint8(data, pos); uint8_t trackNumber = RemoteMeMessagesUtils::getUint8(data, pos); uint8_t time = RemoteMeMessagesUtils::getUint8(data, pos); uint8_t mode = RemoteMeMessagesUtils::getUint8(data, pos); bottom.setMode(bottomMode); top.setMode(topMode); if (mode == 1) { myDFPlayer.loop(trackNumber); } else { myDFPlayer.play(trackNumber); } turnedOff = false; turnOffMillis = millis() + 1000 * time; } |
Ta funkcja będzie wołana jak przyjdzie wiadomość do wyświetlenia notyfikacji. Kod jest na tyle przejrzysty, że sam siebie opisuje. Do szczegółów klas odsyłam do dokumentacji tutaj i tutaj
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void loop() { remoteMe.loop(); top.loop(); bottom.loop(); if (turnOffMillis<millis()) { if (!turnedOff) { top.clear(); bottom.clear(); myDFPlayer.stop(); turnedOff = true; } } |
w pętli wywołujemy funkcję loop obiektów, a także jeżeli czas wyświetlania notyfikacji minął wyłączamy diody i dźwięk.
Odtwarzacz mp3
Komunikuje się on z arduino poprzez TX/RX – po stronie arduino serial softwerowy. Szczegóły samego odtwarzacza tutaj , a bilbioteka z której krozystam tutaj
Na kartę SD wgrywamy pliki mp3. Pliki na karcie są uporządkowane alfabetycznie i wtedy wołając:
1 |
myDFPlayer.play(5); |
Odtwarzamy piąty plik z karty SD z katalogu głównego. Dlatego warto plikom na karcie SD dać przedrostki w postaci 01,02 itd. U mnie to wygląda tak:
Do generowania komunikatów głosowych użyłem tej strony.
Wgranie programu do arduino
Przed wgraniem należy ściągnąć bilbioteki. Opisałem to tutaj
dodatkowo musimy zianstalować biblioteke DFRobotDFPlayerMini
oraz Adafruit_NeoPixel
Sterowanie
Sterowanie nofikatorem polega na wysyłaniu do niego wiadomośći pięcio bajtowych opis bajtów raz jeszcze:
- pierwszy bajt efekt świetlny dla górnego pierścienia led
- drugi bajt efekt świetlny dla dolnego pierścienia led
- numer pliku mp3 do odtworzenia
- ilość sekund jak długi ma być efekt świetlny i odtwarzane mp3
- czy mp3 ma być odtworzone raz czy w pętli (1 jeżeli ma być odtwarzany w pętli)
Czyli wysyłając bajty:
1 |
07 0F 01 05 01 |
górny pasek będzie udawał policję (mode 6), dolny będzie migał na zielono(mode 15) (patrz funkcja setMode w singleRing.cpp w komentarzach znajduję się opis efektu). Zostanie odtworzony pierwszy plik mp3 z karty, efekt będzie wyświetlany przez 5 sekund, a dźwięk będzie odtworzony w pętli (bo ostatni bajt to 01 – patrz funkcja onUserMessage a arduino.ino)
Wyślijmy zatem te bajty. Logujemy się do aplikacji
Przechodzimy do zakładki devices – nr 1 , 2: status naszego urządzenia powinien być jak na screenie. Klikamy w ikonkę do wysyłania wiadomości – 3
Okienko które się pojawiło służy do wysyłania wiadomości do urządzenia. W polu 1 wybieramy urządzenie które wybieramy jako wysyłające – ponieważ mamy tylko jedno urządzenie wybieramy właśnie je (jest to pole obowiązkowe i nie ma znaczenia, że jest to, to samo urządzenie do którego wysyłamy wiadomość ) W polu 2 podajemy bajty do wysłania ( w czerwonym polu wartość którą wpisaliśmy w 2 będzie reprezentowana jako string) i klikamy przycisk Send.
Po wysłaniu wiadomości nasz notyfikator powinien zareagować wyświetlając odpowiednie efekty świetlne i grając wybrany mp3. Zachęcam do wypróbowania różnych efektów podając jako dwa pierwsze bajty liczby z zakresu 0 – 22 ( patrz opis w funkcji setMode).
Wysyłanie wiadomości korzystając z URLi
Jeżeli chcemy wyświetlić notyfikacje z zewnętrznej aplikacji np z IFTTT potrzebujemy mieć url który zrobi dokładnie to samo co robiliśmy w okienku w poprzednim kroku. remoteme.org udostępnia REST APi. Przechodzimy do niego klikając zakładkę swagger w (ostania po lewej stronie). Wyświetli się strona gdzie widzimy Api dzięki któremu możemy komunikować się z remoteme.org wysyłając zapytanie http.
Strona pozwala również wysłać komunikaty http z poziomy przeglądarki. Kliknjimy przycisk “Try it out” i wyślijmy wiadomość
uzupełnijmy dane jak na screenie powyżej. Po kliknięciu execute wyślemy wiadomość
1 |
070F010501 |
do urządzenia o id 205, jako adresat jest również to samo urządzenie. MessageId przy ustawieniach “No_RENEVAL” jest nie istotne. I kliknijmy Execute.
Notifikator zareaguje identycznie jak w czasie wysyłania wiadomości z poziomu aplikacji.
Po wywołaniu RESTa poniżej znajduje się URL który został wywołany:
skopiujmy go i wklejmy do adresu przeglądarki:
W moim przypadku URL to:
1 |
https://app.remoteme.org/api/*/rest/v1/message/sendUserMessageHexString/205/1/NO_RENEWAL/1/070F010501/ |
Niestety po wylogowaniu z app.remoteme.org, przestaje on działać. Dzieje się tak dlatego, że nie podaliśmy tokenu uwierzytelniającego, a nie jesteśmy już zalogowani. Pobierzmy zatem nasz token (lub wygenerujmy nowy) i wklejmy go do URL’a zamiast gwiazdki
mój token to
1 |
~267_ZxoWtJ)0ph&2c |
więc url wygląda tak:
1 |
https://app.remoteme.org/api/~267_ZxoWtJ)0ph&2c/rest/v1/message/sendUserMessageHexString/205/1/NO_RENEWAL/1/070F010501/ |
Teraz możemy go wywoływać nawet jak jesteśmy niezalogowani. A po jego wywołaniu do naszego urządzenia 205 zostanie wysłana wiadomość
1 |
070F010501 |
Uwaga: Request GET będzie działał prawidłowo , jednak nie jest to sytuacja dla której request GET był zaprojektowany, ładniej użyć requesta PUT, albo POST – są dostępne odpowiednie wersje REST’a do wysyłania wiadomości tymi wywołaniami.
Integracja z IFTTT
Url utworzny w kroku powyżej nadaję się do wykonywania przez aplikacje zewnętrzne. Jak go użyć pokaże na przykładzie IFTTT. I skonfiguruje go tak żeby notyfikator się włączał jak przyjdzie do mnie email (konto gmail).
Zalogujmy się do IFTTT.W iFTTT przechodzimy do zakładki My Applets a następnie New Applet:
Następnie klikamy w “+this”
w polu “Search services” wpisujemy gmail.
A następnie new email in inbox (Możliwe że musimy wybrać konto i pozwolić IFTTT na dostęp).
Po Tych krokach nasz IFTTT powinien wyglądać tak:
teraz klikamy na “+that”
wyszukujemy i wyberamy Webhooks:
następnie “Make a web request”
uzupełniamy URL naszym url z tokenem. Content type to application/json i klikamy “create action” i Finish. Teraz mamy nasz aplet:
Po wysłaniu emaila na wskazane w IFTTT konto, Nasz notyfikator da nam znać (IFTTT dopiero po chwili poinformuje remoteme.org dlatego może upłynąć trochę czasu zanim dostaniemy notyfikacje, u mnie do 1minuty ale zwykle dużo szybciej).
Podsumowanie
W tym kursie pokazałem jak wysłać do naszego arduino wiadomości z zewnętrznych systemów na przykładzie IFTTT. Podobnie integrujemy inne zewnętrzne systemy. To nie koniecznie musi być notyfikator, i nie koniecznie musi to być IFTTT ;), chciałem pokazać na tym przykładzie jak wysyłać wiadomości z zewnętrznych systemów do naszego arduino.
remoteme.org Facebook
Pozdrawiam,
Maciek
Kapitalny projekt i świetny opis! Gratki!
Dzięki :)
Witaj,
ciekawy tekst, łączenie wielu technik – podoba mi się. Sam już raz przymierzałem się do IFTTT dla thingy52, więc poradnik mi się przyda:) Sam tekst do lekkiego przejrzenia – np. raz piszesz o arduino, raz o nodemcu, plik z projektem nazywa się “arduino.ino” ale kod dla ESP:) Proponuję posprzątać.
Daję 5* (mimo drobnego bałaganiarstwa:))
Pozdrawiam,
Arek
dzięki, wieczorem posprzątam ;)
Rewelacja!
Projekt bardzo ciekawy, ale nie wiem czy w erze smartfonow uzyteczny :)
Jak najbardziej, w pracy podpielismy go do systemu “Continous integration” i jak ktos popsuje builda to sie wlacza ;)
Bardzo fajny projekt jak przyjda czesci to sprobuje złożyć.