Chcesz, aby Twój robot reagował na nagłe zmiany kierunku ruchu, wstrząsy i wychylenia od pionu? Przeraża Cię obsługa akcelerometrów opisywana w języku C? Zrób to w BASCOM-AVR! Zobacz, jakie to proste.
Spadek cen akcelerometrów wykonanych w technologii MEMS w ciągu ostatnich czterech lat sprawił, że mamy dziś z nimi do czynienia niemal na każdym kroku. Zaczęto je powszechnie stosować w wielu urządzeniach korzystających z detekcji i pomiaru ruchu, zmiany położenia lub wibracji. Najbardziej oczywiste dziedziny zastosowań to motoryzacja, fotografia (stabilizacja obrazu, wyświetlanie zdjęcia w orientacji zależnej od położenia urządzenia), kontrolery gier (Sony Playstation 3, Wii…), telefonia komórkowa oraz – ostatnimi czasy – także robotyka.
Układ LIS35DE to trójosiowy akcelerometr typu MEMS, produkowany przez firmę STMicroelectronics. Pozwala wykryć drgania oraz określić nachylenie urządzenia względem pola grawitacyjnego Ziemi. Do komunikacji z innymi układami wykorzystuje dwa interfejsy – SPI i I2C. Posiada obudowę typu (T)LGA-14 – kłopotliwą w montażu przy użyciu lutownic „kolbowych”. Na szczęście w sprzedaży pojawił się moduł KAmodMEMS2 dystrybuowany przez firmę Kamami.
Najważniejsze cechy:
- napięcie zasilania 2.16V – 3.6V
- pobór mocy <1mW
- cyfrowy interfejs SPI/I2C
- programowalne generatory przerwań
- wykrywanie pojedynczego i podwójnego „kliknięcia”
- wbudowany filtr górnoprzepustowy
- odporność na wstrząsy 10000g
O ile obsługa tego typu urządzeń przy pomocy języka C jest wspierana przez wiele źródeł, o tyle użytkownicy języka Bascom mogą mieć problem z implementacją gotowych bibliotek oferowanych np. przez Kamami. Z tego powodu przygotowałem zestaw kodów źródłowych kompilujących się w środowisku BASCOM-AVR. Zostały one napisane i skomentowane tak, żeby ułatwić implementację potrzebnych rozwiązań we własnych programach. Skorzystałem z podstawowych funkcji układu LIS35DE, którymi jest pomiar przyspieszenia w każdej z trzech osi. Wartości owego przyspieszenia przypisywane są trzem, odpowiednio nazwanym zmiennym.
Do współpracy z KAmodMEMS2 zaprzągłem mikrokontroler AVR pracujący przy napięciu 3,3V – Atmega16L (pominąłem w ten sposób konieczność korzystania z konwerterów napięć). Widoczna na zdjęciach płytka uruchomieniowa ZL3AVR służy jedynie jako złącze wyświetlacza LCD (zintegrowane zasilanie i potencjometr kontrastu), nie jest więc konieczna do testowania podanego niżej przykładu.
Układ zasilam ze stabilizowanych 5V (w moim przypadku jest to zasilanie poprowadzone prosto z programatora USB) poprzez stabilizator LDO (low-dropout) LD1117VC33.
Podświetlenie LCD jest kwestią indywidualną i zależną od firmy. W moim przypadku konieczne było podłączenie jak na schemacie poniżej. Potencjometr kontrastu to 10kOhm, ale praktycznie każda zbliżona wartość wystarczy. Warto pomyśleć o dodatkowej filtracji w postaci kondensatorów między liniami VCC i GND, chociaż w przypadku zasilania z USB praktycznie nie jest to potrzebne. Schemat:
Program przedstawiony jest poniżej (wersja *.bas i skompilowana dla ATmega32L *.hex dostępna w załączniku):
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 |
$regfile = "m32def.dat" $crystal = 8000000 Config Porta = Output Config Sda = Portc.1 'konfiguracja I2C Config Scl = Portc.0 I2cinit Gosub Akcelstart Dim X As Byte 'zmienna zawierająca wartość 'przyspieszenia w osi X po odczycie z akcelerometru Dim Y As Byte Dim Z As Byte Do Cls Gosub Odczytx 'Gosub Odczyty 'Gosub Odczytz Lcd X Waitms 100 Loop End Akcelstart: Const Zapisadr = &H3A 'rejestr zapisu Const Odczytadr = &H3B 'rejestr odczytu I2cstart I2cwbyte Zapisadr I2cwbyte &H20 I2cwbyte &B01000111 'wyjście z trybu power-down I2cstop Return Odczytx: 'Odczytuje wartość przyspieszenia w osi X I2cstart I2cwbyte Zapisadr I2cwbyte &H29 I2cstart I2cwbyte Odczytadr I2crbyte X , Nack I2cstop Return Odczyty: 'Odczytuje wartość przyspieszenia w osi Y I2cstart I2cwbyte Zapisadr I2cwbyte &H2B I2cstart I2cwbyte Odczytadr I2crbyte Y , Nack I2cstop Return Odczytz: 'Odczytuje wartość przyspieszenia w osi Z I2cstart I2cwbyte Zapisadr I2cwbyte &H2D I2cstart I2cwbyte Odczytadr I2crbyte Z , Nack I2cstop Return |
Pobierz “Odczyty XYZ - kod źródłowy” odczyt_xyz.zip – Pobrano 1120 razy – 2 KB
Efekt końcowy (wyświetlana jest tylko jedna oś – X, ze względu na mały wyświetlacz):
Widoczne w programie etykiety gosub „Odczytx”, „Odczyty”, oraz „Odczytz”, to najważniejsze etykiety obsługi akcelerometru, które służą do przypisania wartości przyspieszenia osi do odpowiednich zmiennych (X, Y, Z). Pamiętajmy, że po inicjalizacji I2C, musimy układ wybudzić przy pomocy etykiety „Akcelstart”.
Aby zaprezentować działanie akcelerometru w praktyce, postanowiłem zamieścić go na specjalnie przygotowanym robocie. Pomysł zastosowania nie jest może najtrafniejszy, ale ma szansę stać się inspiracją dla bardziej kreatywnych osób ;). W robocie wykorzystałem Atmega16L, mostek L293D oraz dwa przerobione mikroserwa HXT900. Widoczne podporowe kółko pochodzi z działu meblowego Leroy Merlin i kosztowało ok. 3zł.
Akcelerometr pełni w tym projekcie coś w rodzaju funkcji tempomatu – podczas stromego podjazdu, poprzez mikrokontroler, daje silnikom sygnał do bardziej wytężonej pracy (większe wypełnienie PWM na mostkach), a podczas zjazdu kompensuje trochę „ześlizgiwanie się” poprzez spowalnianie silników.
Schemat robota:
Program w BASCOM-AVR:
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 |
$regfile = "m32def.dat" $crystal = 8000000 Config Porta = Output Config Portb = Output Config Timer1 = Pwm , Pwm = 8 , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down Config Sda = Portc.1 'konfiguracja I2C Config Scl = Portc.0 I2cinit Gosub Akcelstart Set Portb.2 Set Porta.6 Reset Portb.3 Reset Porta.7 Dim X As Byte 'zmienna zawierająca wartość przyspieszenia 'w osi X po odczycie z akcelerometru Do Gosub Odczytx Pwm1a = 255 - X Pwm1b = 255 - X Waitms 100 Loop End Akcelstart: Const Zapisadr = &H3A 'rejestr zapisu Const Odczytadr = &H3B 'rejestr odczytu I2cstart I2cwbyte Zapisadr I2cwbyte &H20 I2cwbyte &B01000111 'wyjście z trybu power-down I2cstop Return Odczytx: 'Odczytuje wartość przyspieszenia w osi X I2cstart I2cwbyte Zapisadr I2cwbyte &H29 I2cstart I2cwbyte Odczytadr I2crbyte X , Nack I2cstop Return |
Pobierz “Robot - kod źródłowy” robot.zip – Pobrano 863 razy – 2 KB
Efekt końcowy:
Zalety układu:
- cena (35,15zł),
- wygodne wyprowadzenia dla interfejsów SPI i I2C,
- małe rozmiary i waga,
- przejrzysta dokumentacja i przykładowe kody źródłowe w C,
Wady:
- praktycznie uniemożliwiony montaż modułu (brak otworów, jedynie gumowe nóżki) – choć można to tłumaczyć edukacyjnym charakterem urządzenia.
Pliki źródłowe (*.bas) wraz z plikami skompilowanymi (*.hex i *.bin do wyboru) dla obu przykładów:
Ten plik (i wiele innych ciekawych rzeczy) jest też dostępny na moim koncie Chomikuj.pl:

