Dzisiaj śledzimy niebo i to co nad nami lata… A do tego nawet to wyświetlimy!

Wczoraj w nocy bawiłem się w detektywa 😉 Śledziłem samoloty… Czyli nic nielegalnego, można powiedzieć – niestety. 
Łukasz Jokiel z zaprzyjaźnionego bloga opisywał sposób budowy swojego odbiornika ADS-B. Pomysł świetny, czemu nie. Ale kolega (ponownie pozdrowienia dla Macieja), zasugerował mi inny projekt – zdecydowanie prostszy w realizacji.
Postanowiłem dodać kolejny bardzo długi post. Love it or hate it, ale będzie dużo czytania. Wydaje mi się jednak, że czasem nawet warto przejść po raz kolejny pewne zebrane w innych miejscach tematy dla przypomnienia.
Nad moją miejscowością lata dużo samolotów, co często podziwiamy z dzieciakami. Kolejnym gadżetem z serii 'Nie jest mi to do niczego potrzebne, ale warto to zrobić’ jest informacja o przelatujących nad nami samolotach z wykorzystaniem Wemos D1 Mini oraz wyświetlacza OLED SSD1306. Przy okazji nauczymy się wiele rzeczy! Wstyd się przyznać, ale sam kilka tematów robiłem po raz pierwszy w życiu.
W tym wpisie przewiną się między innymi:
– Wemos D1 Mini
– OLED SSD1306
– pakiet Arduino IDE do obsługi Arduino i innych platform
– GitHUB
– ładowanie sketch’y (i co to w ogóle jest)
– kompilacja
– wgrywanie skompilowanego kodu na docelową platformę
Czyli dużo tematów. Gdzie nie sięgniesz tam sprawa zaczyna mieć zawsze jakieś głębokie korzenie 🙂
Efekt finalny będzie wyglądał jak na zdjęciu poniżej:
Oczywiście wiem, że jest FlightRadar24. Trzeba jednak siedzieć z komórką, albo otwartym komputerem, a my będziemy mieli informację na bieżąco wyświetloną na ekranie. No i zrobimy coś sami, dużo się przy okazji ucząc.
Wemos D1 Mini (i jego klony) jest już bardzo popularnym urządzeniem, do tego tanim. 
2-3 dolary za platformę:
– opartą o ESP-8266, 
– kompatybilną z Arduino, NodeMCU, MicroPython, 
– posiadającą WiFi i 
– posiadającą dużą bazę 'shieldów’ (czyli 'nakładek’ rozszerzających funkcjonalność) 
jest ceną naprawdę niską, nawet dla samej zabawy i poznania nowych możliwości.
Wyświetlacz to już kwestia 20 PLN, to również jednak moim zdaniem nie jest wielką barierą.
Zaczniemy od czegoś prostszego – wyświetlimy tekst na ekranie.
Podłączamy jak poniżej:
 
Jak widać, jest to banalnie proste:
GND -> GND
VCC -> 3.3V
SCL -> D1
SDA -> D2 
I to tyle jeżeli chodzi o Hardware. Super!
Przechodzimy do oprogramowania. Zaczynamy od Arduino IDE: https://www.arduino.cc/en/Main/Software. Alternatywą jest PlatformIO, nawet w przypadku tego projektu jest to ciut prostsze, ale skupmy się na ten moment na Arduino IDE.
Po pierwsze podłączamy D1 Mini to komputera. I teraz UWAGA – już kilka razy przekonałem, się, że dużo zależy od kabla USB -> Micro USB. Ileż razy kląłem, gdy sprzęt nie chciał się pojawić na liście, a wystarczyło wymienić kabel na porządny. Gdy już pojawi się nam nowy port COM, wypełniamy w sekcji Tools w Arduino IDE następujące parametry:

Chcemy połączyć się z ekranem OLED, a do tego będą nam potrzebne dodatkowe biblioteki. Przechodzimy do Sketch -> Include Library -> Manage Libraries.

Wyszukujemy dwie z pakietu Adafruit:
– Adafruit GFX
– Adafruit SSD1306
wybieramy je i instalujemy. Opcja będzie dostępna po ich zaznaczeniu.

Świetnie, brawo! Jesteśmy gotowi.
Czym jest sketch? Niczym więcej jak programem, który musimy napisać, później skompilować na język maszynowy i wgrać do naszego modułu.
Otwórzcie nowy plik i wklejcie poniższe. Nie wgłębiamy się w każdą z bibliotek, bo to mogłoby nam zająć miesiące ;), na ten moment wykorzystamy tylko to, czego potrzebujemy.

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 0  // GPIO0
Adafruit_SSD1306 OLED(OLED_RESET);

