ADuCino360: akcelerometryczny, cyfrowy miernik refleksu z ADuCM360 (Cortex-M3 z Analog Devices)
ADuCino to płytka ewaluacyjna z mikrokontrolerem ADuCM360, za pomocą której można nie tylko dogłębnie poznać ten interesujący układ, ale także wykonać wiele ciekawych eksperymentów, a nawet zastosować w rozmaitych aplikacjach. W artykule opisano konstrukcję prostego miernika czasu reakcji (refleksu), wykorzystującego m.in. montowany na płytce akcelerometr MEMS 3-osiowy.
Prezentowany zestaw pomiarowy miernika refleksu składa się z płytki ADuCino, modułu wyświetlacza LCD KAmodTFT2 i… dowolnego kijka o długości co najmniej 1 metra, np. od mopa lub szczotki. W przykładowym oprogramowaniu uwzględniono dwie metody pomiarowe. W każdej z nich, do pomiaru czasu wykorzystywany jest timer TIM1 mikrokontrolera ADuCM360. Analizując udostępniony kod źródłowy programu Czytelnik będzie mógł zapoznać się m.in. z obsługą tego bloku peryferyjnego.
Przygotowanie stanowiska pomiarowego
Przed rozpoczęciem pomiarów należy dołączyć moduł wyświetlacza KamodTFT2 do płytki ADuCino zgodnie ze schematem przedstawionym na rys. 1. Procesor komunikuje się z wykorzystywanymi w przyrządzie blokami peryferyjnymi (wyświetlacz i akcelerometr) za pośrednictwem interfejsu SPI. Linie tego interfejsu są dostępne dla urządzeń zewnętrznych (wyświetlacz) na gnieździe „SPI” z wyprowadzeniami szpilkowymi. Akcelerometr jest montowany bezpośrednio na płytce, połączenia z mikrokontrolerem zapewniają więc ścieżki obwodu drukowanego. W projekcie przyjęto, że sygnał CS wyboru wyświetlacza pochodzi z portu P0.1 mikrokontrolera. Linia ta jest wyprowadzona na odpowiedni pin łączówki J1.
Rys. 1. Schemat połączeń płytki ADuCino z modułem wyświetlacza KAmodTFT2
Płytka ADuCino jest zasilana napięciem +5 V z gniazda USB. Podczas pomiarów nie jest wymagane połączenie jej z komputerem, gdyż wszystkie funkcje pomiarowe są wykonywane wyłącznie przez mikrokontroler ADuCM360. Jeśli użytkownik dysponuje zasilaczem +5 V z wtyczką USB, może z niego korzystać, jeśli nie, płytkę ADuCino można dołączyć do gniazda USB komputera. Ze względu na wymagania związane z pomiarem akcelerometrycznym zalecane jest stosowanie jak najdłuższego kabla USB (minimum 1 m). Pozostałe czynności związane z przygotowaniem stanowiska dla pomiaru akcelerometrycznego omówiono w dalszej części artykułu.
Pomiar czasu reakcji z zastosowaniem przycisku P2.2
Po włączeniu zasilania płytki ADuCino lub po wyzerowaniu mikrokontrolera, na wyświetlaczu przez kilka sekund wyświetlana jest winietka programu, po czym wykonywana jest prosta animacja polegająca na przesuwaniu napisu widocznego w dolnej części ekranu. Tryb pracy przyrządu zależy od tego czy w chwili wysuwania ostatniej litery napisu będzie wciśnięty przycisk P2.2 czy nie. Naciśnięcie przycisku spowoduje wejście w opisywany tryb pomiarowy. Na ekranie pojawi się napis „Przygotuj się…”, wyświetlany aż do momentu zwolnienia przycisku. Gdy to nastąpi, po chwili zostaje wyświetlony napis „S T A R T !” oznaczający, że został uruchomiony timer odmierzający czas. Osoba badana powinna jak najszybciej nacisnąć przycisk P2.2, co spowoduje zatrzymanie timera i wyświetlenie zmierzonego przez niego czasu odpowiadającego czasowi reakcji (fot. 2).
Fot. 2. Wynik pomiaru czasu reakcji
Przed automatycznym wznowieniem pomiaru na wyświetlaczu ponownie pojawia się napis „Przygotuj się…”, który jest zastępowany napisem „S T A R T !” w chwili uruchomienia kolejnego pomiaru czasu. Procedura ta działa w pętli. Naciśnięcie przycisku przed rozpoczęciem pomiaru czasu jest traktowane jako falstart, o czym informuje napis „ZA WCZEŚNIE!” wyświetlony na czerwonym ekranie. Po chwili procedura pomiarowa jest wznawiana automatycznie. Z kolei zbyt późne (32 sekundy) naciśnięcie przycisku powoduje wyświetlenie napisu „Przekroczony zakres”. I w tym przypadku procedura jest wznawiana automatycznie. Na list. 1 przedstawiono fragment programu odpowiedzialnego za inicjalizację systemu, w tym za konfigurację timera TIM1 odmierzającego czas. Użyte w nim stałe zadeklarowano w plikach *.h.
List. 1. Konfiguracja systemu
//konfiguracja zegarow ClkCfg(CLK_CD0,CLK_HF,CLKSYSDIV_DIV2EN_DIS,CLK_UCLKCG); //system 16MHz ClkSel(CLK_CD1,CLK_CD0,CLK_CD7,CLK_CD7); //SPI: 4MHz, I2C: 16MHz, UART: - (125kHz), PWM: - (125kHz) ClkDis(CLKDIS_DISSPI1CLK|CLKDIS_DISUARTCLK|CLKDIS_DISPWMCLK|CLKDIS_DIST0CLK|CLKDIS_DISDACCLK|CLKDIS_DISDMACLK|CLKDIS_DISADCCLK); //blokuj niewykorzystywane //Konfiguracja SPI0 SpiBaud(pADI_SPI0,0,SPIDIV_BCRST_DIS); //8MHz bez detekcji bledu linii CS SpiCfg(pADI_SPI0,SPICON_MOD_TX1RX1,SPICON_MASEN_EN,SPICON_CON_EN| SPICON_RXOF_EN|SPICON_ZEN_EN|SPICON_TIM_TXWR|SPICON_CPOL_HIGH|SPICON_CPHA_SAMPLETRAILING|SPICON_ENABLE_EN); //przerwanie po 1 wpisie do TX, tryb master, tryb ciagly //zezwolenie na nadmpisanie RX, transmituj 00 jesli brak nowych danych w TX //inicjalizacja transmisji po wpisie do TX, probkowanie na opadajacym zboczu SCLK //SPI0 wlaczone //Konfiguracja timera1 wykorzystywanego do pomiaru czasu reakcji GptLd(pADI_TM1,0); GptCfg(pADI_TM1,TCON_CLK_LFOSC,TCON_PRE_DIV16,TCON_MOD_FREERUN|TCON_UP|TCON_RLD|TCON_ENABLE_DIS); //T1: Up, LFOSC/16, Free run
Źródłem przebiegu taktującego timer TIM1 jest wewnętrzny generator 32768 Hz wybierany opcją TCON_CLK_LFOSC, z włączonym preskalerem dzielącym tę częstotliwość przez 16 (opcja TCON_PRE_DIV16). W ten sposób uzyskano rozdzielczość pomiaru czasu równą 0,488 ms i maksymalny zakres pomiaru czasu równy 32 s. Po tym czasie 16-bitowy licznik przekręca się, generując przerwanie. Jest ono wykorzystywane do wyświetlenia komunikatu o przekroczeniu zakresu pomiarowego. Timer TIM1 liczy w górę pracując w trybie Reload umożliwiającym wpisywanie dowolnego stanu początkowego. W mierniku refleksu wartością początkową jest 0. Wpis do rejestru timera jest możliwy tylko wtedy, gdy licznik nie zlicza. Sekwencję rozkazów zerujących timer przedstawiono na list. 2. Zastosowano funkcje biblioteczne dla mikrokontrolera ADuCM360 dostępne w środowisku mVision wykorzystywanym do uruchomiania projektu.
List 2. Sekwencja rozkazów zerujących timer TIM1
GptCfg(pADI_TM1,TCON_CLK_LFOSC,TCON_PRE_DIV16,TCON_MOD_FREERUN|TCON_UP|TCON_RLD|TCON_ENABLE_DIS); //zatrzymaj timer GptLd(pADI_TM1,0); //wpisz zero do rejestu timera ... ... GptCfg(pADI_TM1,TCON_CLK_LFOSC,TCON_PRE_DIV16,TCON_MOD_FREERUN|TCON_UP|TCON_RLD|TCON_ENABLE); //uruchomienie zliczania z nowym stanem początkowym
Pomiar czasu reakcji z zastosowaniem akcelerometru
Uruchomienie przyrządu bez naciskania przycisku w chwili wyświetlania winietki powoduje wejście w tryb pomiaru wykorzystującego akcelerometr ADXL362 montowany standardowo na płytce ADuCino. Już teraz można domyślić się, że pomiar będzie związany z ruchem płytki ADuCino. Dokładniej będzie to spadek swobodny. Do tego eksperymentu konieczne będzie umocowanie płytki ADuCino wraz z wyświetlaczem do jakiegoś kijka. Czytelnik może zastosować własne rozwiązanie tego problemu. Obie płytki powinny być przymocowane do dolnej części kijka. Należy zapewnić taką orientację płytki ADuCino, by gniazda SPI i USB znajdowały się u góry (fot. 3). Nie jest przy tym wymagana szczególna precyzja montowania. Odchylenie płytki w dowolną stronę nie będzie miało wpływu na wyniki pomiarów.
Fot. 3. Akcelerometryczny miernik pomiaru czasu reakcji z płytką ADuCino przygotowany do pracy
Jak działa taki przyrząd? W eksperymencie biorą udział dwie osoby: badający i badany. Badający trzyma wysoko kijek w górnym jego końcu pozwalając na swobodne przyjęcie orientacji pionowej. Osoba badana obejmuje dłonią kijek najlepiej tuż nad przymocowaną do niego płytką ADuCino, lecz nie ściska go, zachowując gotowość do szybkiego uchwycenia. W pewnym momencie osoba badająca puszcza kijek, który zaczyna swobodnie spadać, osoba badana natomiast powinna jak najszybciej go złapać. Faza lotu jest wykrywana automatycznie za pomocą akcelerometru, a czas trwania swobodnego spadku jest mierzony przez mikrokontroler.
Układ ADXL362 jest przystosowany do aplikacji wykrywających ruch. Ma wbudowane procedury wykrywające stan spadku swobodnego, przekazujące wyniki przez rejestry wewnętrzne i generujące przerwania. W projekcie zastosowano jednak programową detekcję spadku swobodnego, co umożliwi ewentualne wykorzystanie algorytmu w aplikacjach z innymi czujnikami. Zasada działania przyrządu jest oparta na fakcie, że dobrze już nam znane czujniki przyspieszeń typu MEMS reagują na przyspieszenie ziemskie. Jeśli dana oś czujnika (np. X) będzie równoległa do pola grawitacyjnego, to w stanie spoczynku czujnik będzie mierzył przyspieszenie ziemskie (9,81 m/s2). Taki czujnik puszczony swobodnie pokaże zero. Odchylenie osi czujnika od pionu o pewien kąt spowoduje zmniejszenie wskazania o wartość kosinusa tego kąta (lub sinusa dla osi ortogonalnej). Zauważmy, że niezależnie od położenia układu, w spadku swobodnym (nieważkość) czujniki wszystkich wzajemnie ortogonalnych osi XYZ będą mierzyły zerowe przyspieszenia. Do wykrycia spadku swobodnego wystarczy więc stwierdzenie takiego stanu. Miernik refleksu cyklicznie mierzy więc przyspieszenia z osi X, Y i Z i sprawdza czy wszystkie są równe zero. Po wykryciu zerowych przyspieszeń zostaje uruchomiony timer TIM1 mierzący czas trwania spadku swobodnego. Pomiar przyspieszeń jest kontynuowany, lecz tym razem, wskazanie dowolnego czujnika różne od zera oznacza, że zakończyła się faza spadku swobodnego. Odczytywany jest wówczas stan timera TIM1 równoznaczny z czasem reakcji osoby badanej. Tak ostro postawione warunki mogłyby jednak spowodować niemożliwość wykonania pomiaru, gdyż choćby na skutek szumów własnych, stan, w którym wszystkie trzy czujniki jednocześnie wskazywałyby zero nie byłby możliwy lub bardzo mało prawdopodobny. Przyjęto więc margines dla zera równy 200 (przy pełnej skali 2048). Po zakończeniu pomiaru wynik czasu reakcji jest wyświetlany w formie zbliżonej do poprzedniej metody.
Akcelerometry są skonfigurowane do pracy z próbkowaniem 200 Hz i zakresem ±8g. Pasmo pomiarowe ustalono na połowę częstotliwości próbkowania.
Miłośnicy i znawcy fizyki mogą oczywiście zadać pytanie: po co stosować tak zaawansowaną technikę, skoro wystarczy nanieść odpowiednią skalę na kijku i odczytywać z niej czas reakcji. Wszak wzory
znają już uczniowie gimnazjum, a mogą one posłużyć do wykonania skali miernika refleksu. Sytuacja przypomina nieco znaną anegdotę związaną z podbojem kosmosu, w której Rosjanie nie mogli wyjść ze zdumienia, że Amerykanie przeznaczają setki tysięcy dolarów na opracowanie długopisu piszącego w nieważkości, podczas gdy oni od lat stosują tanie i niezawodne ołówki.
Jeśli dokładniej przyjrzeć się pomiarowi czasu reakcji wykorzystującemu skalę konwertującą odległość na czas, to okazuje się, że wynik pomiar może być zniekształcony, np. przez poślizg kijka w fazie jego hamowania, czyli zaciskania dłoni. Przyrząd elektroniczny wykazuje znacznie większą czułość, pozwalającą na zatrzymanie timera nawet przed pełnym wyhamowaniem spadającego kijka, niemniej odzwierciedlającym czas reakcji.
Na zakończenie warto dodać, że czas reakcji jest zwykle uzależniony od rodzaju bodźca. Nieco inaczej działają na człowieka sygnały dźwiękowe, inaczej wzrokowe, jeszcze inaczej dotykowe. W pomiarach ze spadającym kijkiem warto przeprowadzić kilka prób, w których osoba puszczająca kijek będzie dodatkowo coś w tym momencie krzyczała. Ciekawym eksperymentem, choć nie związanym już z pomiarem czasu reakcji jest powtarzanie rytmu zadawanego raz dźwiękiem, raz światłem. Z pewnością powtórzenie rytmu podanego za pomocą światłą będzie znacznie trudniejsze, a niektórzy w ogóle sobie z tym nie poradzą. Dobrą formą takiego testu jest odczytywanie informacji nadawanej alfabetem Morse’a. Osoby znające go mogą ocenić czy łatwiej odczytać informację nadawaną np. latarką czy dźwiękiem generowanym za pomocą klucza telegraficznego.
Formatowanie wyników
Jednym z zagadnień związanych z projektem było wyświetlanie wyników jako liczb zmiennoprzecinkowych. Problem można względnie łatwo rozwiązać przez zastosowanie dostępnej w języku C funkcji printf. Wyprowadza ona na standardowy strumień wyjściowy sformatowane zgodnie z życzeniem programisty informacje tekstowe i numeryczne. Trudność polega na tym, że standardowy strumień jest związany z portem szeregowym UART, a w żadnej bibliotece nie znajdziemy funkcji wyświetlających napisy na zastosowanym w module KAmodTFT2 wyświetlaczu Nokia 6100. Problem jest dwuczęściowy. Po pierwsze trzeba napisać oprogramowanie obsługujące sam wyświetlacz, składające się zwykle z funkcji wyświetlających znaki alfanumeryczne oraz kilku funkcji graficznych (rysowanie kół, kwadratów, linii, wyświetlanie pojedynczych pikseli itp.) Drugim zagadnieniem jest przekierowanie standardowego strumienia z portu szeregowego na wyświetlacz. Funkcje obsługi wyświetlacza zapisane w pliku lcd.c napisano w oparciu o znalezione w Internecie materiały autorstwa Jamesa P. Lyncha, natomiast przekierowanie strumienia rozwiązano za pomocą własnej implementacji funkcji fputc, korzystającej również z własnej funkcji LcdPutChar bezpośrednio wyświetlającej znak na wyświetlaczu. W ten sposób wyświetlenie zmiennoprzecinkowej liczby będącej wynikiem pomiaru czasu (zmienna pomiar1) stało się niezwykle proste, wystarczy do tego jedna instrukcja, np.:
printf("%6.4f",pomiar1/2048.);
Szczegóły dotyczące takiego rozwiązania można znaleźć śledząc udostępniony kod źródłowy.