Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 18 kwi 2024, o 08:33


Strefa czasowa: UTC + 1





Utwórz nowy wątek Ten wątek jest zablokowany. Nie możesz w nim pisać ani edytować postów.  [ Posty: 12 ] 
Autor Wiadomość
PostNapisane: 15 lip 2012, o 13:34 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

Obrazek
Witam, ten artykuł będzie poświęcony budowie aplikacji dla androida w celu komunikacji bezprzewodowej bluetooth z modułami których używamy do pracy z avr. System android zdecydowanie podbił rynek urządzeń mobilnych i warto jest się nim zainteresować. W sieci dostępne są narzędzia wspomagające tworzenie aplikacji dla androida, niektóre bardziej lub mniej rozwinięte, łatwiejsze lub trudniejsze do opanowania. W tym temacie opiszę pisanie aplikacji w Basic4Android ponieważ sam używam tego produktu i cenię go sobie za prostą składnię językową, dużą intuicyjność i szybkość realizacji każdego projektu dla androida. Czytelnicy mojego artykułu o pythonie dla noki wiedzą już że do tematu podejdziemy jak najbardziej praktycznie, więc od razu zaczniemy od przygotowania sobie oprogramowania w komputerze, będzie nam potrzebna Java i SDK dla androida, może brzmi groźnie ale proszę mi wierzyć że to nic strasznego, cały proces instalacji opiszę ze screenami tak żeby nikt nie miał najmniejszego kłopotu z wystartowaniem. Zaczynamy od ściągnięcia sobie pliku instalacyjnego Java Development Kit, obecnie dostępne jest w wersji 7.5, ściągamy plik dla windows odpowiednio x86 dla 32bit lub x64 dla 64bit
>>> http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1637583.html <<<

Obrazek

Obrazek

Obrazek

Obrazek

Obrazek

Obrazek

Obrazek

Instalator jak widzimy pyta czy doinstalować JavaFX, ja anuluję ponieważ nie potrzebuję dodatkowych efektów specjalnych. Pierwszy krok mamy za sobą, teraz pora zabrać się za instalację SDK, w tym celu ściągamy sobie instalator SDK obecnie w wersji R20 i instalujemy tak jak na zamieszczonych screenach
>>> http://developer.android.com/sdk/index.html <<<

Obrazek

Obrazek

Obrazek

Obrazek

Obrazek

Obrazek

Obrazek

Obrazek

Instalator SDK gotowy do pracy więc ściągnijmy za jego pomocą SDK, otwieramy Android SDK Manager i zaznaczamy interesujące nas pola, ja wybrałem API8 dla androida w wersji 2.2 ponieważ budując aplikację będę miał świadomość że zainstaluje się ona na wszystkich wersjach androida wstecz aż do 2.2, gdyby wystąpiły kłopoty ze ściągnięciem SDK i może tak się zdarzyć jeśli Manager nie będzie mógł utworzyć katalogu to proszę go zamknąć i uruchomić jeszcze raz jako administrator prawym przyciskiem myszy.

Obrazek

Obrazek

Obrazek

No i mamy za sobą przygotowanie Java i SDK. Przyda się jeszcze nam emulator, ja nie korzystam z niego ponieważ wolę wszystko widzieć dokładnie bezpośrednio na urządzeniu, ale opiszę później oba sposoby testowania pisanych aplikacji i każdy będzie sobie używał tego co uzna za lepsze. Przygotujmy więc emulator, uruchamiamy AVD Manager który zainstalował się razem z SDK Managerem i postępujemy według screenow

Obrazek

Obrazek

Obrazek

Mamy gotowy emulator, ja wybrałem rozdzielczość ekranu 320x480 ponieważ artykuł piszę na netbooku w którym mam małą rozdzielczość i nie chcę żeby emulator zajmował mi większość ekranu, nie ma to też specjalnie znaczenia bo aplikacje które będziemy pisali same dopasują się rzeczywistych wymiarów wyświetlacza w urządzeniu. Jeśli ktoś jest niecierpliwy i chciałby już pobawić się emulatorem to proszę bardzo, zaznaczamy stworzony emulator i wybieramy Start, po uruchomieniu mamy działającego wirtualnego androida na komputerze

Obrazek

Obrazek Obrazek

Obrazek Obrazek

Następnym razem uruchomimy Basic4Android i od razu napiszemy pierwsze aplikacje, postaram się żeby to stało się jeszcze dziś.



Ostatnio edytowano 15 lip 2012, o 16:26 przez ariek44, łącznie edytowano 1 raz

Góra
 Zobacz profil  
 
PostNapisane: 15 lip 2012, o 22:46 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

Tak jak obiecałem od razu startujemy z Basic4Android i zbudujemy pierwszą aplikację. W tej części wyjątkowo będę umieszczał dużo screenów żeby za ich pomocą pokazać cały przebieg pracy z Basic4Android, w kolejnych częściach wystarczą nam już kody źródłowe z ewentualnym widokiem zbudowanej aplikacji. Jestem pewny że po zapoznaniu się z tą częścią artykułu każdy polubi Basic4Android. No to zaczynamy od poznania głównego okienka w którym będziemy tworzyć

Obrazek

Widzimy typowe okienko z domyślnie utworzonymi funkcjami trochę przypominające znane delphi, visual studio czy visual basic. Wykonamy teraz podstawową czynność tzn wskazanie ścieżek dostępowych gdzie mamy jave i sdk, to jednorazowe ustwienie wymagane przy pierwszym uruchomieniu Basic4Android. Jeśli ścieżki dostępowe przy instalacji JDK były takie jak na screenach w poprzednim poście to teraz też powinny się one pokrywać ze screenem poniżej

Obrazek

Obrazek

Od razu zapiszmy sobie naszą aplikację, ja utworzyłem sobie na pulpicie specjalnie w tym celu katalog i tam będę zapisywał aplikacje, będzie to pierwsza aplikacja więc nadałem jej nazwę Program001

Obrazek

Obrazek

Domyślnie włączona jest opcja automatycznie zapisująca tworzoną aplikację, ja zawsze to wyłączam i sam decyduję czy chcę zapisywać zmiany które wykonałem i kiedy chcę to zrobić

Obrazek

Teraz szybko łatwo i przyjemnie stworzymy przycisk w który będzie można sobie klikać, otwieramy z menu Designer i intuicyjnie dodajemy przycisk

Obrazek

Obrazek

Obrazek

Po dodaniu przycisku musimy zapisać nasz interfejs, wcześniej zapisaliśmy projekt z kodem źródłowym pod nazwą Program001 więc pasowałoby żeby interfejs nazwać tak samo, nie jest to konieczne i można nadać dowolną nazwę ale w taki sposób utrzymujemy sobie porządek w plikach

Obrazek

Obrazek

Według naszego założenia w przycisk będzie można klikać, więc od razu stworzymy funkcję która będzie za to odpowiedzialna klikając na niego prawym klawiszem myszki tak jak na poniższym screenie

Obrazek

Widzimy że utworzyła się funkcja obsługi kliknięcia przycisku Button1, możemy zamknąć Designera jeśli już nic nie będziemy do niego dodawać

Obrazek

Po kliknięciu w przycisk niech pokaże się okienko informujące nas co to za aplikacja, dopisujemy więc pokazanie okienka w funkcji obsługi kliknięcia przycisku

Obrazek

Wierzcie lub nie ale pierwsza aplikacja jest gotowa i tylko czeka żeby ją uruchomić. Wspominałem w poprzednim poście że można testować aplikacje w emulatorze lub bezpośrednio na urządzeniu, zacznijmy od emulatora, jeśli mamy zamknięty emulator to uruchamiamy go tak jak widać na screenach

Obrazek

Obrazek

Obrazek

Obrazek

Obrazek

Kiedy emulator jest już gotowy do pracy to wybieramy z menu Project -> Compile and Run żeby skompilować projekt i uruchomić w emulatorze

Obrazek

Kompilujemy pierwszy raz nasz projekt więc musimy podać identyfikator naszej aplikacji którym jest ciąg znaków składający się z małych literek, zwyczajowo zawiera się w nim informacja o nazwie aplikacji i jej autorze

Obrazek

Podajemy również nazwę aplikacji, ta nazwa będzie widoczna pod ikonką w urządzeniu kiedy zainstalujemy naszą aplikację. Nazwę i identyfikator mogliśmy podać wcześniej w menu Project -> .. ale nie została wcześniej określona więc Basic4Android teraz prosi o te informacje, nie będziemy już o to pytani przy kolejnym kompilowaniu. Po podaniu nazwy rozpocznie się proces kompilacji i wysyłania aplikacji do emulatora

Obrazek

Obrazek

Obrazek

No i mamy naszą aplikację, jedno tylko się nie zgadza, nie ma naszego przycisku. I słusznie, stworzyliśmy interfejs ale nigdzie nie napisaliśmy że chcemy go użyć w naszej aplikacji, zróbmy to teraz

Obrazek

Interfejs nazywany jest Activity i jest naszą przestrzenią na której możemy umieszczać przyciski i inne elementy interfejsu. Teraz po kompilacji i wrzuceniu na emulator widzimy już nasz przycisk

Obrazek

Jest przycisk tylko jakiś nie taki jakbyśmy chcieli, nie ma na nim tekstu i nie jest ułożony tak jakbyśmy chcieli. Moglibyśmy to zrobić w Designer we właściwościach tego przycisku, jest tam pole do wprowadzenia tekstu i można go dowolnie rozciągać, ale ja wolałbym to wykonać programowo głównie z dwóch powodów, pierwszy jest taki że czasem zdarza się że chcę zmieniać w czasie pracy aplikacji tekst na przycisku np kiedy mam napisz ON to po kliknięciu chcę żeby zmienił się na OFF i odwrotnie, drugi powód to taki że kiedy prześlę aplikację koledze który ma inną rozdzielczość wyświetlacza w urządzeniu to ten przycisk nie będzie w tym miejscu gdzie powinien. Dlatego teraz programowo nadamy właściwości temu przyciskowi

Obrazek

W funkcji przechowującej zmienne i globalne utworzyliśmy zmienną Button1 która jest naszym przyciskiem i możemy teraz zmieniać wszystkie właściwości tego przycisku, proszę zobaczyć na screenie jak fajnie Basic4Android udziela nam podpowiedzi po naciśnięciu kropki. Ustawimy tekst na przycisku, nadamy mu szerokość (width) i wysokość (height) oraz wycentrujemy go dokładnie na środku obliczając jego położenie na podstawie wymiarów ekranu i jego samego. Zamiast wybierać z menu Project -> Compile and Run taka fajna niespodzianka w postaci niebieskiego trójkącika który oznacza to samo

Obrazek

Obrazek

Obrazek

Wszystko działa jak trzeba, teraz spróbujemy zamiast emulatora używać naszego urządzenia. Zamykamy więc emulator i bierzemy urządzenie do ręki, uruchamiamy Android Market i instalujemy B4A-Bridge