void setup()   {
  OLED.begin();
  OLED.clearDisplay();

  //Dodajemy elementy do 'display listy’
  OLED.setTextWrap(false);
  OLED.setTextSize(1);
  OLED.setTextColor(WHITE);
  OLED.setCursor(0,0);
  OLED.println(„Cezarowy blogspot”);

  OLED.display(); //wyświetl zawartość pamięci ekranu na ekran 
  OLED.startscrollleft(0x00, 0x0F); //make display scroll 

void loop() {
}

Można wybrać Verify/Compile, co wyłącznie skompiluje nasz program, można od razu Upload, co wymusi kompilację i załaduje skompilowany sketch do D1 Mini.

Cierpliwie czekamy na zakończenie kompilacji…
I załadowanie programu do D1 Mini…
I od razu efekt!

Skoro proste tematy mamy za sobą, ruszamy od razu z czymś trudniejszym. A co! Do odważnych świat należy!

Po pierwsze, kolejne dwie biblioteki do pobrania. WiFiManager i biblioteka do parsowania (czyli czytania i przetwarzania) plików JSON.

Od razu piszę, że pomysł i kod nie jest mój, dostosowałem znaleziony przez Macieja kod do swoich potrzeb.

Zacznijmy od tego, że skorzystaliśmy z biblioteki Weather Station opracowanej przez zespół ThingPulse. W ramach dostępnych w niej przykładów znajduje się kod PlaneSpotterDemo, który przerobimy na nasze potrzeby.

Ze strony https://github.com/ThingPulse/esp8266-weather-station pobieramy ZIP z biblioteką, którą trzeba rozpakować do folderu jak poniżej.

Restart Arduino IDE i już mamy w Examples dostępny kod PlaneSpotterDemo.

U mnie potrzebny był 'delikatny’ tuning.

W parametrach wywołania strony, która pokazuje JSON trzeba podać promień okręgu jaki mamy sprawdzać, oraz jeżeli chcecie – wysokość graniczną samolotów Od/Do.

Przy okazji dowiecie się jak wyglądają pliki JSON, które można później obrabiać, czytać i zapisywać na przykład w Domoticz.

Na przykład:
https://public-api.adsbexchange.com/VirtualRadar/AircraftList.json?lat=LATZDomoticz&lng=LongZDomoticz&fDstL=0&fDstU=12, gdzie fDstL i fDstU oznacza odległość Od/Do jaka nas interesuje.

Kolejny: fDstL=0&fDstU=12&fAltL=5000&fAltU=45000 interesują nas samoloty, które są w odległości od zera do 12 kilometrów, na wysokości od 5 do 45 tysięcy stóp.

Aby zobaczyć co lata obok lotniska na Balicach, wystarczy sprawdzić adres: https://public-api.adsbexchange.com/VirtualRadar/AircraftList.json?lat=50.0769780&lng=19.7881190&fDstL=0&fDstU=100

W ogóle – nazwy parametrów to jak widać fDst, L oraz U oznacza limit dolny oraz górny, S – zaczynający się od – jeżeli szukacie konkretnych modeli samolotów. Itd., itp. Dokładna dokumentacja wszystkich parametrów znajduje się pod adresem: http://www.virtualradarserver.co.uk/Documentation/Formats/AircraftList.aspx

Aplikacja o której tutaj mówimy pobiera właśnie dane z tej strony, przetwarza je, zapisuje w odpowiednich zmiennych i wyświetla na ekranie OLED.

Aby być pewnym, że moje parametry są poprawne, uruchamiam na jednym ekranie https://global.adsbexchange.com/VirtualRadar/desktop.html z moją okolicą, na drugim odświeżam wyniki https://public-api.adsbexchange.com/VirtualRadar/AircraftList.json?lat=50.0769780&lng=19.7881190&fDstL=0&fDstU=100 (podajecie oczywiście swoje współrzędne). Wtedy wiem, że to co mam na mapie pokrywa się z tym, co zawierają dane w formacie JSON.

Aby program zadziałał musimy prowadzić kilka zmian.

Po pierwsze, mam ekran SSD1306, także usuwam komentarz (czyli //) z jednej linii i komentuję tą z SH1106.

#include „SSD1306Wire.h”
//#include „SH1106Wire.h”

const String QUERY_STRING = „lat=LatZDomoticz&lng=19.562571&fDstL=0&fDstU=12”;

Autor podłącza piny trochę inaczej niż ja, również musiałem to zmienić.

//const int SDA_PIN = D3;
//const int SDC_PIN = D4;
const int SDA_PIN = D2;
const int SDC_PIN = D1;
SSD1306Wire     display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);
//SH1106Wire      display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);
Autor korzysta z biblioteki WiFiManager i stara się automatycznie podłączyć do dostępnej, otwartej, sieci. Ja musiałem się podłączyć do swojej, opatrzyłem więc komentarzem następujące linie i podałem w funkcji WiFi.begin swoje dane sieci – nazwę i hasło.

//  WiFiManager wifiManager;
// Uncomment for testing wifi manager
//wifiManager.resetSettings();
//  wifiManager.setAPCallback(configModeCallback);
//or use this for auto generated name ESP + ChipID
//  wifiManager.autoConnect();
//Manual Wifi
  WiFi.begin(„WiFiID”, „Password”);
//  String hostname(HOSTNAME);
//  hostname += String(ESP.getChipId(), HEX);
//  WiFi.hostname(hostname);

  // Setup OTA
//  Serial.println(„Hostname: ” + hostname);
//  ArduinoOTA.setHostname((const char *)hostname.c_str());
//  ArduinoOTA.onProgress(drawOtaProgress);
//  ArduinoOTA.begin();

Kompilacja powinna przejść bez problemu, ładowanie identycznie jak w przypadku pierwszego przykładu również.

TADAM! Mamy, działa, pokazuje!

Tak w sumie posiadając ekran otwierają się przed nami nowe możliwości eksperymentowania – z samych przykładów można się mnóstwo nauczyć i robić swoje małe (albo i duże) projekty.

Postaram się rozszerzyć ten wpis o kolejny, w którym dane wylądują w Domoticz, ale tak prawdę mówiąc, to muszę się tego najpierw sam nauczyć 😀

Powodzenia! Pozdrawiam serdecznie!

1 komentarz do “Dzisiaj śledzimy niebo i to co nad nami lata… A do tego nawet to wyświetlimy!”

  1. — 'Aircrafts' – nazwa dummy text
    — 'xxxx' w apiUrl – tu wstaw współrzędne, które Cię interesują
    — 'fDstU' 'fDstU' minimalna i maksymalna odległość od podanych współrzędnch

    — skrypt odpala się co minutę, mnie interesowała trochę większa częstotliwość stąd:
    — domoticz.openURL({ url = apiUrl, method = apiMethod, callback = apiCallback }).afterSec(15) — i kolejne
    — if(gnd == false) to warunek na samoloty, które są w powietrzu

    return {
    on = {
    timer = { 'every minute' },
    httpResponses = { 'aircraftsRetrieved' }
    },
    execute = function(domoticz, item)
    if (item.isTimer) then
    local apiUrl = 'https://public-api.adsbexchange.com/VirtualRadar/AircraftList.json?lat=xxxx&lng=xxxx&fDstL=0&fDstU=1&#39;
    local apiMethod = 'GET'
    local apiCallback = 'aircraftsRetrieved'
    domoticz.openURL({ url = apiUrl, method = apiMethod, callback = apiCallback })
    domoticz.openURL({ url = apiUrl, method = apiMethod, callback = apiCallback }).afterSec(15)
    domoticz.openURL({ url = apiUrl, method = apiMethod, callback = apiCallback }).afterSec(30)
    domoticz.openURL({ url = apiUrl, method = apiMethod, callback = apiCallback }).afterSec(45)
    elseif (item.isHTTPResponse) then
    local textArea = domoticz.devices('Aircrafts')
    local cnt = 0
    local caption = ''
    if (item.ok) then
    local json = domoticz.utils.fromJSON(item.data)
    for i, ac in pairs(json.acList) do
    local gnd = ac.Gnd and ac.Gnd or false
    if(gnd == false) then
    cnt = cnt + 1
    local mdl = ac.Mdl and ac.Mdl or '-' –model
    local from = ac.From and ac.From or '-'
    local to = ac.To and ac.To or '-'
    local op = ac.Op and ac.Op or '-' –operator
    local call = ac.Call and ac.Call or '-' –call name
    local dst = ac.Dst and ac.Dst or '-' –distance
    local alt = ac.Alt and domoticz.utils.round(ac.Alt * 0.3048) or '-' –altitude
    local spd = ac.Spd and domoticz.utils.round(ac.Spd * 1.852,0) or '-' –speed
    caption = caption..'Aircraft: '..mdl..'nFrom: '..from..'nTo: '..to..'nOper: '..op..'nCall: '..call..'nDist: '..dst..' km'..'nAlt: '..alt..' km'..'nSpeed: '..spd..' km/h'..'nn'
    end
    end
    if(cnt == 0) then
    caption = '-'
    end
    else
    caption = '?'
    end
    if(not(textArea.text == caption)) then
    textArea.updateText(caption)
    end
    end
    end
    }

    Odpowiedz

Dodaj komentarz