sorki za może lamerskie pytanie, ale jestem początkującym użytkownikiem Bascoma. Bardzo zainteresował mnie Twój projekt, ponieważ szukam akcelerometru/decelerometru współpracującego z Bascomem przez złącze I2C, a nie potrafię jeszcze poradzić sobie z obsługą takich modułów przez I2C.
Chcę zrobić miernik przyspieszenia/opóźnienia do samochodu, nie musi być to pomiar w G, mogą to być „umowne” jednostki odczytywane z I2C. Tutaj moje pytanie: moduł KAmodMEMS2 ma w nazwie „akcelerometr”, ale już w opisie jest „Umożliwia określenie nachylenia urządzenia względem pola
grawitacyjnego” – czy wykorzystując Twój program można odczytywać wartość akceleracji/decelaracji? (w jednej osi)
Tak, można. Określanie nachylenia urządzenia względem pola grawitacyjnego to nic innego jak pomiar wypadkowego przyspieszenia w jednej z osi, którego składowym jest po prostu skierowane pionowo w dół, ziemskie „g” 🙂
Witam.
Załadowałem program do procka atmega8 i na wyświetlaczu pokazuje się liczba 255 jak przekręcę wtedy jest 0 czasami wyskakują jakieś inne liczby.Co robię źle. Co zrobić aby program działał jak na filmiku powyżej.
Pozdrawiam.
Witam czy za pomocą tego akcelerometru da sie wykryć tak zwany FreeFall czyli swobodny spadek ?
Oczywiście, wszystko jest w dokumentacji układu http://www.st.com/web/en/resource/technical/document/datasheet/CD00231405.pdf
Cześć,
Mam problem – odczytuje teoretycznie wszystkie wartości z akcelerometru – dwie osie działają poprawnie, natomiast oś Z ciągle wyświetla wartość 127.
Ustawienia ctrl_reg1(20h) to 0x47 (wszystkie osie włączone).
W czym może być problem?
Gosiek