Obrazek

Po uruchomieniu widzimy że mamy do wyboru dwie możliwości, pierwsza to połączenie bluetooth i druga to połączenie wifi, zaczniemy od tego pierwszego, klikamy na Start - Bluetooth. W Basic4Android wybieramy z menu Tools -> B4A Bridge -> Connect - Bluetooth

Obrazek Obrazek

Obrazek

Obrazek

Obrazek

Obrazek

Obrazek

Obrazek Obrazek


Obrazek Obrazek

Aż się prosi wypróbować wifi, zróbmy to teraz, naciskamy Stop w B4A-Bridge i tym razem wybieramy Start - Wireless, widzimy na górze podany adres IP urządzenia. W Basic4Android wybieramy z menu Tools -> B4A Bridge -> Connect Wirless

Obrazek

Podajemy adres IP naszego urządzenia który mamy przedstawiony na urządzeniu w B4A-Bridge

Obrazek

Obrazek

Obrazek Obrazek

Wszystko się zgadza, widzimy więc jak intuicyjnym środowiskiem jest Basic4Android, praca na nim nawet bez dużej wiedzy o androidzie może być przyjemna. Teraz na koniec chciałbym jeszcze powiedzieć o dwóch przydatnych ustawieniach podczas budowania aplikacji, pierwsza rzecz to możliwość dodania własnej ikonki która będzie widoczna w urządzeniu, może nią być plik png, bmp, jpg, najlepiej będzie png ponieważ mamy w nim przeźroczystość

Obrazek

Druga rzecz to reakcja aplikacji na zmianę orientacji ekranu, możemy ustawić żeby aplikacja pracowała w trybie tylko pionowym, tylko poziomym lub w obu trybach zgodnie z rotacją urządzenia.

Obrazek

W następnych częściach nie będzie już tylu screenów, zamiast tego będą kody źródłowe z widokiem budowanej aplikacji i zaczniemy nawiązywać łączność z modułem bluetooth.



Góra
 Zobacz profil  
 
PostNapisane: 16 lip 2012, o 21:53 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

Znamy już środowisko Basic4Android i potrafimy z niego korzystać, wiemy jak stworzyć aplikację i wysłać ją do emulatora lub urządzenia. Teraz spróbujemy wykorzystać więcej elementów interfejsu żebyśmy mogli się nimi posługiwać w przyszłości, zaczynamy od uruchomienia Basic4Android i zapisujemy pusty projekt, wcześniej aplikacja miała nazwę Program001 więc ja aplikację z tej części artykułu nazwę Program002. Uruchamiamy Designer i układamy na nim elementy mniej więcej według poniższego screena, proszę nie przywiązywać dużej wagi do dokładnego układania kolorowych klocków ponieważ my i tak będziemy programowo nadawali wszystkie właściwości łącznie z szerokością, wysokością i ułożeniem na interfejsie, widok ten jednak będzie nam pomocny żeby mieć pogląd na to jak będzie wyglądała nasza aplikacja

Obrazek

Kiedy mamy ułożone elementy to zapisujemy taki interfejs, ja zapisuję pod nazwą taką samą jak cały projekt czyli Program002. Spróbujmy od razu zobaczyć jak to wygląda w emulatorze, przed tym jednak napiszmy w projekcie że będziemy używali utworzony wcześniej interfejs

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Widać mój emulator nie ułożył mi elementów na Activity tak jak zapisałem w Designer, zobaczmy z ciekawości jak wyglądać będzie taka aplikacja na moim urządzeniu

Obrazek

Jest mniej więcej dobrze, nie wiemy jednak jak będzie wyglądać to na innej rozdzielczości ekranu, dla pewności najlepiej sami o to zadbamy, wtedy kiedy wyślemy aplikację do innego urządzenia wszystko będzie ułożone tak jak chcemy. Automatyczne rozmieszczanie elementów na Activity wykonujemy poprzez obliczanie ich szerokości i wysokości oraz pozycji od góry i od dołu, obliczamy to na podstawie rozmiaru całego Activity, zaczniemy powoli, najpierw od samej góry czyli od elementu Label1, jeśli chcemy operować na właściwościach Label1 to też musimy utworzyć zmienną która będzie ten element reprezentować w naszym kodzie, robimy to albo ręcznie dodając taką zmienną do funkcji globalnych albo w Designer klikamy na ten element prawym klawiszem myszki i wybieramy generowanie zmiennej

Obrazek

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


zerknijmy jeszcze raz na projekt w Designer i popatrzmy na ułożenie elementów

Obrazek

widzimy że całe Activity możemy podzielić na siedem równych części poziomych jakbyśmy kroili je na siedem plasterków w poziomie, więc wiemy że wysokość Label1 będzie jednym takim plasterkiem czyli 1/7 wysokości całego Activity, szerokość Label1 będzie taka jak szerokość Activity, położenie od góry (top) będzie równe zero i od lewej strony (left) także zero. Label1 to element wyświetlający tekst, ja chciałbym żeby wyświetlanym tekstem była wartość SeekBar1 czyli takiego fajnego potencjometru, tak też napiszemy, ale żeby pobrać wartość SeekBar1 to najpierw musimy utworzyć zmienną która reprezentuje ten SeekBar

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Domyślnie potencjometr ułożony jest na środku, jego wartość maksymalna wynosi 100 więc Label1 wskazuje 50, proszę zauważyć że wartość ta jest liczbowa, do tekstu w Label1 możemy dodawać dowolnie łańcuchy znakowe i liczby. Ja chciałbym jeszcze żeby wskazywana wartość była na środku Label1, dopiszmy więc linię centrującą tekst w poziomie i pionie

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Jak dla mnie czcionka trochę mała, powiększmy ten napis dwukrotnie

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Moim zdaniem jest już dobrze, teraz zajmiemy się potencjometrem bo kiedy nim przesuwamy nie ma żadnej reakcji w Label1, nie ma dlatego że ustawiliśmy jego tekst w funkcji która wywoływana jest jednorazowo podczas tworzenia interfejsu. Musimy zrobić tak żeby Label1 wiedział o tym że zmieniła się wartość SeekBar1 i odpowiednio zmienił się napis. W tym celu otwieramy Designera i prawym klawiszem myszki na SeekBar1 generujemy funkcję która będzie wykonywała się przy zmianie jego wartości (ValueChanged). W tej funkcji odpowiednio zmienimy napis na Label1 i będziemy mieli od teraz liczbowy podgląd wartości potencjometru

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Fajnie się reguluje ale jeśli miałbym taki potencjometr wykorzystać do wysyłania np wartości PWM do mikrokontrolera to od razu ustawiłbym jego maksymalną wartość na 255 oraz wartość początkową na 0 zamiast na połowę wartości maksymalnej. Oczywiście należy także ustawić ten potencjometr w Activity nadając mu programowo wysokość, szerokość i położenie od góry i od dołu

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Ustawiliśmy maksymalną wartość SeekBar1 na 255+1 ponieważ podaje on wartości licząc od zero, czyli żeby wskazał 255 musi mieć maksymalną wartość o jeden więcej. Skoro mamy napisane automatyczne dopasowanie Label1 i SeekBar1 to możemy spróbować uruchomić aplikację w emulatorze i te dwa elementy powinny teraz ułożyć się dokładnie tak jak chcieliśmy

Obrazek Obrazek Obrazek

Aplikacja zaczyna wyglądać ciekawie w emulatorze, aż chce się wykonać następne dopasowania elementów, zerkamy jeszcze raz na widok interfejsu w Designer

Obrazek

Następne w kolejce są trzy przyciski Button1,2,3. Ja w zamyśle mam taki plan że te trzy przyciski będą dodawały wartości liczbowe wpisane w poniżej umieszczone Label2,3,4 i przyciskami Button4,5,6 te wartość będą zmniejszane, przy czym będziemy osobno regulować jednostki, dziesiątki i setki całej wartości, czyli każdy z przycisków będzie zliczał w górę lub w dół w przedziale 0 do 9. Zacznijmy od pierwszych trzech przycisków na trzecim plasterku poziomym Activity

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Idzie nam coraz lepiej, układamy kolejny plasterek czyli Label2,3,4 i nadajemy im początkowy napis 0, przy okazji ułożymy do kompletu trzy następne przyciski które będą odejmowały wartości

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Aź się przyjemnie patrzy i klika w te przyciski, dopiszmy więc resztę układania pozostałych elementów

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Interfejs aplikacji mamy gotowy, ładnie nam to wyszło. Przez te programowe układanie elementów wydłużył nam się znacznie kod, kiedy nie będziemy pisać w danej funkcji i nie potrzebujemy jej widzieć to możemy ją zwinąć klikając w mały kwadracik ze znakiem minusa przy nazwie funkcji, potem w dowolnej chwili możemy sobie to rozwinąć, zwinięte funkcje będą obramowane szarym prostokątem tak jak na poniższym screenie

Obrazek

No to włączamy przyciski "+" i "-" do akcji, żeby to zrobić wywołujemy Designer i generujemy dla każdego z tych przycisków funkcję kliknięcia, w tych funkcjach odpowiednio modyfikujemy napis na właściwych Label1,2,3

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Licznik działa nam tak jak powinien, pora na dwa kolejne przyciski, ja chciałbym mieć zawsze jeden nieaktywny, kiedy kliknę w ten drugi to pierwszy będzie aktywny i nieaktywny będzie będzie ten drugi, w Designer generujemy funkcję kliknięcia na te przyciski i zapisujemy w tych funkcjach włączanie i wyłączanie przycisków, trzeba też do funkcji wywołującej się przy uruchomieniu interfejsu dopisać początkowe wyłączenie drugiego przycisku

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek

Zostały nam ostatnie elementy na Activity tzw ptaszki zaznaczenia, napiszmy kod w którym jeden ptaszek wyklucza drugiego i odwrotnie, domyślamy się już że z Designer generujemy funkcje które będą za to odpowiedzialne, w tym przypadku to funkcje CheckedChange

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek

Ostatnia rzecz to etykieta Activity która domyślnie ma nazwę "Activity", zmienimy ją na włąsną, w funkcji pierwszego uruchomienia interfejsu Activity_Create zaraz po załadowaniu interfejsu LoadLayout dopisujemy sobie nasz tytuł

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Możemy ustawić także wymuszenie pionowego trybu pracy żeby całe nasze ułożenie ładnie nam się utrzymywało przy rotacji ekranu. W tej części to będzie na tyle, jest późno i trzeba powoli kończyć tą opowieść, myślę że zainteresowanym spodobało się środowisko Basic4Android, po testach jakie wykonaliśmy każdy już potrafi zaprojektować sobie własną aplikację, nadać jej odpowiedni wygląd i ułożenie. W miarę możliwości postaram się szybko opublikować kolejną część artykułu.



Góra
 Zobacz profil  
 
PostNapisane: 17 lip 2012, o 21:34 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

