Ta cześć będzie poświęcona dotykowi ,choć na naszych układach to prosta sprawa jednak wymagająca nieco omówienia i tym mam zamiar sie właśnie zająć …
Stworzymy sobie w naszym Mbed programik którego jedynym celem będzie reagować na dotyk i zmieniać kolory ekranu ….. wiem nic wielkiego , ale tymczasowo nam wystarczy zanim pokarzę jak można uzyskać takie efekty:
nie wspominając już o używaniu 7″ LCD z naszymi FT810 :
Oczywiście o tym później .. dużo później na początek jednak prosta obsługa dotyku i gdyż to nam się przyda , do naszej zabawy użyjemy zaprzyjaźnionej płytki FRDM z dużo za dużym mikrokontrolerem czyli K64F:
i 5″ LCD TFT z kontrolerem FT810 oraz dotykiem rezystancyjnym tylko dlatego że mam ładnego stylusa który się idealnie nadaje do pokazywania działania dotyku :)
zatem odpalamy mBed i zaczynamy:
Na początku musimy ładnie zainkludować potrzebne nam pliki oraz biblioteki i zdefiniować piny dla naszego FT81x :
1 2 3 4 5 |
#include "mbed.h" #include "FT_Platform.h" DigitalOut led(LED1); // dioda RGB FT800 TFT(D11,D12,D13,D9,D8,D14); // piny SPI dla FT810 |
Oczywiście cały czas bazujemy na zmodyfikowanej bibliotece FT800 o której pisałem wcześniej i której używamy we wcześniejszych częściach …
Każdy ekran dotykowy należy skalibrować i tak samo musimy postąpić i tutaj , chodzi o zdefiniowanie obszaru roboczego dla naszego LCD , który jak pamiętamy ma rozmiar 5″ i rozdzielczość 800×480 pixeli , a dotyk ma o wiele większą … dlaczego tak się dzieje pisałem tutaj:
Start z STM32 VL Discovery – 21 — Ekran dotykowy wprowadzenie
Oczywiście tak jak w tamtym przypadku nie będziemy się męczyć :) Pomimo iż też opisałem uproszczoną metodę kalibracji 3 punktowej , którą zastosujemy tutaj. Warto jednak przeczytać żeby dogłębniej się dowiedzieć jak cały mechanizm działa.
Tu w przypadku naszego FT81x mamy sprawę uproszczoną gdyż nasz kontroler ma wbudowany mechanizm kalibracji ekranu :
1 |
TFT.Callibrate(); |
ale z niego nie skorzystamy … znaczy nie w tym sensie gdyż napiszemy sobie funkcyjkę … o nazwie Kalibracja_ekranu()
1 2 3 4 5 6 7 8 9 10 11 |
ft_void_t Kalibracja_ekranu() { TFT.DLstart(); // Startujemy nową listę komend TFT.DL(CLEAR_COLOR_RGB(64,64,64)); // ustawiamy kolor kasujący ekran TFT.DL(CLEAR(1,1,1)); // czyścimy wszystkie bufory TFT.DL(COLOR_RGB(0xff,0xff,0xff)); // ustawiamy kolor ekranu R, G, B TFT.Text((TFT.DispWidth/2), (TFT.DispHeight/2), 27, OPT_CENTER, "Dotknij kropek by skalibrowac ekran ..."); // Nasz text na ekranie kalibracyjnym TFT.Calibrate(0); // uruchomienie kalibracji TFT.Flush_Co_Buffer(); // załadowanie komend do pamieci FIFO TFT.WaitCmdfifo_empty(); // Oczekiwanie na zakończenie operacji } |
Jak widać w sumie uruchomiłem tu wbudowaną kalibrację ekranu ale też i wyczyściłem bufory i podmieniłem napis Please TAP … na nasz polski :) Teraz by nasze demko miało smaczek dodamy sobie splash screen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
ft_void_t Splash_Screen(ft_char8_t *str) { TFT.DLstart(); TFT.DL(CLEAR_COLOR_RGB(255,255,255)); TFT.DL(CLEAR(1,1,1)); TFT.DL(COLOR_RGB(0x80,0x80,0x00)); TFT.Text((TFT.DispWidth/2), TFT.DispHeight/2, 31, OPT_CENTERX, str); TFT.DL(COLOR_RGB(0xFF,0x00,0x00)); TFT.Spinner((TFT.DispWidth/2),TFT.DispHeight/4, 0,0); TFT.DL(DISPLAY()); TFT.Swap(); TFT.Flush_Co_Buffer(); TFT.WaitCmdfifo_empty(); TFT.Sleep(5000); } |
Nasz screen będzie się wyświetlał przez 5 sekund i możemy mu przekazać napis jako parametr:) oczywiście nie zastosowałem tu nic nowego i wszystkie elementy są wam znane z poprzednich części.
I najważniejsza rzecz czyli pętla główna naszego programu to właśnie w niej będą się dziać wielkie rzeczy :) a więc działanie naszego dotyku ….
1 2 3 4 5 6 7 8 9 |
int main() { { ft_uint32_t TrackRegisterVal = 0; ft_uint16_t angleval = 0,slideval = 0,scrollval = 0; Splash_Screen("DEMONSTRACJA DOTYKU DLA FT81X"); Kalibracja_ekranu(); |
Na początek definiujemy kilka zmiennych :
TrackRegisterVal , której wartość początkową ustalamy na 0 oczywiście musi byc ona typu uint32_t to właśnie ta zmienna będzie przechowywać w odpowiednim rejestrze wartość dotyku w momencie używania.
kolejne zmienne definiujemy jako typ uint16_t i są to :
- angelval – będzie przyjmować wartość obrotu dialera
- slideval – bedzie przyjmować wartość pozycji slidera
- scrollval – będzie przyjmować wartość pozycji scroolera
oczywiście inicjujemy je wartością 0. Kolejne 2 linijki to wywołanie naszego Splash Screena i Wstawienie napisu :) oraz wykonanie Kalibracji ekranu …
Do tego momentu jakoś nam leciało i w sumie ciekawie wygląda :)
ale nie o to nam chodzi dlatego teraz użyjemy funkcji TRACK która zajmie się ścieżka naszego dotyku. Mianowicie na ekranie zdefiniujemy sobie 3 obiekty i opiszemy śćieżki właśnie dla nich i oczywiście wyczyścimy bufory …
1 2 3 4 5 6 7 |
TFT.Track(TFT.DispWidth/2, TFT.DispHeight/2, 1,1, 10); TFT.Track(40, (TFT.DispHeight - 40), (TFT.DispWidth - 80),8, 11); TFT.Track((TFT.DispWidth - 40), 40, 8,(TFT.DispHeight - 80), 12); TFT.Flush_Co_Buffer(); TFT.WaitCmdfifo_empty(); |
Trochę wyjaśnienia :
TRACK – tworzy ścieżkę dotyku dla obiektu graficznego, Dzięki temu że całośc mechanizmu jest wbudowana w FT81x odciąża to uC od wykonywania obliczeń i śledzenia obiektów graficznych co pozwala zaoszczędzić sporo zasobów zwłaszcza w małych uC. Track zwraca wartość która zostaje przypisana do tagu co wskazuje jednoznacznie na wybrany obiekt. Rejestrowana jest tylko część toru dla Tagu, a każde dotkniecie obiektu jest zapisane w REG_Tracker jako 1 punkt próbkowania itd.. np
- REG_TRACKER_1 – drugie dotkniecie
- REG_TRACKER_2 – trzecie dotknięcie
- REG_TRACKER_3 – czwarty punkt dotyku ….
itd … tu uwaga wiele punktów dotyku jest dostępne w kontrolerach FT811 i FT813, które korzystają z ekranów pojemnościowych. Dla FT810 dostępny jest REG_TRACKER
Szczegóły znajdziecie w dokumencie : FT81x Series Programmers GUIDE z poprzedniej części . I jedziemy dalej czyli w pętli głównej musimy stworzyć interakcję obiektów graficznych z otoczeniem:
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 71 72 73 74 75 76 77 78 79 |
while(1) { ft_uint8_t tagval = 0; TrackRegisterVal = TFT.Rd32(REG_TRACKER); // sprawdzenie który obiekt został dotkniety tagval = TrackRegisterVal & 0xff; if(0 != tagval) { if(10 == tagval) { // Gałka została dotknieta angleval = TrackRegisterVal>>16; // pobranie nowej wartosci obrotu(kąta) } else if(11 == tagval) { // dotknieto slidera slideval = TrackRegisterVal>>16; // pobranie nowej wartosci slidera } else if(12 == tagval) { // dotknieto scrolbara scrollval = TrackRegisterVal>>16; // pobranie nowej wartosci scrolbara if((scrollval + 65535/10) > (9*65535/10)) { scrollval = (8*65535/10); } else if(scrollval < (1*65535/10)) { scrollval = 0; } else { scrollval -= (1*65535/10); } } } /// ------- Wyswietlanie wlwmentów interaktywnych TFT.DLstart(); // Nowa lista wyswietlania { // kalkulacja noweo koloru tła ft_int32_t tmpval0,tmpval1,tmpval2; // Ścieżka obrotu ft_uint8_t angval,sldval,scrlval; tmpval0 = (ft_int32_t)angleval*255/65536; tmpval1 = (ft_int32_t)slideval*255/65536; tmpval2 = (ft_int32_t)scrollval*255/65536; angval = tmpval0&0xff; sldval = tmpval1&0xff; scrlval = tmpval2&0xff; TFT.DL(CLEAR_COLOR_RGB(angval,sldval,scrlval)); //ustawienie nowych kolorów kasujących } TFT.DL(CLEAR(1,1,1)); // kasowanie buforów TFT.DL(COLOR_RGB(0xff,0xff,0xff)); // kolor biały /// Gałka z efektem 3D TFT.FgColor(0x00ff00); TFT.BgColor(0x800000); TFT.DL(TAG(10)); // przypisanie wartosci do taga (10) TFT.Dial((TFT.DispWidth/2), (TFT.DispHeight/2), (TFT.DispWidth/8), 0, angleval); // Suwak z efektem 3d TFT.FgColor(0x00a000); TFT.BgColor(0x800000); TFT.DL(TAG(11)); // przypisanie wartosci do tagu (11) TFT.Slider(40, (TFT.DispHeight - 40), (TFT.DispWidth - 80),8, 0, slideval, 65535); /// Pasek przewijania z efektem 3D TFT.FgColor(0x00a000); // pierwszy plan TFT.BgColor(0x000080); // tło TFT.DL(TAG(12)); // przypisanie wartosci do taga (12) // Pasek przewijania max wartosc 65535 TFT.Scrollbar((TFT.DispWidth - 40), 40, 8, (TFT.DispHeight - 80), 0, scrollval, (65535*0.2), 65535); TFT.FgColor(TAG_MASK(0)); // resetujemy maskę tagów TFT.DL(COLOR_RGB(0xff,0xff,0xff)); // zmiana koloru na biały // napisy informacyjne TFT.Text((TFT.DispWidth/2), ((TFT.DispHeight/2) + (TFT.DispWidth/8) + 8), 26, OPT_CENTER, "Obracanie"); TFT.Text(((TFT.DispWidth/2)), ((TFT.DispHeight - 40) + 8 + 8), 26, OPT_CENTER, "Horizontal"); TFT.Text((TFT.DispWidth - 40), 20, 26, OPT_CENTER, "Vertical"); TFT.DL(DISPLAY()); TFT.Swap(); // Odswiezenie listy wyswietlania TFT.Flush_Co_Buffer(); TFT.WaitCmdfifo_empty(); // Oczekiwanie na zakończenie operacji TFT.Sleep(10); // 10ms } } } |
uff … mamy tu Suwak , pasek przewijania i obrotową gałkę , jak widzicie całość zmienia kolory tła i 1 planu elementów , a rozpoznawanie ścieżki dotyku i przypisanie wartości odbywa się poprzez TAGi … TAG przyjmuje wartośc od 1 do 255 , ale szczegółowe informacje w dokumencie ,… teraz tylko tak na szybko , jak macie pytania to piszcie :)
Na tą chwilę zostawiam was z zabawką która działa następująco:
i do zobaczenia w następnej części gdzie nieco więcej się wyjaśni …..
miłej zabawy:)