wtorek, 9 maja 2017

ESP32 - Konfiguracja środowiska

Co będzie nam potrzebne

Najpierw trzeba sobie przygotować środowisko w którym będziemy pisać i kompilować oprogramowanie. Potrzebne nam będzie:

  • komputer PC z dowolnym systemem operacyjnym: Windows, Linux lub Mac. Ja będę używał Windowsa ale poza Toolchainem reszta powinna wyglądać identycznie na każdym systemie.
  • Toolchain do kompilacji aplikacji na ESP32. Toolchain to w uproszczeniu kross-kompilator i biblioteka standardowa C
  • ESP-IDF który zasadniczo zawiera API dla ESP32 i skrypty do obsługi Toolchaina
  • Edytor tekstowy  do pisania programów w C np. Eclipse, Notepad++, Visual Studio Code albo cokolwiek w czym lubisz pisać
  • no i oczywiście moduł ESP32. Ja będę używał ESP‑DevKitC, który ma na pokładzie ESP-WROOM-32, przyciski do resetu i wgrywania firmware'u, interfejs USB i wyprowadzone większość pinów. Przyda się również kabel microUSB.


Konfiguracja Toolchaina

Przygotować Toolchain można sobie na dwa sposoby. Najszybszym i najprostszym sposobem na rozpoczęcie pracy z ESP32 jest zainstalowanie gotowego Toolchaina. 
Zamiast pobierać binarny toolchain z witryny Espressif, możesz samodzielnie zbudować narzędzie.
Jeśli nie przychodzą Ci do głowy powody, dla których musisz go samodzielnie zbudować, prawdopodobnie lepiej jest trzymać się wersji binarnej. Oto niektóre z przyczyn, dla których warto skompilować toolchain ze źródła:
  • chcesz użyć innej wersji GCC (np. 7.1)
  • chcesz użyć jakiejś alternatywy dla newlib np. newlib-nano
  • jesteś ciekawy i / lub masz dużo wolnego czasu
  • nie masz zaufania do plików binarnych pobranych z Internetu
Ja wybieram opcję pierwszą i pobieram toolchain ze strony Espressif: https://dl.espressif.com/dl/esp32_win32_msys2_environment_and_toolchain-20170330.zip a następnie rozpakowuję na dysku D. Po rozpakowaniu w katalogu d:/msys32 możesz uruchomić terminal mingw32.exe.


Pobranie ESP-IDF

Oprócz toolchaina potrzebne są nam również biblioteki/API do ESP32. Są one udostępniane przez Espressif w repozytorum na githubie https://github.com/espressif/esp-idf . Użyjemy je i w tym celu tworzymy otwieramy terminal, tworzymy katalog w którym chcemy umieścić ESP-IDF, przechodzimy do niego i robimy klona za pomocą polecenie git clone:
mkdir ~/esp
cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git

Toolchain potrzebuje dostępu do ESP-IDF, bo w przeciwnym razie projekty nie będą się budować. Aby wskazać gdzie ESP-IDF się znajduje należy ustawić zmienną środowiskową IDF_PATH. Można to robić ręcznie po każdym uruchomieniu komputera lub na trwałe ustawić to w profilu użytkownika. W tym celu w katalogu D:\msys32\etc\profile.d tworzymy nowy skrypt o nazwie export_idf_path.sh w którym umieszczamy:

export IDF_PATH="D:/msys32/home/Mateusz/esp/esp-idf"

Oczywiście ścieżkę trzeba odpowiednio zmodyfikować, bo nie każdy ma na imię Mateusz ;)
Teraz zapisujemy plik, zamykamy konsolę i ponownie otwieramy. Aby sprawdzić czy wszystko poszło ok, wklepujemy: printenv IDF_PATH Powinniśmy dostać coś takiego:

Zasadniczo już teraz mamy przygotowane całe środowisko do zabawy z ESP32. Sprawdźmy teraz czy jesteśmy w stanie skompilować jakiś przykład i wgrać do ESP-DevKitC


Hello world!

Skopiujmy sobie przykład hello_world dostarczony przez Espresiff do nowego katalogu:

cd ~/esp/
cp -r $IDF_PATH/examples/get-started/hello_world .

Zauważ, że na końcu drugiego polecenia jest kropka, która oznacza: "skopiuj do katalogu w którym jestem".

Teraz potrzebna nam będzie informacja pod jakim numerem portu COM pojawia się moduł. Podłączamy więc moduł do komputera i sprawdzamy w menadżerze urządzeń:
W moim przypadku jest to port COM4 - trzeba tę informację zapamiętać.
Przejdźmy teraz do katalogu z projektem i go skonfigurujmy:

cd ~/esp/hello_world 
make menuconfig