Rozpoczynamy trzecią część artykułu o androidzie, wiem że zainteresowani chcą już jak najszybciej sterować swoim modułem bluetooth, czytając artykuł trzymają w jednej ręce urządzenie z androidem i w drugiej ręce moduł bluetooth, ja chciałem z początku najpierw pobawić się Basic4Android i na końcu wykorzystać całą zdobytą wiedzę z artykułu do budowy aplikacji łączących się z modułami, ale znając oczekiwania czytelników zmienię trochę moje plany i przeskoczę kilka tematów żeby przedstawić możliwie szybko komunikację bluetooth. Zanim to zrobimy chciałem jeszcze dodać że Basic4Android ma naprawdę duże możliwości jeśli chodzi o tworzenie aplikacji, umożliwia wykorzystanie praktycznie każdego zasobu sprzętowego urządzenia typu dostęp do plików, użycie dźwięków, grafiki, łączenie się z internetem, odczyt wartości z czujników ruchu, czujników magnetycznych, temperatury i innych dostępnych dla danego urządzenia, można budować naprawdę ciekawe aplikacje i tworzony tutaj temat o połączeniu bluetooth to tak naprawdę maleńka cząstka możliwości jakie możemy osiągnąć w nieskomplikowany sposób. Nie mam zamiaru namawiać nikogo na wydanie pieniążków na pełną wersję tego środowiska, ale biorąc pod uwagę liczbę urządzeń z androidem na rynku i możliwości jakie nam przynoszą mogę śmiało polecić taki zakup dla osoby która lubi, która chce i która widzi korzyści z tego płynące, kwota nie jest nazbyt przesadna i na pewno przyniesie nam to dużą satysfakcję z dostępnych modułów, świetnych tutoriali i wsparcia na stronie domowej projektu, poza tym w ten sposób dziękujemy także autorowi Basic4Android za jego pracę przy stworzeniu dla nas tego produktu. To tyle byłoby pisania w słowach wstępu do trzeciej części i zabierajmy się teraz do działania, jednak przed nawiązaniem komunikacji z modułem i wysłaniem rozkazu do mikrokontrolera zróbmy chociaż jedną aplikację typu narzędziowego która być może zachęci czytelników do stworzenia kolejnych aplikacji tego typu i dzielenia się nimi z osobami o podobnych zainteresowaniach. Zacznijmy więc jak zawsze od pustego projektu który od razu zapisujemy, aplikacja którą teraz stworzymy będzie nam obliczała częstotliwość PWM, będzie to taka mała pomoc przy pisaniu programu dla mikrokontrolera w którym używać będziemy sprzętowego pwm. Zapisujemy więc projekt pod nazwą wskazującą na przeznaczenie naszej aplikacji, ja zapiszę pod nazwą PWMcalc. Trzeba teraz w Designer stworzyć prosty interfejs w którym możemy podawać wartości na podstawie których zostanie obliczona częstotliwość podana w Hz, ja obliczam to ze wzroru kwarc/preskaler/rozdzielczość, gdzie rozdzielczość to 255 dla 8 bitów i 1024 dla 10 bitów

Obrazek

Kiedy mamy mniej więcej ułożone kafelki to zapisujemy gotowy interfejs i nadajmy programowo wszystkie typowe właściwości tych kafelek takie jak wielkość, ułożenie na Activity, napisy i wartości początkowe

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


W emulatorze lub na urządzeniu powinniśmy zobaczyć efekt ułożenia elementów interfejsu w początkowymi ustawieniami

Obrazek

Wynik w Label5 ustawiony jest z dwoma miejscami po przecinku dzięki użyciu Round2, jest to jedno z wielu poleceń Basic4Android ułatwiających operowanie na liczbach i łańcuchach znaków. Skoro mamy już właściwie gotowy interfejs to dopiszmy mechanizm obliczający, będzie to mechanizm automatyczny tzn będzie obliczał częstotliwość PWM po każdej zmianie w EditText1,2,3. Żeby tak się działo to trzeba oczywiście wygenerować funkcje które będą wywoływane przy zmianie zawartości EditText'ów, generujemy więc dla każdego EditText'a funkcje TextChanged w Designer i tym razem zamiast pisać w każdej funkcji cały mechanizm obliczający to wykonamy wywołanie do nowej jednej funkcji którą zaraz sobie napiszemy

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Mamy pięknie działającą aplikację, w dodatku praktyczną i samodzielnie napisaną, takich narzędzi można sobie tworzyć do woli i jak już kiedyś wspomniałem ogranicza nas tylko nasza wyobraźnia, a dzięki Basic4Android praca przy tworzeniu takich narzędziowych aplikacji to sama przyjemność. Do aplikacji chciałbym jeszcze dodać menu, mamy taki przycisk w urządzeniach, dodajmy sobie menu w którym będzie pozycja "Informacja" i po wybraniu wyświetli się ładne okienko z informacją o aplikacji

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek

Proszę zobaczyć jak łatwo można było zbudować menu, określiliśmy menu w funkcji zmiennych globalnych zapisując w nim pozycję "Informacja" i podając funkcję do wykonania po wybraniu tej pozycji, zaraz poniżej utworzyliśmy sobie funkcję i w niej pokazanie okienka informacyjnego. W emulatorze menu wywołujemy przyciskiem F2 w komputerze. Dziś miałem trochę innych zajęć w domu i późno podszedłem do pisania tej trzeciej części, teraz znowu zrobiło się późno i będę musiał przerwać, obiecuję jednak że w kolejnej części już z samego początku będziemy nawiązywać komunikację bluetooth.



Góra
 Zobacz profil  
 
PostNapisane: 18 lip 2012, o 20:26 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

Przyszedł czas na komunikację z modułem bluetooth, od razu uruchamiamy cieszący nas coraz bardziej Basic4Android, zapisujemy pusty projekt pod kolejną nazwą ćwiczeń, dla mnie będzie to Program003. Zaczniemy od rzeczy podstawowej tzn sprawdzenia czy mamy włączony adapter bluetooth w urządzeniu, do tego wystarczy nam jeden Label w Designer który będzie powiadamiał nas o tym czy bluetooth jest włączony czy nie. Dodajemy więc w Designer Label1 i zapisujemy taki interfejs. Za każdym razem kiedy dodamy wszystkie elementy i zapiszemy to możemy zamknąć Designer, nie potrzeba go mieć ciągle uruchomionego. W kodzie projektu napiszemy właściwości dla Label1, ja ułożę go sobie na dole ekranu

Obrazek

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


W naszym powiadomieniu nie ma napisu dla Label1 ponieważ jeszcze nie wiemy jaki on będzie w chwili uruchomienia aplikacji. Żeby się o tym dowiedzieć musimy pierwszy raz użyć biblioteki w naszym projekcie, biblioteka którą użyjemy nazywa się Serial. Napiszmy więc sprawdzenie włączonego adaptera bluetooth

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Po próbie uruchomienia kodu widzimy błąd

Obrazek

Zgadza się, Basic4Android słusznie wygenerował dla nas okienko z błędem ponieważ w kodzie napisaliśmy użycie biblioteki Serial ale nie dodaliśmy jej do projektu, dodamy bibliotekę teraz zaznaczając ją w zakładce LIB po prawej stronie głównego okna Basic4Android

Obrazek

Obrazek Obrazek

Po zaznaczeniu biblioteki Serial projekt nam się ładnie skompilował, w kodzie utworzyliśmy zmienną Adapter która jest dla nas potrzebną biblioteką do sprawdzania stanu adaptera bluetooth w urządzeniu. Od razu przy ustawianiu właściwości Label1 dodaliśmy jego napis zależny od tego czy bluetooth jest włączony czy wyłączony. Takie rozwiązanie jak się domyślamy zostanie wykonane tylko raz przy uruchomieniu aplikacji i potem gdybyśmy wyłączyli bluetooth nie zmieniło by się nasze powiadomienie w Label1. Rozwiązaniem na to jest cykliczne sprawdzanie stanu bluetooth. Stworzymy sobie do tego celu timer który będzie w tle aplikacji sprawdzał stan bluetooth. Przy okazji dodam że jeśli ktoś nie pracuje w emulatorze tylko w urządzeniu to przy połączeniu USB jednocześnie ładuje sobie baterię i sprawdza pisany kod bez użycia bluetooth lub wifi, to bardzo wygodne i pożyteczne.

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Utworzyliśmy zmienną Timer1 która będzie timerem sprawdzającym cyklicznie włączenie bluetooth, przy pierwszym uruchomieniu określiliśmy pracę tego timera na 100ms i włączyliśmy go. W funkcji jaka będzie się wykonywać po każdym zliczeniu naszego timera (Timer1_Tick) sprawdzamy stan adaptera bluetooth i odpowiednio ustawiamy napis w Label1. Powyższy kod najlepiej sprawdzić sobie na urządzeniu włączając lub wyłączając bluetooth i obserwować zmiany napisu który powinien nas o tym informować. Jeśli wszystko się zgadza to możemy zrobić kolejny krok jakim będzie połączenie z modułem. Połączenie możemy wykonać na kilka sposobów i wszystkie kolejno omówimy. Pierwszy sposób polega na zainicjowaniu połączenia z modułem znając jego adres MAC. Adres modułu możemy odczytać we właściwościach modułu w komputerze

Obrazek

Otwieramy Designer i dodajemy przyciski połączenia i rozlączenia, nastepnie tworzymy funkcje kliknięcia dla każdego z przycisków, gdy mamy gotowe to zapisujemy projekt interfejsu i zamykamy Designer

Obrazek

Do kodu projektu dodajemy właściwości przycisków, jeden z nich będzie do połączenia, drugi do rozłączenia, oba zrobimy nieaktywne przy uruchomieniu aplikacji, pierwszy przycisk będzie aktywny jeśli bluetooth bedzie włączony, naciśnięcie pierwszego przycisku zmieni stan przycisków na przeciwny

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek Obrazek

Po sprawdzeniu pracy przycisków i zmiany powiadomienia o stanie bluetooth możemy spróbować połączyć się i rozłączyć z naszym modułem, uwaga podając MAC adres modułu należy używać dużych liter

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek

Obrazek Obrazek

Utworzyliśmy nową funkcję Adapter_Connected do której nasza zmienna Adapter będzie przekazywała True lub False po próbie połączenia, w funkcji zmiennych globalnych utworzyliśmy sobie zmienną Flaga do której będziemy przekazywali czy połączenie się powiodło lub nie, w funkcji pierwszego uruchomienia aplikacji ustawiliśmy tą zmienną na False, zależnie od zmiennej Flaga aktywujemy przyciski w funkcji timera jeśli bluetooth jest włączony, jeśli jest wyłączony to oba przyciski będą nieaktywne. Przy rozłączaniu się z modułem ustawiamy zmienną Flaga do razu na False, ciekawym trikiem było wyłaczenie timera na czas połączenia dzięki czemu mogliśmy do Label1 napisać "Czekaj.." informujące nas że trwa proces łączenia, timer ten zostanie włączony kiedy tylko dostaniemy informację o połączeniu w funkcji Adapter_Connected. Jeśli możemy połączyć się z modułem to wyślijmy teraz znak który powinniśmy odebrać w terminalu jeśli mamy moduł podłączony do komputera. Wysłanie znaku zrealizujemy także na przycisku, dodajmy go w Designer i od razu utwórzmy funkcję od kliknięcia, zapisujemy i zamykamy. Do kodu projektu dorzucamy właściwości trzeciego przycisku i w funkcji kliknięcia będziemy wysyłać znak

