ZL31ARM: sterowanie kulki i obroty bryły w 3D za pomocą czujnika MEMS LIS35
Również parametry czasowe, jak ograniczenie w czasie i opóźnienie są podawane (wartości te są przykładowe i mogą zostać swobodnie zmieniane w zależności od potrzeb):
LIS35_WriteRegister(LIS35_CLICK_TIME_LIMIT,0x0F); // 7.5 msec LIS35_WriteRegister(LIS35_CLICK_LATENCY,0x07); // 7 msec
Na koniec zostaje jeszcze włączenie generacji sygnału przerwania po wykryciu kliknięcia:
//Poziom niski (log. 0) - przerwanie aktywne //Linia podciagnieta do (+) w STM32 //Przerwanie na linii INT1 po wystapieniu klikniecia LIS35_WriteRegister(LIS35_CR3,0x87);
Po skonfigurowaniu czujnika wg powyższego wzoru (konfigurację przerwań z kontrolerem NVIC przedstawiono przy konfiguracji projektu) można skorzystać z funkcji EXTI0_IRQHandler i odpowiednio reagować za zdarzenia w postaci kliknięć:
void EXTI0_IRQHandler(void){ LIS35_ReadRegister(LIS35_CLICK_SRC, &rx_data); if(rx_data | 0x10){ color = color << 4; //Kolejny kolor if(color > 0xF00) color = 0x00F; setBallColor(color); //Zmien kolor kulki //Zmien stan wyswietlania diody na przeciwny GPIO_WriteBit(GPIOB, GPIO_Pin_1, (BitAction)((1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_1)))); } // Czyszczenie flagi przerwania EXTI_ClearITPendingBit(EXTI_Line0); }
Obracanie figury
Wykorzystując wiedzę nabytą w poprzednim punkcie można zrealizować obracanie figurą 3D za pomocą odchylenia akcelerometru od pozycji neutralnej (osie X i Y są równoległe do powierzchni Ziemi). Im dłużej jest on odchylony tym coraz szybciej figura się obraca, a im większy jest kąt pochylenia tym większe przyśpieszenie kątowe otrzymuje obracający się obiekt. Również uwzględnia się tarcie, które powoduje, że prędkość kątowa w dowolnej osi maleje do zera w pozycji neutralnej akcelerometru. Funkcja realizująca powyższe zamierzenie jest podobna do tej opisanej z kulką na stole wirtualnym z niewielką różnicą; wielkości liniowe zostały zamienione na kątowe:
#define Ts 1 //Okres probkowania #define Tstrat 1 //Wspolczynnik strat na skutek tarcia void rotatingFigure(){ signed short x_orient=0, y_orient=0; //Zmienne orientacji signed short x_angle=0, y_angle=0; //Zmienne katowe signed short Wx=0, Wy=0; //Zmienne predkosci katowej signed short delta_x=0, delta_y=0; //Zmienne przemieszczenia katowego while(1){ drawCube(0, 0, x_angle, y_angle, 0, 0x000); //Usun stara figure LIS35_GetPosition(&x, &y, &z); //Odczyt wartosci przyspieszen //Korekta wskazan akcelerometru x+=_xKor; y+=_yKor; z+=_zKor; //Wyznaczanie aktualnej predkosci katowej Wx += (x/5)*Ts; Wy += (y/5)*Ts; //Uwzglednienie strat na skutek tarcia if(Wx > 0) Wx -= Tstrat; else if(Wx < 0) Wx += Tstrat; else Wx = 0; if(Wy > 0) Wy -= Tstrat; else if(Wy < 0) Wy += Tstrat; else Wy = 0; //Wyznaczanie aktualnego przemieszczenia katowego delta_x = Wx*Ts; delta_y = Wy*Ts; //Wyznaczanie aktualnej orientacji x_orient += delta_x; y_orient += delta_y; //Pobranie katow w zakresie -+360 stopni x_angle = x_orient % 360; y_angle = y_orient % 360; drawCube(0, 0, x_angle, y_angle, 0, 0xFFF); //Rysuj nowa obrocona figure Delay(0xFFFF); //Ustawienie okresu aktualizacji pomiaru/obrazu } }