Po chwili pokaże się menu znajome każdemu kto próbował kiedykolwiek zmienić coś w jądrze Linuksa. 

Przechodzimy do Serial flasher config > Default serial port i ustawiamy odpowiednio port, po czym wychodzimy i na końcu zapisujemy.

Teraz pozostało nam jedynie skompilować projekt i wgrać do urządzenia. Można to zrobić jednym poleceniem:

make flash

Jeśli wszystko pójdzie dobrze na końcu powinieneś zobaczyć coś takiego:

Przykład, który wgraliśmy wysyła Hello world! na konsolę i po chwili się resetuje. Możemy to podejrzeć w dowolnym terminalem np Putty (baudrate 115200) lub za pomocą wbudowanych narzędzi w ESP-IDF:

make monitor


No to tyle na dzisiaj. Następnym razem odpalimy GPIO, podłączymy LED i może jakiś switch i spróbujemy to oprogramować.

niedziela, 7 maja 2017

Wznawiam działalność bloga. Parę słów o ESP32

Minęły ponad 3 lata od ostatniego wpisu, więc zostały przekroczone wszelkie możliwe timeouty. Czas zatem na reaktywację. Impulsem do tego są dary, które zamówione od naszych żółtych braci właśnie dotarły.
Post udostępniony przez Mateusz Klatecki (@kltcki)
Jakiś czas temu zamówiłem moduły ESP-WROOM-32 oraz ESP-DevKitC żeby ułatwić sobie prototypowanie.
Cena modułów ESP-WROOM-32 jest stosunkowo niewielka ok. $5 jeśli zamówi się w Chinach.  W Polsce można znaleźć poniżej 30zł. A możliwości takiej kosteczki o rozmiarach 18x25 mm są naprawdę duże. Na pokładzie znajdziemy m.in. :

  • dwurdzeniowy MCU taktowany zegarem do 240MHz
  • Wi-Fi z wbudowaną anteną na PCB
  • Bluetooth 4.2 i BLE
  • 448 kB wewnętrznej pamięci Flash i 4 MB zewnętrznej
  • 520 kB wewnętrznej pamięci SRAM
  • wbudowany czujnik temperatury i Halla
  • RTC (potrzebny zewnętrzny kwarc)
  • i 32 wyprowadzenia GPIO ze sporą ilością interfejsów:
    • 3x UART
    • 3x SPI
    • 2x I2C 
    • 2x I2S
    • 2x 12-bitowy przetwornik ADC z sukcesywną aproksymacją
    • 2x 8-bitowy przetwornik DAC
    • Wyjścia PWM
    • Interfejs kart SD
Ważną rzeczą jest również to, że moduły mają certyfikaty: FCC, CE, IC, TELEC, SRRC & KCC, dzięki czemu wprowadzenie komercyjnego produktu na rynek będzie dużo łatwiejsze.

Pomysłów na wykorzystanie tego modułu mam w głowie kilka a proces poznawania modułu i odpalania poszczególnych peryferiów postanowiłem uwiecznić na blogu. So, stay tuned :)

piątek, 4 października 2013

Unikanie błędów programując w C - #3 Operacje bitowe na liczbach ze znakiem


Nie należy używać operacji bitowych ( &, |, ~, ^, << i >> ) na liczbach ze znakiem.

    // Nie rób tego ...
    int8_t  signed_data = -4;
    signed_data >>= 1;  // niekoniecznie -2


Standard C nie definiuje formatu danych liczb ze znakiem (na przykład U2 - uzupełnień do dwóch) i efekt niektórych operacji bitowych zależy od zastosowanej przez autora kompilatora implementacji zapisu takich liczb.

niedziela, 15 września 2013

Liczenie pola powierzchni wielokąta nieforemnego

Ostatnio musiałem napisać funkcję, która liczy pole powierzchni dowolnego wielokąta nieforemnego na podstawie współrzędnych wierzchołków. Straciłem trochę czasu na znalezienie prostego i uniwersalnego algorytmu, więc podzielę się moim znaleziskiem.

Jest to metoda analityczna obliczania pola powierzchni ze współrzędnych wzorami Gaussa.
Metoda analityczna bazuje na punktach o znanych współrzędnych. Do wyznaczenia pola powierzchni wzorami Gaussa musimy znać współrzędne wierzchołków wielokąta.

Pole P wieloboku obliczamy ze wzoru (wystarczy jeden - oba dają ten sam wynik) Gaussa:
 P = \frac{1}{2}\left| \sum\limits_{i=1}^n {X_i(Y_{i+1}-Y_{i-1}})\right| = \frac{1}{2}\left| \sum\limits_{i=1}^n {Y_i(X_{i-1}-X_{i+1}})\right|