Obrazek

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek

Obrazek

Wysyłaniem zajmuje się TextWriter, utworzyliśmy dla niego zmienną globalną i przy udanym połączeniu w funkcji Adapter_Connect przygotowujemy go do pracy. W funkcji kliknięcia przycisku wysyłającego znak użyliśmy wysłania znaku ascii 48 czyli znaku "0", można zamiast chr(48) napisać po prostu "0", wysyłane w ten sposób znaki nie zawierają znaczników przejścia do nowej linii. Jeśli wysłanie znaku nie uda się to aplikacja nie zatrzyma pracy na błędzie tylko ustawi zmienną Flaga na false i timer zadba o przywrócenie przycisków do właściwego stanu. Czasem może zdarzyć się że nawiązywanie połączenia trwa bardzo długo, na tyle długo że nie chce nam się czekać, być może biblioteka Serial nie jest jeszcze ostateczną wersją Basic4Android i mogą zdarzyć się takie niespodzianki, dlatego dobrym pomysłem byłoby dodanie do kodu ograniczenia czasowego które zadziała po zadanym czasie w ten sposób że przywróci nam stan przycisków żebyśmy mogli jeszcze raz nawiązć połączenie, można to zrobić bardzo szybko w poniższy sposób

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Został zaciągnięty do pracy drugi timer ustawiony na 5000ms czyli 5sek, kiedy odliczy swój czas wyłączy swoją pracę i przywróci zatrzymaną pracę pierwszego timera, a jak wiemy w pierwszym timerze mamy odświeżenie przycisków i Label1 zależnie od włączonego bluetooth i zmiennej Flaga. Od teraz możemy pisać pierwsze aplikacje wysyłające rozkazy do mikrokontrolera, ja dodałbym jeszcze jedną rzecz tzn utrzymywanie podświetlania ekranu w czasie pracy aplikacji żeby ekran nie gasnął nam jak chwilę nie będziemy wysyłać rozkazu. Do utrzymywania podświetlania ekranu użyjemy biblioteki Phone więc zaznaczmy ją sobie w zakładce po prawej stronie głównego okna Basic4Android i dopisujemy kod projektu utrzymywanie podświetlenia

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Dodane zostały tylko dwie linie odpowiedzialne za utrzymanie podświetlania, w funkcji zmiennych globalnych utworzyliśmy zmienną Ekarn i w funkcji przy pierwszym uruchomieniu ustawiliśmy ciągłe podświetlanie na True. Teraz po uruchomieniu aplikacji ekran powinien być ciągle włączony. Po testach okazuje się że kiedy zamykamy aplikację to ekran ciągle pozostaje włączony, dzieje się tak dlatego że android pozostawia włączony proces naszej aplikacji, powinniśmy zadbać o całkowite zamknięcie aplikacji i zrobimy to poprzez dodanie do kodu naszego projektu poniższej funkcji

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Przechwyciliśmy kody przycisków w naszej aplikacji, przycisk zamykania który domyślnie jest strzałką skierowaną w lewą stronę ma kod 4, kiedy zostanie naciśnięty to wykonujemy na pożegnanie rozłączenie z modułem jeśli był połączony, zamykamy interfejs i ostatecznie całą naszą aplikację. Na dziś skończymy dalsze pisanie, w kolejnej części artykułu poznamy inny sposób łączenia się z modułem.



Góra
 Zobacz profil  
 
PostNapisane: 19 lip 2012, o 19:46 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

Jeśli udało nam się nawiązać połączenie z modułem przez podanie MAC adresu to możemy spróbować kolejnego sposobu połączenia. Zanim to zrobimy stworzymy najpierw interfejs ze znaną nam funkcją informującą nas czy mamy włączony bluetooth w urządzeniu, funkcją podtrzymującą podświetlenie i funkcją całkowitego zamknięcia aplikacji. W tym celu uruchamiamy Basic4Android i zapisujemy pusty projekt, ja zapiszę pod nazwą Program004. Oczywiście zaprojektujemy też interfejs w Designer, ostatnio łączenie i rozłączenie wykonaliśmy na dwóch przyciskach, teraz dla odmiany użyjemy tylko jednego przycisku

Obrazek

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek

Proszę zwrócić uwagę na dwie nowe rzeczy, pierwsza taka że napisz na przycisku możemy dzielić na linie za pomocą znaków CRLF czyli przejścia do początku nowej linii, druga rzecz to odczytywanie adresu MAC urządzenia, obie te rzeczy nie mają znaczenia w pracy aplikacji ale są elementami wizualnymi nadającym ciekawy wygląd interfejsu. Możemy teraz obsłużyć przycisk połączenia, tym razem nie będzie nas interesował adres MAC modułu z którym chcemy się połączyć, wygenerujemy sobie listę powiązanych już urządzeń i stworzymy możliwość wybrania naszego modułu na podstawie nazwy. Oczywiście nasz moduł powinien zostać wcześniej powiązany z urządzeniem

Obrazek Obrazek

Obrazek Obrazek

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek Obrazek

W funkcji kliknięcia przycisku sprawdzona jest Flaga przechowująca informację o tym czy jesteśmy połączeni z modułem, jeśli nie to zostają wykonane instrukcje tworzące listę sparowanych urządzeń i mamy możliwość wyboru naszego modułu. Kolejno tworzone są zmienne lokalne tyu Map, List i Int. Zmienna typu Map podobna jest do tablicy składającej się z par elementów, na jedną parę składa się nam nazwa sparowanego urządzenia i jego adres MAC. Zmienna typu List podobna jest do typu Map ale elementy są tutaj pojedyncze i my wypełniamy taką zmienną nazwami sparowanych urządzeń które pobierane są w pętli ze zmiennej typu Map. Dalej tworzymy listę wyboru w której składnikami będą elementy zmiennej List czyli nazwy, parametr -1 mówi o tym że domyślnie nie będzie zaznaczona żadna z pozycji w liście wyboru. Jeśli wybierzemy pozycję z listy wyboru to wykonujemy połączenie podając adres MAC pobrany ze zmiennej Map. Jest to już jakaś wygoda obsługi ponieważ możemy używać takiej aplikacji z wieloma różnymi modułami, wystarczy że wcześniej raz sparujemy dany moduł bluetooth z naszym urządzeniem. Dodajmy teraz do kodu timeout połączenia tak jak w poprzedniej części artykułu, niech timeout będzie miał 5 sekund i w przypadku przekroczenia tego czasu przywracamy ustawienia przycisku i tekstu w Label1. Żeby widzieć postęp timeout dodajmy w Designer jeszcze ProgressBar

Obrazek

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek

Obrazek Obrazek

Bardzo fajnie to teraz wygląda jak mamy pasek postępu, ProgressBar1 napełniany jest przez Timer2 i napełni się całkowicie kiedy osiągnie wartość 100, dlatego utworzyliśmy zmienną liczbową Timeout i w funkcji Timer2 zwiększamy tą zmienną, Timer2 wykonuje się co 50ms czyli stetne wykonanie funkcji Timer2 upłynie po pięciu sekundach, mnie ten czas wystarcza, każdy może sobie zwiększyć czas Timer2 jeśli będzie taka potrzeba. Zbajerujmy jeszcze aplikację dodając informację o nazwie i adresie modułu z którym nawiązaliśmy połączenie, otwieramy Designer i dodajemy jeszcze jeden Label

Obrazek

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek

Obrazek Obrazek

Teraz mamy ładnie pokazane z jakim modułem jesteśmy połączeni, utworzyliśmy dwie zmienne typu tekstowego Adres i Nazwa, do tych zmiennych przypisujemy wartości podwójnego elementu z Map wybranego z listy wyboru sparowanego urządznia. Po połączeniu się z modułem wpisujemy te zmienne w Label2 i tutaj tak jak w przypadku Button1 dzielimy napis na dwie linie. Właściwie mamy gotową aplikację, na koniec dodamy przyciski którymi wyślemy rozkazy do modułu

Obrazek

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek

Obrazek Obrazek

Obrazek

W funkcjach obsługi przycisków napisaliśmy wywołanie stworzonej funkcji Rozkaz z parametrem typu liczbowego, w funkcji Rozkaz wysyłamy kod znaku o numerze podanym w parametrze wywołania z dodaną wartością 48 co w rezultacie po naciśnięciu Button2 da nam wysłanie znaku 48+1 czyli "1". Następny razem poznamy jeszcze jeden sposób połączenia się z modułem.



Góra
 Zobacz profil  
 
PostNapisane: 21 lip 2012, o 12:30 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

Jeszcze jednym sposobem na połączenie się z modułem jest wyszukanie go w otoczeniu bluetooth, przy takim rozwiązaniu nie musimy już wcześniej go parować poza naszą aplikacją. Jednak każde nawiązanie połączenia przez skanowanie nie będzie wygodne ponieważ zajmuje czas na wyszukiwanie urządzeń i jest zbędne jeśli mamy już sparowany moduł. Dlatego napiszemy aplikację która pozwoli nam łączyć się na dwa sposoby, pierwszy przez wybranie modułu z listy urządzeń sparowanych i drugi przez wyszukanie modułu w otoczeniu bluetooth. Zaczniemy od napisania pierwszego trybu pracy bo znamy już ten sposób. Do tej pory używaliśmy przycisków do połączenia, żeby nie było znowu tak samo to teraz opcje połączenia zrealizujemy na napisie Label który informuje nas o połączonym urządzeniu. Reszta podstawowych funkcji będzie działała tak jak wcześniej tzn utrzymywanie podświetlenia, zamykanie całkowite aplikacji, ograniczenie czasu nawiązywania połączenia itd. Jest to nowa część artykułu więc zaczynamy od pustego projektu i zapisujemy go pod kolejną nazwą, ja mam już na liczniku Program005. Otwieramy Designer i wrzucamy do interfejsu potrzebne kafelki, dla przycisków i górnego Label generujemy funkcje kliknięcia

Obrazek

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek Obrazek

Obrazek Obrazek Obrazek

Obrazek

