ZL31ARM: sterowanie kulki i obroty bryły w 3D za pomocą czujnika MEMS LIS35
Ostatnia rzecz jakiej jeszcze brakuje to efekt odbijania się kulki od ścianki i dodatkowo utrata przy tym pędu/energii (a zatem i prędkości). Oto przykładowy fragment realizacji powyższego dla jednej osi:
//Uwzglednienie odbijania sie od scianek if(x_pos < min_pos){ //Osiagnieto pierwsza pozycje skrajna x_pos = min_pos; delta_x *= -1; //Zmiana kierunku ruchu Vx *= -5; //Wspolczynnik wplywu strat energii/predkosci przy odbijaniu od scianki=0.5 Vx /= 10; //Im wspolczynnik wiekszy tym mniej maleje predkosc //Wartosc wspo. w granicach od 0 do 1 dla prawidlowego dzialania programu } else if(x_pos > max_pos){ //Osiagnieto druga pozycje skrajna x_pos = max_pos; delta_x *= -1; Vx *= -5; Vx /= 10; }
Cała funkcja wygląda następująco:
#define radius 5 //Promien kulki #define min_pos -65+radius //Wartosc pochodzaca od: -DISPLAY_CENTER-1 = -132/2 + 1 #define max_pos 65-radius //Wartosc pochodzaca od: DISPLAY_CENTER-1 = 132/2 - 1 #define Ts 1 //Okres probkowania #define Tstrat 1 //Wspolczynnik strat na skutek tarcia void ball(){ signed short x_pos=0, y_pos=0; //Zmienne pozycyjne signed short Vx=0, Vy=0; //Zmienne predkosci signed short delta_x=0, delta_y=0; //Zmienne przemieszczenia while(1){ drawCircle(x_pos,y_pos,radius,0x000,1); //Usun poprzednia kulke LIS35_GetPosition(&x, &y, &z); //Odczyt wartosci przyspieszen //Korekta wskazan akcelerometru x+=_xKor; y+=_yKor; z+=_zKor; //Wyznaczanie aktualnej predkosci Vx += (x/5)*Ts; Vy += (y/5)*Ts; //Uwzglednienie strat na skutek tarcia if(Vx > 0) Vx -= Tstrat; else if(Vx < 0) Vx += Tstrat; else Vx = 0; if(Vy > 0) Vy -= Tstrat; else if(Vy < 0) Vy += Tstrat; else Vy = 0; //Wyznaczanie aktualnego przemieszczenia delta_x = Vx*Ts; delta_y = Vy*Ts; //Wyznaczanie aktualnej pozycji x_pos += delta_x; y_pos += delta_y; //Uwzglednienie odbijania sie od scianek if(x_pos < min_pos){ //Osiagnieto pierwsza pozycje skrajna x_pos = min_pos; delta_x *= -1;//Zmiana kierunku ruchu Vx *= -5; //Wspolczynnik wplywu strat predkosci przy odbijaniu od scianki=0.5 Vx /= 10; //Im wspolczynnik wiekszy tym mniej maleje predkosc //Wartosc wsp. w granicach od 0 do 1 dla prawidlowego dzialania } else if(x_pos > max_pos){ //Osiagnieto druga pozycje skrajna x_pos = max_pos; delta_x *= -1; Vx *= -5; Vx /= 10; } if(y_pos < min_pos){ y_pos = min_pos; delta_y *= -1; Vy *= -5; Vy /= 10; } else if(y_pos > max_pos){ y_pos = max_pos; delta_y *= -1; Vy *= -5; Vy /= 10; } drawCircle(x_pos,y_pos,radius,ball_color,1); //Rysuj nastepna kulke Delay(0xFFFF); //Ustawienie okresu aktualizacji pomiaru/obrazu } }
Zmiana koloru kulki przy kliknięciu
Moduł akcelerometru posiada również funkcję wykrywania kliknięć lub krótkich uderzeń co można wykorzystać np. do zmiany koloru kulki z poprzedniego przykładu. Aby z niej skorzystać należy odpowiednio skonfigurować układ LIS35 przez zapisanie 5 rejestrów zaraz po jego inicjalizacji. Na początku należy określić w jakiej osi ma być wykrywane kliknięcie i czy ma ono być pojedyncze lub podwójne; w danym przypadku do tego wykorzystano oś Z:
//Aktywacja wykrywania pojedynczych klikniec w jednej osi Z LIS35_WriteRegister(LIS35_CLICK_CFG,0x10);
Dalej należy wskazać powyżej jakiej wartości (wielokrotność 0.5g) ma nastąpić identyfikacja kliknięcia, tzn. należy określić próg:
//Prog wykrywania dla osi Z - 1.5g LIS35_WriteRegister(LIS35_CLICK_THSZ,0x03);