gdzie: 
P - to wyliczane pole powierzchni
n -to liczba wierzchołków wielokąta
i = to współrzędne i-tego wierzchołka (wierzchołki numerowane są kolejno od 1 do n, poczynając od dowolnego z nich).

zakłada się przy tym, że:
X_0=X_n, Y_0=Y_n\;
X_{n+1}=X_1, Y_{n+1}=Y_1\;

Wartość bezwzględna we wzorze jest konieczna, gdyż przy zmianie kierunku numeracji wierzchołków wielokąta, zmienia się znak sum po prawej stronie. Ponadto sumy te mają zawsze przeciwne znaki.

I na koniec przykład implementacji w języku C:

#include <stdio.h>

typedef struct {
    int x;
    int y;
} point_t;

double liczPow(point_t *punkty, size_t N){
    size_t i;
    double pow;
    for (i=0;i<N;i++){
        if (i==0) {
            pow += punkty[i].x*(punkty[N-1].y-punkty[i+1].y);
        } else if (i==(N-1)){
            pow += punkty[i].x*(punkty[i-1].y-punkty[0].y);
        } else {
            pow += punkty[i].x*(punkty[i-1].y-punkty[i+1].y);
        }
    }

    if (pow < 0){
        pow = -pow;
    }

    pow /= 2;
    return pow;
}

int main(void) {
    point_t punkty[] = {
        {2,1},
        {5,2},
        {7,5},
        {4,7}
    };

    int N = sizeof(punkty)/sizeof(point_t);

    double powierzchnia = liczPow(punkty,N);

    printf("Powierzchnia: %f\n",powierzchnia);

    return 0;

}

Unikanie błędów programując w C - #2 Makra vs funkcje inline

Nie używaj makr parametryzowanych (makrodefinicji) jeśli można napisać funkcję inline, która wykona to samo zadanie.

//Nie rób tak:
#define MAX(A,B) ((A) > (B) ? (A) : (B))
// jeśli możesz zrobić tak:
inline int max(int a, int b)

Powód: Przy używaniu dyrektywy preprocesora #define jest dużo związanych z nią zagrożeń a w szczególności gdy są to makra parametryzowalne. Ważne jest odpowiednie (najczęściej w dużej ilości) użycie nawiasów (tak jak w przykładzie powyżej), ale nie wyeliminuje przypadkowego użycia inkrementacji jak np. MAX(i++,j++), która zwiększy zmienne o 2 zamiast o 1 jak to na pierwszy rzut oka wygląda.
Inne ryzyko nadużycia makr to porównanie liczb ze znakiem i bez (wspominałem o tym w poprzednim odcinku) lub jakiekolwiek porównania z liczbami zmiennoprzecinkowymi.

środa, 11 września 2013

Unikanie błędów programując w C - #1 liczby całkowite ze znakiem i bez

Postanowiłem napisać cykl krótkich artykułów (a właściwie porad) dla osób, które zaczynają programować systemy wbudowane w języku C. Skłonił mnie do tego sposób w jaki piszą studenci, którzy odbywają praktyki (lub dorabiają sobie) u nas w firmie. Ich kod jest mało czytelny, zajmuje dużo miejsca po skompilowaniu i zawiera dużo błędów, które nie ujawniają się od razu ale dopiero np. po włączeniu optymalizacji, dopisaniu kolejnego fragmentu kodu lub w losowych momentach.

Na pierwszy ogień idą liczby całkowite ze znakiem i bez.

Liczby całkowite ze znakiem nie powinny być używane z liczbami całkowitymi bez znaku w porównaniach lub innych wyrażeniach.

//Nie rób tego...
uint8_t a = 6u;
int8_t b = -9;

if (a + b < 4) {
    //program powinien iść tą prawidłową ścieżką
    //bo -9 + 6 = -3 < 4
} else {
    //ale wykona się ten fragment ponieważ 
    // -9 + 6 stanie się dla kompilatora
    // (256 - 9) + 6 = 253.
    // 247 (bez znaku) == -9 ze znakiem
}

Powyższy program skompilowany i uruchomiony na 8-bitowym AVR wykona się tak jak opisałem w komentarzach. Co ciekawe jeśli skompilujesz ten kod u siebie na komputerze to wykona się poprawnie (zgodnie z przewidywaniami). Dzieje się to dlatego, że pracujesz na 32 lub 64 bitowym procesorze i rejestry mają taką długość. Zmień jednak typ zmiennych na np. uint32_t i int32_t a zadziała jak na AVR :)

niedziela, 24 lutego 2013

Projekty anten na PCB

Zestaw anten na różne częstotliwości (2.4GHz, 868 / 915 / 920 MHz, 433 MHz, 315 MHz, 136 - 240 MHz), o różnych rozmiarach i pasmach do wykonania na PCB od Texas Instruments http://www.ti.com/lit/an/swra351a/swra351a.pdf