W kodzie nie ma nowości, znamy mechanizmy które tam działają, dodatkowo dodaliśmy programowy sposób wymuszenia pionowego trybu pracy ekranu dzięki modułowi Phone, wywołując SetScreenOrientation z parametrem 1 ustawiamy tryb pionowy, z parametrem 0 będzie tryb poziomy. Kiedy mamy włączony bluetooth możemy nawiązać połączenie przez kliknięcie w górny Label, wtedy zostanie utworzona lista wyboru "Wybierz i połącz" oraz "Szukaj i połącz", dla pierwszej możliwości mamy napisane tworzenie listy sparowanych urządzeń i możliwość połączenia z jednym dowolnie wybranym. Jeśli aplikacja na tym etapie działa to możemy zabrać się za dopisanie skanowania otoczenia po wybraniu drugiej pozycji z listy wyboru. Przedstawię najpierw w jaki sposób obsługujemy szukanie urządzeń

Kod:
Dim Admin As BluetoothAdmin
Admin.Initialize("Admin")


Skanowanie otoczenia wymaga zarządzania adapterem bluetooth w trybie administracyjnym, tworzymy więc zmienną Admin i przygotowujemy ją do pracy

Kod:
Admin.StartDiscovery


W powyższy sposób rozpoczynamy wyszukiwanie urządzeń

Kod:
Sub Admin_DeviceFound(AdminNazwa As String, AdminAdres As String)

End Sub


Podczas wyszukiwania gdy znajdziemy kolejne urządzenie zostanie automatycznie wywołana funkcja Admin_DeviceFound

Kod:
Sub Admin_DiscoveryFinished

End Sub


Kiedy skanowanie się zakończy zostanie wykonana funkcja Admin_DiscoveryFinished

Kod:
Admin.CancelDiscovery


Proces skanowania możemy przerwać w dowolnym momencie przez wywołanie CancelDiscovery. Mając te informacje możemy spróbować dopisać tryb skanowania do naszej aplikacji

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek Obrazek

Obrazek Obrazek Obrazek

Obrazek Obrazek

Możemy testować teraz aplikację, w ustawieniach bluetooth z listą powiązanych urządzeń można usunąć powiązanie z modułem żeby wykonać test parowania. Ja zmieniłbym trochę aplikację w taki sposób żeby wizualnie było widać proces skanowania otoczenia, teraz jest tylko napis Szukanie urządzeń, spróbujmy użyć Timer2 który ustawiony jest na 10 sekund i za jego pomocą na ProgressBar1 pokazywać postęp skanowania

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Bardzo fajnie to teraz wygląda. Popatrzmy jak ogólnie pracuje mechanizm skanowania. Kiedy próbujemy się połączyć z modułem który nie jest powiązany z naszym urządzeniem to zostajemy zapytani o klucz powiązania, ale do funkcji Adapter_Connected przychodzi informacja że połączenie nie powiodło się. W takim układzie niezależnie od tego czy podamy dobry czy zły klucz powiązania to i tak dostaniemy informację o nieudanym połączeniu. Ja rozwiązałem to tak że utworzyłem sobie zmienną Skanowanie którą ustawiam na True lub False, True wtedy kiedy następuje proces skanowania i False kiedy przebiega połączenie ze sparowanym urządzeniem. W funkcji Adapter_Connected niezależnie jaki będzie wynik powodzenia połączenia najpierw sprawdzam zmianną Skanowanie, jeśli jest False to znaczy że jest to informacja o sparowanym urządzeniu i wykonuję instrukcje tak jak wcześniej, jeśli jednak Skanowanie ustawione jest na True to znaczy że próbowałem się połączyć z urządzeniem którego nie ma na liście sparowanych i po podaniu klucza powiązania uruchamiam Timer3, ten timer daje chwilkę urządzniu na odświeżenie listy powiązanych urządzeń, jeśli podany został poprawny klucz powiązania to do listy trafi dodany właśnie moduł. W funkcji Timer3 która wykona się po 1 sekundzie następuje sprawdzenie listy powiązanych urządzeń i czy znajduje się w niej to urządzenie z którym próbowaliśmy się połączyć, jeśli tak to Skanowanie ustawiam na False i łączę się z tym urządzeniem, jeśli nie ma na liście urządznia to znaczy że parowanie się nie udało i otwiera się okienko informacyjne które informuje o tym zdarzeniu i pyta czy powtórzyć ten proces. Ja na ogół nie korzystam w napisanych aplikacjach ze skanowania otoczenia ponieważ prościej jest wykonać to w ustawieniach bluetooth, poza tym niepotrzebnie komplikuje się cały kod, ale gdyby była taka potrzeba to teraz wiemy jak się za to zabrać. W kolejnej części spróbujemy odbierać rozkazy tak żeby można było pogadać z mikrokontrolerem.



Góra
 Zobacz profil  
 
PostNapisane: 22 lip 2012, o 12:01 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

Potrafimy już połączyć się z modułem bluetooth na podstawie Mac adresu, przez wybranie go z listy powiązanych modułów i za pomocą wyszukiwania go w otoczeniu bluetooth, każdy z tych sposobów przydaje się zależnie od tego co konkretnie chcemy osiągnąć, nawet ten najprostszy sposób przez podanie Mac adresu także się przydaje jeśli zbudujemy układ w którym z pewnych względów ustawimy moduł do pracy w trybie niewidocznym żeby nikt nie zobaczył go skanując otoczenie bluetooth. Po połączeniu się z modułem możemy wysłać rozkazy, ale czasem będzie potrzeba nadać wartości początkowe zmiennych w naszej aplikacji po połączeniu z modułem zależne od ustawień układu do jakiego podpięty jest moduł. Zanim dokładnie o tym pogadamy to najpierw uruchomimy sobie Basic4Android i zapisujemy projekt, niech będzie to Program006, w Designer dodajmy trzy przyciski ToggleButton

Obrazek

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek

W kodzie nie ma niczego poza ułożeniem przycisków ToggleButton, uruchamiamy emulator i klikamy. Widzimy że są to przyciski które ładnie wskazują nam stan włączenia lub wyłączenia. Gdybyśmy mieli w układie diodę LED RGB to każdy z tych przycisków mógłby włączać i wyłączać odpowiedni kolor. W zdarzeniach od zmiany stanu przycisku CheckedChange moglibyśmy napisać rozkazy do sterowania kolorami

Kod:
Sub ToggleButton1_CheckedChange(Checked As Boolean)

 'wysyłamy 1 dla koloru czerwonego
   
End Sub

Sub ToggleButton2_CheckedChange(Checked As Boolean)

 'wysyłamy 2 dla koloru zielonego
   
End Sub

Sub ToggleButton3_CheckedChange(Checked As Boolean)

 'wysyłamy 3 dla koloru niebieskiego
   
End Sub


W taki sposób mamy trzy rozkazy dla kolorów, kiedy mikrokontroler otrzyma 1 to zaświeci lub wygasi kolor czerwony zależnie od tego czy w danym momencie był zaświecony czy wygaszony. Jeśli kolor był wygaszony to się zaświeci i ToggleButton1 będzie wizualnie wskazywał włączenie tego koloru. Inaczej będzie kiedy dioda już świeciła na czerwono, wtedy po wysłaniu rozkazu zostanie ona wygaszona ale ToggleButton1 pokaże że jest ten kolor włączony. Nie może tak być, możemy spróbować inaczej zaprojektować wysyłanie rozkazów

Kod:
Sub ToggleButton1_CheckedChange(Checked As Boolean)
 If ToggleButton1.Checked Then
  'wysylamy 1
 Else
  'wysylamy 2
 End If
End Sub

Sub ToggleButton2_CheckedChange(Checked As Boolean)
 If ToggleButton2.Checked Then
  'wysylamy 3
 Else
  'wysylamy 4
 End If
End Sub

Sub ToggleButton3_CheckedChange(Checked As Boolean)
 If ToggleButton3.Checked Then
  'wysylamy 5
 Else
  'wysylamy 6
 End If
End Sub


W taki sposób wysyłamy sześć rozkazów które zależne są od tego czy przycisk wskazuje na włączenie lub wyłączenie więc nigdy nie będzie sytuacji że dany kolor jest zaświecony ale przycisk wskazuje odwrotnie. Dokonajmy analizy takiej pracy. Żaden kolor nie jest zaświecony, naciskamy przycisk dla czerwonego koloru i zostaje wysłany rozkaz 1, zaświeca się kolor czerwony, naciskamy przycisk drugi raz i zostaje wysłany rozkaz 2, kolor czerwony gaśnie, kolejne naciskanie przycisku będzie wysyłać przemiennie rozkaz 1 i 2. Jest już prawie dobrze ponieważ nie ma takiej możliwości żeby włączenie któregoś koloru nie zgadzało się z wizualnym stanem przycisku. Dokonajmy jeszcze raz tej analizy. Wszystkie kolory są wyłączone, naciskamy ToggleButton1 i wysyłamy rozkaz 1, zapala się czerwony kolor, drugi raz naciskamy ToggleButton1 i wysłany zostanie rozkaz 2 który mówi mikrokontrolerowi że należy wygasić kolor czerwony. Wszystko się zgadza. Teraz co będzie kiedy kolor czerwony jest już zaświecony i uruchamiamy aplikacje, naciskamy przycisk i zostanie wysłany rozkaz 1, mikrokontroler wykona operacje zaświecenia czerwonego koloru, ale kolor już jest zaświecony więc my nie zauważymy różnicy, zmieni się jednak wizualne wskazanie przycisku, naciskamy przycisk drugi raz i wysyłamy rozkaz 2 do wygaszenia czerwonego koloru, od teraz każde kolejne naciskanie przycisku będzie działać prawidłowo. No właśnie, tylko pierwsze naciśnięcie było takie bez reakcji diody i ustawiło po prostu wizualny stan przycisku. Powinno być tak że przyciski po uruchomieniu aplikacji automatycznie wskazywałyby aktualny stan każdego koloru diody. Żeby to wykonać potrzebujemy po połączeniu się z modułem zapytać mikrokontroler o to które z kolorów są zaświecone i które wygaszone. Jeśli chodzi o sposób zapytania to mamy dwie możliwości, pierwsza jest taka że mając moduł który potrafi wystawić wysoki stan logiczny na jednym z wyprowadzeń mówiący o aktywnym połączeniu to podpinamy to wyprowadzenie pod mikrokontroler i w momencie wykrycia takiego zdarzenia wysyłamy rozkaz z informacją o kolorach. Druga możliwość jest taka że nasza aplikacja po połączeniu się sama wysyła zapytanie do mikrokontrolera. Ta druga możliwość jest trochę lepsza ponieważ nie musimy zajmować cennego wyprowadzenia w mikrokontrolerze i on sam nie musi pilnować czy przypadkiem nie pojawił się stan wysoki żeby wysłać informacje o kolorach. Decydujemy się więc na rozwiązanie drugie czyli zapytanie mikrokontrolera o wysłanie znaku umownego który zostanie rozpoznany i nastąpi wysłanie odpowiedzi. Ja wysyłam najczęściej znak "?" chr(63). Kiedy mikrokontroler otrzyma taki znak to od razu wysyła informacje do naszej aplikacji. Trzeba jeszcze pomyśleć jak będzie wyglądała taka informacja, może być ciągiem trzech znaków np 135 wszystkie kolory zaświecone, 246 wszystkie wygaszone, 235 zapalony jest kolor czerwony. Innym sposobem jest wysłanie jednego znaku który będzie liczbą określającą stan kolorów na zasadzie pojedynczych bitów np kolory wygaszone to 0 (00000000), kolor czerwony 1 (00000001), kolor zielony 2 (00000010), kolor niebieski 4 (00000100), kolor czerwony i niebieski 5 (00000101) itd. Na takie rozwiązanie się teraz zdecydujemy i kiedy będziemy mieli moduł podpięty do terminala to wyślemy ręcznie stan kolorów przez naciskanie przycisków liczbowych w komputerze. Tak najlepiej jest budować komunikację, przez terminal, wtedy wszystko dobrze widać co jest wysyłane i kiedy jest wysyłane. Dodajmy do Designer kolejne kafelki żeby zbudować działającą aplikację, od przycisku Button generujemy zdarzenie kliknięcia (Click), od trzech ToggleButton generujemy zdarzenia CheckedChange

