[PROJEKT] Elektroniczny kompas z sensorem HMC5883L
W czasie kalibracji wyznaczane są maksymalne i minimalne wartości pola magnetycznego dla osi „X” oraz „Y” czujnika. Gdy kalibracja skończy się, wyskalowane i przesunięte zostają wartości odczytane z czujnika na środek wirtualnego układu współrzędnych:
offsetx=((xmin+xmax)*0.5); if (offsetx<0) offsetx=(-1*offsetx); if (xmin<0) xmin=(-1*xmin); if ((xmin)<xmax) offsetx=-offsetx; offsety=((ymin+ymax)*0.5); if (offsety<0) offsety=(-1*offsety); if (ymin<0) ymin=(-1*ymin); if ((ymin)<ymax) offsety=-offsety;
Następnie pobierane są wartości natężeń pola magnetycznego:
//Pobranie danych pola magnetycznego HMC5883Get(HMC5883File, &x,&y,&z); //Obliczenie kierunku geograficznego //Skalowanie wartosci z czujnika i przesuniecie //ukladu wspolrzednych scaledx=(x+offsetx)*0.73; scaledy=(y+offsety)*0.73; //Obliczenie kierunku geograficznego //heading = atan2(y, x); heading = atan2(scaledy, scaledx); heading += declinationAngle+3.1415926; if(heading < 0) heading += 6.2831853; //2 pi if(heading > 6.2831853) heading -= 6.2831853; //Zamiana wyniku na stopnie headingDegrees = (heading * 180/3.1415926);
Po tych obliczeniach wyświetlony zostaje wynik w postaci przewijającej się linijki z zaznaczonym kierunkiem geograficznym. Zastosowany efekt przypomina widok sztucznego horyzontu stosowanego w starszych samolotach:
SLCD_Horyzont(pasek,(unsigned short)headingDegrees);
Funkcja wygląda następująco:
void SLCD_Horyzont(unsigned char *tablica, unsigned short pozycja) { unsigned char i, odnowa=0, poczatek=0; float mnoznik = 0.355555; unsigned short polozenie; polozenie=(unsigned short) (pozycja * mnoznik); for (i=0;i<37;i++) { //jeśli koniec tablicy if (tablica[i+polozenie]==0x00) poczatek=1; if(!poczatek) { for(piksel=0;piksel<8;piksel++) { if((tablica[i+polozenie]&(1<<piksel))!=0) { _SLCDModule_SetSegment(i, piksel); } } } else { //Jeśli koniec tablicy rysuj obraz od początku na dalszej części lcd for(piksel=0;piksel<8;piksel++) { if((tablica[odnowa]&(1<<piksel))!=0) { _SLCDModule_SetSegment(i, piksel); } } odnowa++; } } }
Funkcja przyjmuje wskaźnik do tablicy z rysunkiem wspomnianej linijki. Gdyby ją wyświetlić na szerszym ekranie wyglądało by to mniej więcej tak:
|-i-N-i-|-i-E-i-|-i-S-i-|-i-W-i-
z czego małe „i” to krótka pionowa kreseczka
Jako, że ekran jest za krótki do wyświetlenia całego paska, funkcja wycina część z tego obrazka oraz – jeśli jest to konieczne – przerysowuje początek tablicy na końcu ekranu w celu wypełnienia brakującego obrazu.
W dalszej części programu main() znajduje się opóźnienie oraz na końcu na obraz zostaje nałożona maska, która wyświetla pierwsze i ostatnie dwie kolumny pikseli oraz kolumnę pośrodku, aby wiadomo było jaki kierunek geograficzny wskazuje układ kompasu. Logo Freescale oraz symbol buzzera pozostają włączone.
for(czas=0;czas<200000;czas++); LCD_WF3TO0 = 0xFFFF1100; LCD_WF7TO4 = 0x00000000; LCD_WF11TO8 = 0x00000000; LCD_WF15TO12 = 0x00000000; LCD_WF19TO16 = 0x00000000; LCD_WF23TO20 = 0x000000FF; LCD_WF27TO24 = 0x00000000; LCD_WF31TO28 = 0x00000000; LCD_WF35TO32 = 0x00000000; LCD_WF39TO36 = 0x00FFFF00;
Całość od momentu odczytu pola magnetycznego aż do wyświetlenia kierunku geograficznego powtarza się w pętli.
Uwaga! W pliku C:\Freescale\Freescale MQX 3.8\mqx\source\io\lcd\slcd_kwikstik-k40x256 jest błąd polegający na tym, że w funkcji void _SLCDModule_SetSegment(U08 X, U08 Y) przed wyświetleniem pojedynczego piksela cała kolumna zostaje skasowana. Aby to zmienić należy wykomentować linię: //WFRegisterCopy &= WaveFormRegisterClearTable[X]; Wygląd fragmentu po zmianach: .... WFRegisterCopy = _SLCDModule_CopyWFRegister(X); //WFRegisterCopy &= WaveFormRegisterClearTable[X]; if (Y <= 7) .... Następnie nadpisujemy ten plik i otwieramy projekt C:\Freescale\Freescale MQX 3.8\config\kwikstikk40x256\uv4\build_libs kompilujemy całość (Project>Batch Build>Build). Dopiero teraz poprawnie możemy skompilować kod dla niniejszego przykładu. Oczywiście do kompilacji potrzebny jest wcześniej zainstalowany MQX 3.8. |