Spis treści:
Każdy, kto interesuje się elektroniką wcześniej czy później napotyka na tajemniczo brzmiące słowo Arduino. Mimo że początkowo nie kojarzy się ono z niczym szczególnym, to po zapoznaniu się z dostępnymi w internecie informacjami potrafi rozpalić wyobraźnię. Wszakże niemal wszędzie Arduino przedstawiane jest jako świetna platforma dla początkujących elektroników, dzięki której można nauczyć się programowania. Poza tym przeglądając pierwszy lepszy kurs związany z tą platformą, można zauważyć, że charakteryzuje się ona względną prostota i niewielkim nakładem sił osiągnąć można naprawdę zdumiewające efekty.
Sukces Arduino to efekt przede wszystkim prostoty, niskiego progu wejścia i wynikającej z nich późniejszej popularności. Wokół tych pochodzących z Włoch płytek przez lata powstała ogromna i niezwykle zaangażowana społeczność, dzieląca się własnymi doświadczeniami, projektami, ale też napotkanymi problemami, które nie raz potrafią być rozwiązywane kolektywnie. Rozbudowana społeczność to też ogrom dostępności zasobów. Dzięki nim osoby początkujące mogą korzystać z poradników i gotowych bibliotek kodów pozwalających uruchomić nawet najbardziej nietypowy czujnik. W jednym zdaniu można powiedzieć, ze Arduino to prostota i społeczność, dzięki którym z łatwością można zacząć własną przygodę z programowaniem.
Płytek sygnowanych logiem Arduino jest całkiem sporo, a czasy, gdy jedynym powszechnie znanym przedstawicielem tej rodziny było klasyczne UNO, minęły bezpowrotnie. Choć modele wyposażone w procesory AVR są nadal dostępne, to z roku na rok ustępują one konkurencyjnemu ARM. W ten sposób powstała między innymi seria Arduino Nano, której sercem może być dla przykładu RP2040 zaprojektowany przed Raspberry Pi Fundation. Poza tym rozwiązania z dziedziny komunikacji bezprzewodowej oferowane są przez płytki MKR, napędzane chipami ESP oraz LoRa. Na wspomnienie zasługują też urządzenia opisywane jako PRO. Płytki te z założenia dedykowane są do bardziej wymagających aplikacji, a klientem docelowym są inżynierowie i zaawansowani niedzielni majsterkowicze. Gałąź profesjonalnych rozwiązań oferowanych przez Arduino jest cały czas rozwijana, czego efektem jest powstanie między innymi sterownika mikroPLC dedykowanego aplikacją przemysłowym. Jednak opis tego, co by nie mówić ciekawego urządzenia zostawimy sobie na kiedy indziej i zajmiemy się innym przedstawicielem serii PRO, czyli Arduino Nicla Vision.
Kamera na USB czy mikrokontroler?
Arduino Nicla Vision z zewnątrz wygląda dość niepozornie i bez wątpienia można by pomylić je z dostępnymi na rynku niewielkimi modułami kamer. Jednak pozory mylą i na tym niewielkim kawałku laminatu znalazło się całkiem sporo komponentów.
Mózgiem całej konstrukcji jest procesor ARM STM32H747AII6 o dwurdzeniowej budowie Cortex M7/M4 rozpędzający się nawet do 480MHz. Jest to całkiem wydajna jednostka, jak na tak mały moduł. Najbardziej rzucającym się w oczy elementem Nicla Vision jest oczywiście wbudowany moduł kamery GC2145. Jej rozdzielczość to 2Mpx co może wydawać się dość małą wartością, ale jest wystarczająca w klasycznych projektach związanych ze sztuczną inteligencją i analizą obrazu. Bezprzewodowa komunikacja ze światem zewnętrznym realizowana jest poprzez chip LBEE5KL, który wspiera standardy takie jak WIFI i Bluetooth. Poza tym na płytce znalazł się też 6-osiowy moduł IMU LSM6DSOX, czujnik odległości VL53L1CBV0FY, moduł kryptograficzny SE050C2 oraz mikrofon MP34DT05. Wspomnieć trzeba też o dostępnej pamięci, program może zajmować maksymalnie 2MB i korzystać z 1MB RAM, dodatkowo dostępne jest też 16MB nieulotnej pamięci Flash na dodatkowe dane.
Po drugiej stronie laminatu nie znajdziemy zbyt wielu elementów. Umieszczono tutaj gniazdo microUSB służące do zasilania i programowania, złącze dla zewnętrznego akumulatora oraz konektor ESLOV będący rozszerzeniem magistrali I2C.
Nicla Vision jako klasyczne Arduino
Moduł Nicla Vision jest przede wszystkim płytką z rodziny Arduino i może być wykorzystywany właśnie jako klasyczny przedstawiciel tej serii. Poza mnogością elementów na płytce znajdziemy szereg pól lutowniczych, do których przytwierdzić możemy złącza typu goldpin. Wyprowadzeń nie ma zbyt wiele, ale wśród nich znajdziemy podstawowe interfejsy takie jak UART, I2C oraz SPI. Poza tym moduł wspiera dwa wejścia analogowe oraz komunikację JTAG i pracuje w standardzie 3,3V.
Po podłączeniu modułu do komputera i uruchomieniu Arduino IDE program powinien automatycznie rozpoznać podłączoną płytkę. Aby móc z niej korzystać potrzebny będzie odpowiedni zestaw narzędzi, którego pobranie zostanie zaproponowane przez środowisko w odpowiednim komunikacie.
Przy tej okazji warto zwrócić też uwagę na wbudowaną w Nicla Vision diodę LED. Jest to konstrukcja trójkolorowa, która kolorem świecenia informuje o aktualnym stanie modułu. Po pierwszym uruchamianiu powinna ona mrugać na niebiesko. Oznacza to, że uruchomiony został domyślny skrypt Pythona, do którego jeszcze wrócimy. Poza tym półprzewodnik mrugając na zielono informuje, że aktualnie trwa proces programowania, jednak najmniej pożądaną sytuacją jest, gdy wszystkie świecące segmenty będą aktywowane jednocześnie. Wówczas zaobserwujemy kolor biały symbolizujący błąd sprzętowy, co może oznaczać uszkodzenie Arduino.
Wykorzystywanie dwurdzeniowego procesora ARM do klasycznego migania diodą jest swego rodzaju przerostem formy nad treścią, ale jest to idealny sposób, aby sprawdzić, czy z płytką jest wszystko w porządku. Po wgraniu przykładu „blink led” zaobserwować możemy synchronicznie uruchamiany i wyłączany zielony segment trójkolorowej diody. Ta, mimo że sygnalizować może stan płytki, o czym wspomniałem wcześniej jest też podpięta do jednego z jej wyprowadzeń, dzięki czemu możemy nią sterować.
#include //http://librarymanager/All#NTPClient
#include
#include
const char *ssid = "";
const char *password = "";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
timeClient.begin();
}
void loop() {
timeClient.update();
time_t nowEpoch = timeClient.getEpochTime();
struct tm *nowStruct = gmtime(&nowEpoch);
int year = nowStruct->tm_year + 1900;
int day = nowStruct->tm_mday;
Serial.print("Year: ");
Serial.print(year);
Serial.print(" Day: ");
Serial.print(day);
Serial.print(" Time: ");
Serial.println(timeClient.getFormattedTime());
delay(1000);
}
Znacznie ciekawszym sposobem sprawdzenia działania Arduino Nicla Vision, będzie wgranie prostego programu korzystającego z sieci WIFI. Jego zadaniem będzie wyświetlić w monitorze portu szeregowego aktualnego roku, dnia miesiąca oraz czasu, bazując na danych sieciowych. Dla tego programu niezbędna jest biblioteka NTPClient, można ją pobrać najeżdżając kursorem myszy na link obok deklaracji, jednocześnie trzymając klawisz ctrl. Pamiętajcie, aby w kodzie umieścić informacje o odpowiedniej sieci WIFI, ssid – nazwa sieci, password – hasło dostępu.
Po uruchamianiu naszym oczom powinna ukazać się cyklicznie zwracana informacja o roku, dniu i godzinie.
Jeśli po uruchamieniu kodu widoczny jest komunikat „Failed to mount the filesystem containing the WiFi firmware”, należy zaktualizować firmware modułu sieciowego. Robimy to poprzez otwarcie przykładu File > Examples > STM32H747_System > WiFiFirmwareUpdater, proces aktualizacji może potrwać kilka minut, a jego status można obserwować w monitorze portu szeregowego.
Obraz i rozpoznawanie obiektów
Przygotowując ten materiał, umieściłem na moim profilu Instagram krótką ankietę, w której spytałem, który z tematów związanych z Arduino Nicla Vision jest najciekawszy. Zdecydowanym zwycięzcą okazała się klasyfikacja obrazów, co nie jest zbyt wielkim zaskoczeniem, bo w dzisiejszych czasach wszystko, co może być jakkolwiek powiązane ze sztuczną inteligencją, klika się doskonale. Dlatego właśnie w tej części opowiem nieco o możliwościach wbudowanej kamery oraz jej podstawowym uruchamianiu.
Jednak, aby zacząć pracę z kamerą, musimy odpowiednio przygotować płytkę. Pierwszym krokiem będzie wgranie odpowiedniego firmwaru, innymi słowy programu, który znaleźć można w gotowych przykładach File > Examples > STM32H747_System > STM32H747_manageBootloader. Gdy proces programowania zakończy się pomyślnie, należy uruchomić serial monitor i postępować zgodnie z instrukcjami. Cały proces ogranicza się do wysłania pojedynczego znaku „Y”, który oznacza zgodę na aktualizację, ta może nieco potrwać, ale postęp procesu można obserwować z poziomu ekranu komputera.
Kolejnym krokiem jest pobranie oprogramowania OpenMV IDE, dzięki niemu możliwe będzie połączenie się z Nicla Vision i uruchamianie skryptu napisanego w języku MicroPython. Program ten jest darmowy, a jego instalacja dość intuicyjna, dlatego uważam, że nie trzeba tego tematu rozwijać.
Po uruchomieniu programu OpenMV waszym oczom powinien pokazać się obraz podobny do widocznego powyżej. Layout programu możemy podzielić mniej więcej na dwie części, po lewej znajdziemy domyślnie uruchamiany kod, nazwany przez producenta „hello world”. W prawej części znajdziemy okno obrazu z kamery oraz związane z nim wykresy, na ten moment płytka nie jest jeszcze połączona z IDE, dlatego sekcje te są puste.
Jeśli chcemy połączyć Arduino z OpenMV, należy kliknąć widoczne w lewym dolnym rogu przyciski „connect” a następnie „start”.
Przy pierwszym uruchamianiu możemy zostać poproszeni o dodatkową aktualizację oprogramowania Nicla Vision. Zgadzamy się na nią.
Chwilę po połączeniu z modułem Arduino na ekranie powinien pojawić się obraz z kamery, bo takie właśnie zadanie realizuje domyślny program, który jeśli się przyjrzymy, nie jest zbyt skomplikowany. Składa się on z wywołania i inicjalizacji kamery oraz pętli while, która przechwytuje obraz. Poza tym w dolnej części środowiska znaleźć możemy coś takiego jak „terminal szeregowy”, po jego uruchamianiu zobaczymy liczbę klatek na sekundę przechwytywanej transmisji.
Tego typu prosty program dość dobrze obrazuje techniczne możliwości wbudowanej w Nicla Vision kamery. Nadużyciem byłoby stwierdzenie, że obraz jest dobry, jest on według mnie przeciętny, jednak to wystarczy do prostych zastosowań takich jak podstawowa identyfikacja czy wykrywanie większych obiektów.
W przykładach, które znaleźć można w programie, istnieje także kod nazwany jako. Dzięki niemu Arduino będzie mogło wykrywać ludzkie twarze. Jest to jedna z prostszych aplikacji sztucznej inteligencji, którą można z powodzeniem uruchomić na Nicla Vision. W internecie dostępnych jest całkiem sporo świetnie opisanych poradników łączenia Arduino i AI, dlatego nie będę ich powielać, ale zostawię wam ich namiary. W oryginalnej dokumentacji znaleźć możemy projekt, którego zadaniem jest klasyfikacja obrazów. Korzysta on z platformy Edge Impulse, z której pomocą przygotować można nawet własny model, rozpoznający co tylko będziemy chcieli. Poza tym, właśnie na stronie Edge Impulse dostępny jest projekt, który pozwala zliczać zarejestrowane przez obiektyw elementy. Ciekawym zastosowaniem Nicla Vision jest też transmisja obrazu w czasie rzeczywistym na stronę internetową.
Obsługa czujnika odległości
Jak już wspominałem, Arduino Nicla Vision wyposażone jest też w czujnik odległości VL53L1X. Jego wykorzystanie może być ciekawym rozwinięciem projektów AI, zwłaszcza jeśli chcielibyśmy wykrywać obiekty, które znalazły się bezpośrednio przed obiektywem kamery. Jeśli chcemy skorzystać z IMU, wystarczy dodać (z poziomu menedżera bibliotek) bibliotekę „VL53L1X ToF” dostarczaną przez Pololu.
#include "VL53L1X.h"
VL53L1X proximity;
bool blinkState = false;
int reading = 0;
int timeStart = 0;
int blinkTime = 2000;
void setup() {
Serial.begin(115200);
Wire1.begin();
Wire1.setClock(400000); // use 400 kHz I2C
proximity.setBus(&Wire1);
pinMode(LEDB, OUTPUT);
digitalWrite(LEDB, blinkState);
if (!proximity.init()) {
Serial.println("Failed to detect and initialize sensor!");
while (1);
}
proximity.setDistanceMode(VL53L1X::Long);
proximity.setMeasurementTimingBudget(10000);
proximity.startContinuous(10);
}
void loop() {
reading = proximity.read();
Serial.println(reading);
if (millis() - timeStart >= reading) {
digitalWrite(LEDB, blinkState);
timeStart = millis();
blinkState = !blinkState;
}
}
Program obsługujący sensor odległości jest dość krótki i składa się z kilku części. Początkowo definiujemy używane w kodzie zmienne, inicjalizujemy czujnik, magistralę danych oraz wbudowaną diodę LED. W głównej pętli realizowany jest odczyt cyfrowej wartości odległości, który przesyłany jest do komputera oraz na którego podstawie wyznaczany jest stan diody.
Po uruchomieniu tego przykładu można zaobserwować zmieniającą się częstotliwość świecenia diody wraz ze zmniejszającą się odległością obiektu od płytki. Poza tym odległość może być śledzona z poziomu terminala portu szeregowego.
Obsługa wbudowanego mikrofonu
Arduino Nicla Vision poza kamerą i czujnikiem odległości wyposażono również w mikrofon, z którym procesor STM radzi sobie całkiem dobrze. W najprostszej konfiguracji skorzystać możemy z przykładowego programu dedykowanego dla płytek Arduino, do którego nie potrzeba dodatkowych bibliotek.
#include
// default number of output channels
static const char channels = 1;
// default PCM output frequency
static const int frequency = 16000;
// Buffer to read samples into, each sample is 16-bits
short sampleBuffer[512];
// Number of audio samples read
volatile int samplesRead;
// Blinking
bool state = false;
int timeStart = 0;
void setup() {
Serial.begin(9600);
pinMode(LEDB, OUTPUT);
while (!Serial);
// Configure the data receive callback
PDM.onReceive(onPDMdata);
// Optionally set the gain
// Defaults to 20 on the BLE Sense and 24 on the Portenta Vision Shield
// PDM.setGain(30);
// Initialize PDM with:
// - one channel (mono mode)
// - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
// - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shield
if (!PDM.begin(channels, frequency)) {
Serial.println("Failed to start PDM!");
while (1);
}
}
void loop() {
// Wait for samples to be read
if (samplesRead) {
// Print samples to the serial monitor or plotter
for (int i = 0; i sampleBuffer[2]) {
digitalWrite(LEDB, state);
state = !state;
}
}
}
/**
Callback function to process the data from the PDM microphone.
NOTE: This callback is executed as part of an ISR.
Therefore using `Serial` to print messages inside this function isn't supported.
* */
void onPDMdata() {
// Query the number of available bytes
int bytesAvailable = PDM.available();
// Read into the sample buffer
PDM.read(sampleBuffer, bytesAvailable);
// 16-bit, 2 bytes per sample
samplesRead = bytesAvailable / 2;
}
Program bazuje na wbudowanej w IDE bazie funkcji ukrytych w pliku PDM.h i jest dość uniwersalny, ponieważ obsługiwać może jeden lub dwa kanały. Nicla Vision wyposażona została w pojedynczy mikrofon, dlatego korzystamy tylko z jednej linii.
Kod poza zwracaniem wartości zmiennej odpowiadającej poziomowi dźwięku wysterowuje też na jej podstawie wbudowaną diodę LED. Podobnie jak w poprzednim przykładzie jest to niebieska struktura świecąca, która zmienia swój stan zależnie od poziomu dźwięku. Wystarczy, że coś powiesz, a dioda zareaguje w odpowiedni sposób.
Dla kogo jest Nicla Vision?
Mimo że Nicla Vision sygnowane jest logiem serii PRO Arduino, to według mnie jak najbardziej może być wyborem niedzielnych majsterkowiczów. Moduł wyposażony został dość bogato, co jest sporą zaleta, ale jeszcze większą jest łatwość jej obsługi. Producent przygotował całkiem spory zasób wiedzy, dzięki czemu nawet bez większego doświadczenia można z powiedzeniem uruchomić wbudowane w moduł elementy. Poza tym mnogość peryferiów i całkiem wydajny mikrokontroler są zaleta dla profesjonalistów szukających niewielkiego modułu do projektowanego urządzenia, czy chociażby platformy służącej do prototypowania. Dodatkowo wsparcie ze strony środowisk i zasobów związanych ze sztuczną inteligencją sprawia, że Arduino Nicla Vision może być świetnym wyborem na początek przygody z tą częścią technologii.
Źródła:
- https://docs.arduino.cc/tutorials/nicla-vision/user-manual/
Jak oceniasz ten wpis blogowy?
Kliknij gwiazdkę, aby go ocenić!
Średnia ocena: 5 / 5. Liczba głosów: 5
Jak dotąd brak głosów! Bądź pierwszą osobą, która oceni ten wpis.