Obrazek

Do tej pory wysyłaniem rozkazów zajmował się TextWriter, teraz zupełnie inaczej napiszemy wysyłanie i odbieranie rozkazów, poniżej przedstawię kompletny kod i potem go opiszemy

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek Obrazek

Obrazek Obrazek

Obrazek

Od teraz po połączeniu możemy do terminala wpisywać ręcznie liczby z klawiatury które będą na zasadzie bitowej włączać i wyłączać wizualne stany przycisków ToggleButon. Omowimy trochę kod. Nowością jest sposób wysyłania i odbierania rozkazów, zajmuje się tym strumień z modułu RandomAccessFile. Tworzymy zmienną Strumien i przygotowujemy ją do pracy w trybie wysyłania i odbierania zaraz po nawiązaniu połączenia z modułem w funkcji Adapter_Connected. Wysyłanie i odbieranie rozkazów oparte jest o tablice bajtowe dlatego np w funkcji Rozkaz wysyłamy łańcuch znakowy przekształcony na tablicę bajtową. Została stworzona zmienna Nadawanie która ustawiona jest na False lub True, jest ona potrzebna do blokowania wywoływania zdarzeń od zmiany stanu ToggleButton1,2,3. Chodzi o to że kiedy aplikacja odbierze informacje o kolorach diody to ustawi wszystkie ToggleButton, ale ustawiając je zmienia się oczywiście ich stan i wtedy zostałby wysyłane rozkazy. Zmienną Nadawanie ustawiamy w funkcji odbierania Strumien_NewData. Opiszemy tą funkcję trochę bardziej bo jest ciekawa

Kod:
Sub Strumien_NewData (Buffer() As Byte)
 Dim x As String
 Nadawanie=False
 x=BytesToString(Buffer, 0, Buffer.Length, "UTF8")
 Try
  x=Bit.ToBinaryString(x)
  x=NumberFormat(x, 3 ,0)
  If x.CharAt(2)=0 Then ToggleButton1.Checked=False
  If x.CharAt(2)=1 Then ToggleButton1.Checked=True
  If x.CharAt(1)=0 Then ToggleButton2.Checked=False
  If x.CharAt(1)=1 Then ToggleButton2.Checked=True
  If x.CharAt(0)=0 Then ToggleButton3.Checked=False
  If x.CharAt(0)=1 Then ToggleButton3.Checked=True
 Catch
 End Try
 Nadawanie=True
End Sub


Kiedy nadlecą dane z modułu do naszej aplikacji to automatycznie zostanie wywołana funkcja Strumien_NewData z parametrem w postaci tablicy bajtów jakie zostały przysłane. My przekształcamy sobie te bajty na łańcuch znakowy BytesToString, dalej taki łańcuch przekształcamy na postać binarną Bit.ToBinaryString czyli np jeśli łańcuch znakowy to "5" wtedy wygląda on już tak "101", kiedy ma wartość 2 to wygląda tak "10" czyli nie są dopisywane zera z przodu. My potrzebujemy informacji o trzech bitach więc musimy sami dopisać sobie zera formatując łańcuch znakowy NumberFormat(x, 3 ,0). Po tej operacji dla informacji która została odebrana np 2 mamy taki łańcuch znakowy "010". Widać już że chodzi o zapalenie zielonego koloru i wygaszenie pozostałych. Sprawdzamy teraz co znajduje się na kolejnym miejscu w łańcuchu znakowym przez CharAt które zwraca znak z łańcucha o indeksie podanym w parametrze, indeks zaczyna się od zero. My mamy łańcuch który posiada trzy znaki więc maksymalny indeks to 2. Bity kolejno ułożone są od lewej strony czyli od końca łańcucha znakowego, w takim razie pierwszy kolor czerwony będzie na trzecim miejscu, drugi kolor zielony będzie na drugim miejscu i trzeci kolor niebieski będzie na pierwszym miejscu. Zależnie teraz czy w łańcuchu jest zero albo jeden to zaznaczamy programowo odpowiedni ToggleButton. Po zaznaczeniu zezwalamy na nadawanie rozkazów od zmiany ToggleButton1,2,3 przez ustawienie zmiennej Nadawanie na True. Myślę że mechanizm pracujący w tej funkcji jest bardzo łatwy do zrozumienia. Musimy pamiętać jednak że my wysyłając z klawiatury znaki nie wysyłamy żadnego tam 1,2,3.. tylko kod znaku dla 1 chr(48+1), dla 2 chr(48+2) itd. W taki też sposób powinien mikrokontroler wysłać informację czyli chr(48+informacja). Na podstawie tej aplikacji możemy budować dowolne aplikacje wymieniające informacje z mikrokontrolerem. W następnej części spróbujemy jeszcze raz sterować diodą LED RGB ale podpiętą pod wyprowadzenia PWM i płynnie regulować jej barwę na trzech potencjometrach, oczywiście po uruchomieniu aplikacji suwaki będą musiały ustawić się automatycznie według aktualnej barwy diody.



Góra
 Zobacz profil  
 
PostNapisane: 23 lip 2012, o 21:55 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

Powoli ale nie ubłaganie zbliżamy się już do końca artykułu, w tej ostatniej części napiszemy aplikację która steruje płynnie kolorami diody LED RGB i przy nawiązaniu połączenia automatycznie ustawi suwaki potencjometrów na aktualne wartości kolorów. Aplikacja będzie o tyle ciekawa że trzeba wysyłać i odbierać rozkazy składające się z kilku znaków i odpowiednio przetworzyć je na użyteczne informacje. Zaczynamy od nowego projektu, będzie to już Porogram007, zapisujemy i otwieramy Designer żeby dodać potrzebne elementy interfejsu składające się na naszą aplikację

Obrazek

Rzecz o której wcześniej nie wspomniałem to sposób generowania zdarzeń, do tej pory klikaliśmy prawym przyciskiem myszki na wybrany element i z rozwijanego menu wybieraliśmy interesujące nas zdarzenie

Obrazek

Jeśli takich elementów było więcej to trochę trzeba było się naklikać, jest inne rozwiązanie które przedstawię na poniższych screenach

Obrazek

Obrazek

Kolejnym fajnym ułatwieniem w Basic4Android jest podpowiadanie nazw funkcji które piszemy, wystarczy napisać słowo Sub i nacisnąć klawisz TAB. Jeśli mamy już gotowy interfejs ze zdarzeniami od Button1 i SeekBar1,2,3 to zapisujemy i zamykamy Designer. Teraz napiszmy podstawową wersję kodu w której ułożymy wszystkie elementy.

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek Obrazek

Obrazek Obrazek

Aplikacja łączy się z modułem i po połączeniu można regulować suwakami, nic poza tym się nie dzieje bo nie napisaliśmy jeszcze obsługi wysyłanych i odebranych rozkazów. Jest jednak mała zmiana przy nawiązywaniu połączenia z modułem. W testach czytelników zdarzył się przypadek w którym aplikacja nie potrafiła nawiązać połączenia, sprawa oczywiście została pomyślenie rozwiązana. Chodziło o to że podawaliśmy MAC adres modułu i reszta odbywała się automatycznie. W tym jednym przypadku ten proces nie mógł opierać się na pełnej automatyzacji i należało podać oprócz adresu MAC jeszcze kanał. Dlatego teraz lepiej będzie pisać aplikacje łączące się z modułami podając ten kanał żeby w przyszłości jeśli zajedzie potrzeba łączenia się z takim modułem nie było niespodzianek. Tak wyglądało łączenie się bez podania kanału

Kod:
Adapter.Connect(Adres)


od teraz łączenie będziemy realizować w następujący sposób

Kod:
Adapter.Connect3(Adres,1)


Jeśli mamy omówioną już tą najważniejszą zmianę to możemy zając się pracą naszej aplikacji. Potrzebujemy opracować wysyłanie i odbieranie informacji. Nie zajmiemy się obiema rzeczami na raz ponieważ nie mamy w głowach dwóch lub czterech rdzeni obliczeniowych i skupiamy się na jednej rzeczy doprowadzając ją do porządku. Zacznijmy więc od odbierania informacji po połączeniu się z modułem. Naszym założeniem jest dioda RGB i suwakami chcemy płynnie regulować każdy z kolorów w zakresie 0-255. Taki też zakres mają SeekBar1,2,3 w aplikacji. Trzeba więc odczytać odebraną informację i ustawić ich wskazania żeby pokazywały aktualny stan każdego z kolorów. Możliwości na postać samej informacji jest wiele, my jednak chcielibyśmy testować w terminalu wszystko co się dzieje więc musimy zdecydować się na taki sposób żeby można było zasymulować stan początkowy za pomocą klawiatury w komputerze. Ja wymyśliłem postać informacji zawierającą się aż w 10ciu znakach ale za to bardzo łatwą do zrozumienia i do wklepania w terminalu. Każdy kolor ma postać liczbową składającą się z trzech znaków w zakresie 000-255, dla trzech kolorów to jest już dziewięć znaków i dziesiąty znak to enter który potwierdza że informacja jest kompletna. Poniżej przedstawię kod z dopisanym takim sposobem odbierania i przetworzenia informacji

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


W kodzie została utworzona globalna zmienna Odebrane typu string i ustawiona jest w funkcji pierwszego uruchomienia na pusty łańcuch znakowy. Reszta kodu jest taka sama oprócz uzupełnienia funkcji wywołanej po odebraniu znaku i tą funkcję teraz omówimy bardziej szczegółowo, choć wygląda może skomplikowanie to jej działanie jest naprawdę bardzo proste

