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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//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:
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 68 69 70 |
#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:
1 2 |
//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:
1 2 |
//Prog wykrywania dla osi Z - 1.5g LIS35_WriteRegister(LIS35_CLICK_THSZ,0x03); |