Kod:
Sub Strumien_NewData (Buffer() As Byte)
 Dim Suwak1 As Int
 Dim Suwak2 As Int
 Dim Suwak3 As Int
 Nadawanie=False
 Odebrane=Odebrane & BytesToString(Buffer, 0, Buffer.Length, "UTF8")
 If Odebrane.Length=10 Then
  If Odebrane.EndsWith(Chr(13))Then
   Try
    Suwak1=Odebrane.SubString2(0,2+1)
    Suwak2=Odebrane.SubString2(3,5+1)
    Suwak3=Odebrane.SubString2(6,8+1)
    If Suwak1>=0 AND Suwak1<=255 Then SeekBar1.Value=Suwak1   
    If Suwak2>=0 AND Suwak2<=255 Then SeekBar2.Value=Suwak2   
    If Suwak3>=0 AND Suwak3<=255 Then SeekBar3.Value=Suwak3
   Catch
   End Try
  End If
  Odebrane=""
 End If
 Nadawanie=True
End Sub


Popatrzmy na tą funkcję i spróbujmy opisać jej działanie. Każdy bajt jaki przychodzi do funkcji jest od razu zamieniany na znak i dodawany jest do zmiennej Odebrane. Dalej sprawdzamy czy ta zmienna przechowuje już 10 znaków czyli 9 dla wartości kolorów i 1 dla entera, jeśli znaków jest mniej to nic się nie dzieje. Jeśli znaków jest już dokładnie 10 to teraz sprawdzamy czy na ostatniej pozycji w tym łańcuchu znakowym znajduje się znak entera chr(13), jeśli się nie znajduje to nie wykonujemy instrukcji w tym warunku i ustawiamy tylko zmienną Odebrane na pusty łańcuch znakowy. Jeśli jednak na końcu tego łańcucha znakowego znajduje się enter to do utworzonych trzech zmiennych lokalnych próbujemy dodawać kolejne trzy znaki z tego łańcucha zamienione na liczby. SubString2 wyciąga z łańcucha te znaki które zawarte są w indeksach podanych w parametrach SubString2 nie wliczając ostatniego znaku tzn dla (0,2) otrzymamy znaki pierwszy i drugi bez trzeciego. Kiedy mamy już pobrane wartości dla trzech potencjometrów to sprawdzamy najpierw czy zawierają się one w przedziale 0-255, jeśli tak to ustawiamy SeekBar1,2,3. Wychodząc z warunku oczywiście znowu ustawiamy zmienną Odebrane na pusty łańcuch znakowy. Na samym początku i końcu całej ten funkcji ustawiana jest zmienna Nadawanie która nie zezwala na wysyłanie rozkazów od zmiany położenia suwaków na naszych potencjometrach kiedy ustawiane są programowo. Od teraz po uruchomieniu aplikacji możemy do terminala wpisać np 123090006 i nacisnąć enter, suwaki powinny od razu powędrować w odpowiednie miejsca

Obrazek

Postać odebranych informacji możemy dowolnie zmieniać, skracać, kombinować na wszystkie sposoby, ja przedstawiłem przykład dzięki któremu możliwe jest testowanie odebranych informacji wysyłanych ręcznie za pomocą terminala. Taki sam sposób przedstawię przy wysyłaniu z aplikacji ustawień kolorów naszej diody. Kiedy nie mamy podpiętego układu do modułu i projektujemy komunikację na poziomie terminala to dobrze jest widzieć i szybko interpretować sobie przychodzące ustawienia kolorow, dlatego tutaj też wykorzystamy zapis 9cio znakowy w którym kolorami będą komplety trzech kolejnych znaków w formie numerycznej, poniżej przykład kodu z dopisaną taką formą wysyłania

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Utworzyliśmy globalną zmianną Zmiana która będzie przechowywała informacje o tym czy któryś z suwaków został zmieniony. Zmienna ustawiana jest z zdarzeniach każdego SeekBar. Uruchomiony został także nowy timer3 który cyklicznie sprawdza czy jest jakaś zmiana w suwakach, jeśli tak to wysyła informacje do terminala, zobaczmy dokładnie jak formatowana jest taka informacja

Kod:
Sub Timer3_tick
 Dim x As String
 If Zmiana=True Then
  x=NumberFormat(SeekBar1.Value, 3 ,0)
  x=x & NumberFormat(SeekBar2.Value, 3 ,0)
  x=x & NumberFormat(SeekBar3.Value, 3 ,0)
  Rozkaz( x & Chr(13) & Chr(10) )
  Zmiana=False
 End If
End Sub


Tworzymy lokalną zmienną x i jeśli któryś z suwaków zmienił swoje położenie to zapisujemy do tej zmiennej kolejne ustawienia koloru przez pobranie wartości liczbowej SeekBar i formatowanie tej wartości do stringa z dopisanymi zerami aby końcowy wynik miał trzy znaki w łańcuchu. Na koniec do zmiennej x dodajemy jeszcze znaki przejścia do nowej lini i powrotu do początku żeby w terminalu widzieć kolejno przychodzące liniki z ustawieniami

Obrazek

Obrazek

Na screenach widzimy że ostatnia informacja w terminalu zgadza się z ustawieniami suwaków. Ktoś mógłby pomyśleć że bez sensu tworzony jest trzeci timer skoro można było w zdarzeniach od SeekBar wysyłać informacje. Zgadza się, ale suwaki ustawiają się bardzo szybko, tak szybko jak szybki mamy palec którym nastawiamy SeekBar i żeby nie generować niepotrzenych wysyłek informacji to wysyłamy je co 100ms, a w przypadku regulacji kolorów diody jest zupełnie wystarczające. Wysyłając informacje sposobem jaki opisałem tzn za pomocą strumienia nie blokujemy aplikacji, informacje będą wysyłane w tle i kiedy będzie ich bardzo dużo to będą się kolejkowały i wysyłały się tak długo jak będzie trzeba. Ja testowałem taki sposób z ustawieniem bitrate 115200 i 10 znaków w informacji, nie było żadnych opóźnień, jednak mimo wszystko dla regulacji koloru diody zdecydowałem się na rozwiązanie z timerem. Inną sprawą jest jeszcze zajętość mikrokontrolera obsługą przerwania od odebranych danych biorąc pod uwagę ich ilość i cykliczność ich przychodzenia ale to już nie temat na ten artykuł. Myślę że zachęciłem wiele osób do środowiska Basic4Android pokazując jak przyjemnie można w nim projektować aplikacje do sterowania modułami bluetooth, czas który zaoszczędzimy budując aplikację w Basic4Android możemy poświęcić na resztę całego układu od strony mikrokonrolera lub po prostu wyjść na spacer albo oddać swoją uwagę rodzinie i innym przyjemnością życia. Bardzo dziękuję czytelnikom za poświęcony czas na przeczytanie w całości artykułu. Pozdrawiam i życzę pomysłowych aplikacji.

Damian (ariek44)



Góra
 Zobacz profil  
 
PostNapisane: 29 lip 2012, o 12:58 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

Witam, reakcja czytelników na forum spowodowała otwarcie tego tematu ponieważ cieszy się on dużym zainteresowaniem co nie jest dziwne ponieważ Basic4Android to rzeczywiście świetne narzędzie. Napiszemy jeszcze jedną aplikację, ale inną niż pozostałe, inną w ten sposób że sterowanie nie będzie się odbywało już przez klikanie w elementy interfejsu. Tym razem do mikrokontrolera będziemy wysyłać rozkazy przychodzące z czujnika ruchu w telefonie, gdybyśmy mieli mały napęd lub zespół napędowy to można byłoby sterować całą mechaniką przez przechylanie urządzenia. Bardziej pomysłowi konstruktorzy wykonać mogą ramię robota oparte na serwo mechanizmach które naśladowałoby ruchy naszego ramienia poprzez odczyty z czujników ruchu urządzenia trzymanego w naszej dłoni. Ja kiedyś miałem inny pomysł którego nigdy nie wykonałem ze względu na ciągły brak czasu, pamiętamy taką starą mechaniczną grę w której na płaskim krążku znajdowały się otworki i trzeba było maleńką kulką umiejętnie manewrować pomiędzy nimi prowadząc ją z jednego końca do drugiego, mój pomysł polegał na tym żeby wykonać to w dużej wersji na powierzchni 1m x 1m lub więcej, powierzchnia byłaby kwadratowa, na rogach zamontowane byłyby serwa które przez odpowiednie ruchy urządzeniem podnosiłyby lub obniżały wybrane serwo lub zespół serw co prowadziłoby do ustawiania całej powierzchni pod różnymi kątami, oczywiście na takiej powierzchni poruszałaby się np kulka łożyskowa która powinna omijać nawiercone otwory. Pomysłów może być naprawdę bardzo wiele. My tutaj nie będziemy budować żadnej konstrukcji mechanicznej, za to zbudujemy aplikację która potrafi odczytywać wartości z czujnika ruchu w urządzeniu, oprócz tego pokażę bardzo fajne dodatki które możemy dodawać do aplikacji czyniąc ją bardziej ciekawą. Zaczniemy od pustego projektu który zapisujemy pod kolejną nazwą np Program008, w Designer dodajemy potrzebne kafelki, od Button1 generujemy funkcję kliknięcia

Obrazek

Uzupełniamy kod znanymi nam już funkcjami połączenia z modułem i ułożeniem elementów interfejsu

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek Obrazek Obrazek

Obrazek Obrazek

Widzimy że ułożenie w pionie Label1 jest takie samo jak Button1, jest to celowo wykonane ponieważ na Label1 mamy napisy zaś od Button1 mamy funkcję kliknięcia i za niedługo będzie dla nas pełnił rolę bardzo ciekawego tła dla napisu na Label1. Polecenie Label1.BringToFront mówi że chcemy przenieść Label1 na pierwszy plan tzn ma być nad Button1, nie pod nim ponieważ nie widzielibyśmy napisów. W tej chwili aplikacja jest mało ciekawa, działa połączenie i rozłączenie z modulem bluetooth ale nic poza tym. Dodajmy teraz naszemu Activity ciekawego koloru, niech nie będzie to kolor jednolity, zrobimy ładny gradient w kolorach od czerwonego do niebieskiego układającego się od górnego lewego rogu ekranu do dolnego prawego

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Utworzyliśmy zmienną GradientActivity i w funkcji pierwszego uruchomienia podaliśmy sposób ułożenia gradientu tzn TopLeft i BottomRight oraz dwu elementową tablicę zawierającą nasze kolory. Mamy na urządzeniach kolorowe wyświetlacze więc prosiło się żeby nadać naszej aplikacji trochę koloru. To samo teraz zrobimy z przyciskiem, ale tym razem ja dam kolory bieli i czerni oraz ustawię gradient ułożony od górnego prawego rogu przycisku do dolnego lewego

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Mnie się to bardzo podoba, ale to nie koniec efektów, teraz sprawimy żeby nasz przycisk obracał się, nada to aplikacji bardzo ciekawego wyglądu. Osią obrotu przycisku będzie jego punkt środkowy wyznaczony przekątnymi kwadratu, obrót będzie wykonywał się kolejno w jedną i drugą stronę zataczając pełne koła

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Utworzyliśmy zmienną AnimButton, we właściwościach przycisku ustawiliśmy go jako element poddany rotacji w zmiennej AnimButton, rotacja będzie zaczynać się od kąta 0 do 359, cykl obrotu będzie trwał 3000ms, obrób będzie powtarzany w nieskończoność (-1) i tryb obrotu będzie rewersyjny tzn najpierw w jedną stronę i potem w drugą. Przycisk podczas rotacji delikatnie wychodzi krawędziami poza górny obszar Activity, to niczemu nie przeszkadza, ale można byłoby obliczyć położenie w pionie przycisku ze wzoru na przekątną kwadratu czyli szerokość boku pomnożoną przez pierwiastek drugiego stopnia z liczby dwa. Żeby jednak nie robić niepotrzebnego zamętu zostawimy to tak w tej chwili. Proszę sobie zobaczyć na własne oczęta jak fajnie to wygląda, może któryś z czytelników stworzy krótki filmik i zamieści w temacie z dyskusją pracę tej aplikacji?

W tym momencie przerwiemy sobie pisanie, kiedy wrócę z niedzielnego spaceru dopiszemy dalsze funkcje aplikacji.



Góra
 Zobacz profil  
 
PostNapisane: 29 lip 2012, o 17:08 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

Mamy gotowy interfejs to teraz spróbujemy odczytywać wartości z czujnika ruchu w trzech osiach x,y,z. Wartości te przypiszemy do Label11,12,13 i zobaczymy w jakich zawierają się one przedziałach liczbowych, ciekawy jestem czy w każdym urządzeniu jest to taka sama wartość czy różni się ona zależnie od modelu urządzenia i zastosowanego tam czujnika, fajnie byłoby gdyby czytelnicy podali swoje wartości i model urządzenia w temacie z dyskusją

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Utworzyliśmy zmienną CzujnikRuchu która będzie przechwytywać wskazania z czujnika, w funkcji pierwszego uruchomienia napisaliśmy że będzie to czujnik ruchu TYPE_ACCELEROMETER, w funkcji Activity_Resume odcztytujemy wartości z tego czujnika i będzie to następowało cyklicznie, każda zmiana wartości będzie wywoływać funkcję CzujnikRuchu_SensorChanged, w tej funkcji przypisujemy odczytane wartości do Label11,12,13. U mnie wartości te zawierają się w przedziale -10 do +10, wartości te są podawane jako liczba zmiennoprzecinkowa więc osiągamy w miarę dużą dokładność. Mając aplikację pracującą w trypie pionowym oś X będzie zmieniała się kiedy urządzenie zostanie pochylone podnosząc lub obniżając prawą i lewą stronę, oś Y będzie zmieniała się kiedy urządzenie będzie przechylało się unosząc górę i dół urządzenia, oś Z będzie zmieniać się kiedy urządzenie będziemy odwracać wyświetlaczem do dołu lub do góry. Oś Z będzie w większości aplikacjach nie używana i wystarczą nam tylko osie X i Y dlatego zrezygnujemy w tej chwili z odczytu tej wartości. Mamy dwa elementy ProgressBar które domyślnie posiadają maksymalny zakres od 0 do 100. Żeby pokazać na nich wskazania osi X i Y trzeba dokonać prostych operacji matematycznych, spróbujmy to sobie rozpisać

najpierw do wartości dodamy 10 żeby mieć zakres 0 do 20 bez liczb ujemnych

Kod:
Label11.Text = "X " & XYZ(0) + 10


następnie wartość tą mnożymy przez 5 żeby uzykać przedział 0 do 100

Kod:
Label11.Text = "X " & ( XYZ(0) + 10 ) * 5


ostatnią rzeczą będzie zaokrąglenie liczby zmiennoprzecinkowej do całkowitej

Kod:
Label11.Text = "X " & Round( ( XYZ(0) + 10 ) * 5 )


Zobaczmy jak będzie to wyglądało teraz w ProgressBar i Label

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Mamy dobrze pracujące ProgressBar, ja jednak chciałbym coś tu zmienić, niech ProgressBar pokazują tak jak teraz od 0 do 100, ale Label niech mają wartość bardziej dla nas przydatną tzn od 0 do 255

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Jest dobrze, został nam Label13 na którym miała być wartość osi Z, ale zamiast tego będziemy sobie wskazywali wartość czujnika magnetycznego tzn takiego który będzie nam pokazywał przesunięcie urządzenia względem pola magnetycznego ziemi jak kompas w pełnym zakresie 360 stopni

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Podobnie jak przy czujniku ruchu tutaj dla czujnika magnetycznego utworzyliśmy zmienną CzujnikMagnetyczny i odczytujemy wartości w funkcji Activity_Resume, zmiana wartości wywoła nam funkcję CzujnikMagnetyczny_SensorChanged skąd pobieramy kąt położenia urządzenia względem pola magnetycznego ziemi i zapisujemy tą wartość w Label13, dodatkowo dodaliśmy znak ascii symbolizujący stopnie. Ostatnie co zostało do zrobienia to wysłanie wszystkich odczytanych wartości do mikrokontrolera uzupełniając funkcję Timer3_tick bo tam cyklicznie wysyłane będą informacje, ale zamiast tworzyć globalne zmienne przechowujące wartości z czujników napiszemy wyciąganie informacji z Label11,12,13. Wysłanie informacji z Label opiszemy w następnej części.

Teraz dopiszę tylko szybko że bardzo ładny efekt samego obracającego się przycisku można wykonać przez zaokrąglenie jego wierzchołków, wtedy podczas rotacji kiedy przycisk będzie zupełnie okrągły zobaczymy tylko obracający się w nim gradient, wystarczy dopisać do właściwości przycisku poniższy fragment

Kod:
GradientButton.CornerRadius=Button1.Height


Obrazek



Góra
 Zobacz profil  
 
PostNapisane: 29 lip 2012, o 21:41 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 cze 2012
Posty: 135
Pomógł: 1

W tej części zajmiemy się wysyłaniem wartości z czujników do mikrokontrolera. Użyjemy tego samego sposobu który już znamy i potrafimy obserwować przychodzące dane w terminalu, wyślemy więc trzy sekwencje liczbowe składające się razem z dziewięciu znaków, trzy dla osi x, trzy dla osi y i trzy dla kąta. Mamy przygotowaną taką funkcję Timer3_tick

Kod:
Sub Timer3_tick
 Dim x As String
 If Zmiana=True Then
  'tu bedzie wysylanie
  Zmiana=False
 End If
End Sub


Zaczniemy przede wszystkim od tego że musimy sprawdzić czy Label11,12,13 nie są puste, być może istnieje możliwość że czujnik ruchu odczyta dane i ustawi zmienną Zmiana na True ale czujnik magnetyczny jeszcze nie zdąży dokonać odczytu, sprawdzimy więc czy Label nie są puste

Kod:
Sub Timer3_tick
 Dim x As String
 If Zmiana=True Then
  If Label11.Text.Length>0 AND Label12.Text.Length>0 AND Label13.Text.Length>0 Then

  End If
  Zmiana=False
 End If
End Sub


Teraz trzeba wyciągnąć wartości z Label, najlepiej by było żebyśmy wcześniej formatowali wartości w Label do postaci składającej się z trzech liczb, ale nie zrobiliśmy tego i nie pójdziemy na łatwiznę, wyciągniemy dane z Label takie jak są

Kod:
Sub Timer3_tick
 Dim x,y,a As String
 If Zmiana=True Then
  If Label11.Text.Length>0 AND Label12.Text.Length>0 AND Label13.Text.Length>0 Then
   For i=0 To Label11.Text.Length-1
    If IsNumber( Label11.Text.CharAt(i) ) Then x=x & Label11.Text.CharAt(i)
   Next
   For i=0 To Label12.Text.Length-1
    If IsNumber( Label12.Text.CharAt(i) ) Then y=y & Label12.Text.CharAt(i)
   Next
   For i=0 To Label13.Text.Length-1
    If IsNumber( Label13.Text.CharAt(i) ) Then a=a & Label13.Text.CharAt(i)
   Next
  End If
  Zmiana=False
 End If
End Sub


Utworzyliśmy sobie trzy zmienne x,y,a i kolejno w pętlach sprawdzamy czy dany Label przechowuje w łańcuchu znakowym liczbę, jeśli tak to wyciągamy ten znak i dodajemy odpowiednio do x,y,a

Kod:
Sub Timer3_tick
 Dim x,y,a As String
 If Zmiana=True Then
  If Label11.Text.Length>0 AND Label12.Text.Length>0 AND Label13.Text.Length>0 Then
   For i=0 To Label11.Text.Length-1
    If IsNumber(Label11.Text.CharAt(i)) Then x=x & Label11.Text.CharAt(i)
   Next
   For i=0 To Label12.Text.Length-1
    If IsNumber(Label12.Text.CharAt(i)) Then y=y & Label12.Text.CharAt(i)
   Next
   For i=0 To Label13.Text.Length-1
    If IsNumber(Label13.Text.CharAt(i)) Then a=a & Label13.Text.CharAt(i)
   Next
   x=NumberFormat(x,3,0)
   y=NumberFormat(y,3,0)
   a=NumberFormat(a,3,0)
   Rozkaz(x & y & a & Chr(13) & Chr(10))
  End If
  Zmiana=False
 End If
End Sub


Jeśli mamy wyciągnięte liczby to wystarczyło je formatować do postaci trzech znaków i wszystko wysłać ze znakami nowej linii i przejścia do początku, w terminalu powinniśmy zobaczyć przychodzące dane

Obrazek

Widzimy że pierwszy znak w terminalu to znak zapytania, jest to nasz znak który użyliśmy w poprzedniej aplikacji i miał on zapytać mikrokontroler o wartości początkowe, tutaj nie korzystamy z tego, ale możemy sobie uzupełnić funkcję odbierania danych, po odebraniu znaków z terminala zakończonych enterem pokażemy co przyszło w tytule aplikacji

Kod:
Sub Strumien_NewData (Buffer() As Byte)
 Odebrane=Odebrane & BytesToString(Buffer, 0, Buffer.Length, "UTF8")
 If Odebrane.EndsWith(Chr(13))Then
  Activity.Title=Odebrane
  Odebrane=""
 End If
End Sub


Obrazek

Poniżej kompletny kod

Składnia: [ Pobierz ] [ Ukryj ]
język basic4gl
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Myślę że od teraz nasze aplikacje będą miały ciekawy wygląd i zachęcały samym interfejsem do korzystania z nich. Pozdrawiam serdecznie czytelników i użytkowników forum.atnel.pl



Góra
 Zobacz profil  
 
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Ten wątek jest zablokowany. Nie możesz w nim pisać ani edytować postów.  [ Posty: 12 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO