Autor: Dondu
W poprzednich dwóch artykułach (cz. I i cz. II) poznałeś zasady tworzenia aplikacji dla systemu Android.
W niniejszym artykule utworzymy kolejną aplikację, która będzie służyła do prostego sterowania diodą LED podłączoną do mikrokontrolera AVR.
Komunikację pomiędzy smartfonem i mikrokontrolerem Bluetooth zapewni nam moduł HC-05, który dokładnie opisałem w artykule HC-05 (Bluetooth) - Informacje podstawowe, a który kosztuje około 25zł (2014r.).
W przeciwieństwie do poprzednich artykułów, w których wyjaśniłem dokładnie jak tworzyć aplikację, w niniejszym nie będę już szczegółowo opisywał jak wykonywać aplikację w środowisku App Inventor, a skupimy się przede wszystkim na layoucie (wyglądzie aplikacji), części programowej oraz części dot. mikrokontrolera ATmega8 i jego programu.
W artykule znajdziesz także plik z gotową aplikacją oraz plik projektu AI Inventora.
Założenia dot. funkcjonalności
Zadania jakie postawimy przed aplikacją nie będą skomplikowane. Na żądanie aplikacji mikrokontroler powinien:
- przedstawić się w postaci komunikatu tekstowego,
- sterować diodą LED (włączyć, wyłączyć lub zmienić stan na przeciwny).
Pozwoli nam to poznać sposoby komunikacji w obie strony pomiędzy smartfonem i mikrokontrolerem.
Aplikacja LED_MASTER v.1.0
Zacznę nietypowo od pokazania jak działa gotowa aplikacja. Po jej uruchomieniu pojawi się ekran powitalny:
Po kliknięciu przycisku listy urządzeń pojawia się wykaz sparowanych ze smartfonem:
Po wybraniu właściwego (w moim przypadku HC-05) schowany zostaje przycisk otwierania listy, a w jego miejsce pojawiają się inne:
W tym momencie aplikacja wysyła do mikrokontrolera komendę AT+START, a mikrokontroler odpowiada tekstem powitalnym, który aplikacja od razu wyświetla w komponencie Label1:
Funkcje przycisków są dość jasno opisane, a jak działają możesz zobaczyć na poniższym filmie:
Layout aplikacji
W oknie App Inventora aplikacja wygląda następująco:
Do ekranu głównego Screen1 dodałem w jego właściwościach tło BackgroundImage oraz ikonę aplikacji (Icon) 48 x 48 pikseli. Dodałem także komponent timera Clock, o którym piszę poniżej.
Zielonymi strzałkami zaznaczyłem "dziwne czarne linie", które w poprzedniej aplikacji nie występowały. Są to komponenty z zakładki Layout, które porządkują układ komponentów na ekranie i są odpowiednikami elementów DIV i TABLE w HTML.
Ponieważ komponenty wzajemnie się wykorzystują, aby łatwiej było zobaczyć jak są rozmieszczone i jakie mają właściwości pokazuję poniżej wszystkie cztery z nich po usunięciu tła:
HorizontalArrangement2 |
VerticalArrangement1 |
HorizontalArrangement3 |
TableArrangement1 |
Aby jeszcze dokładniej zobrazować zależności pomiędzy rozmieszczeniem komponentów, przygotowałem pokolorowany screen:
Zauważ, że w kolumnie Components drzewo elementów jednoznacznie określa, który element znajduje się wewnątrz innego.
HorizontalArrangement2 ma na celu jedynie wprowadzić odstęp pomiędzy górną krawędzią ekranu a elementami znajdującymi się poniżej, dlatego istotne jest by ustawić jego wysokość (właściwość High) na co najmniej kilka punktów.
Label1 na początku nie zawiera żadnego tekstu. Aplikacja wstawi w ten komponent tekst przesłany z mikrokontrolera. Aby więc pokazać ten element na ekranie musiałem go kliknąć.
We właściwościach komponentu TableArrangement1 ustawiony jest jeden wiersz i trzy kolumny. W momencie dodawania (trzymając i przemieszczając myszką) przycisków Button2, Button3 i Button4, komponent TableArrangement1 będzie podzielony na wybraną ilość wierszy i kolumn, czego nie widać na rysunku powyżej.
Program
Program omówię przedstawiając poszczególne funkcjonalności.
Wybranie urządzenia Bluetooth
Najpierw należy pobrać dane o sparowanych urządzeniach Bluetooth i przypisać je do listy ListPicker:
Następnie należy zareagować na wybranie urządzenia z listy ListPicker1:
Po wybraniu urządzenia Bluetooth wykonane zostaną wg kolejności:
- Pobranie z ListPicker1 danych o wybranym urządzeniu i próba połączenia z nim. Jeżeli próba się nie powiedzie poniższe punkty nie zostaną wykonane.
- Włączenie widoczności pozostałych komponentów zawartych w komponencie VerticalArrangementr1.
- Wyłączenie widoczności przycisku listy urządzeń Bluetooth (ListPicker1).
- Wysłanie do mikrokontrolera komendy: AT+START
- Wysłanie do mikrokontrolera znaku końca tekstu (null, czyli zero).
Kolejnym blokiem jest blok odpowiedzialny za odebranie wysłanego z mikrokontrolera komunikaty potwierdzającego poprawną komunikację. Blog ten jest oparty o komponent Clock:
który jest timerem wykonującym przydzielone mu zadania co określony interwał czasowy podany w milisekundach. Ustawiłem 1000ms, czyli jedną sekundę i zleciłem mu następujące zadania:
Blok ten:
- sprawdza, czy smartfon połączony jest z jakimś urządzeniem Bluetooth. Jeśli nie ma połączenia, to poniższe czynności nie są wykonywane.
- sprawdza, czy są jakieś dane do odebrania (>0). Jeśli nie, to poniższe czynności nie są wykonywane.
- wykonuje pętlę while dopóki są jakieś dane do odebrania. W pętli while do globalnej zmiennej tekst_odebrany dodaje pojedynczo kolejne odebrane znaki .
- po zakończeniu pętli (odebraniu wszystkich znaków) pokazuje odebrany ciąg znaków ładując go do komponentu Label1.
- przypisuje zmiennej tekst_odebrany pusty ciąg znaków, by ewentualny kolejny ciąg znaków mógł być załadowany od początku.
Zamiast zmiennej tekst_odebrany można oczywiście dodawać tekst od razu do komponentu Label1. Ja użyłem zmiennej, by pokazać jak ich używać oraz po to, by tekst pojawił się od razu w całości, a nie sukcesywnie wraz z odbieranymi znakami.
Przyciski sterujące diodą LED
W aplikacji są trzy przyciski sterujące stanem diody LED: Włącz, Wyłącz oraz Zmień stan na przeciwny. Przyciski te wysyłają komendy AT:
- Włącz: AT+LEDON
- Wyłącz: AT+LEDOFF
- Zmień stan na przeciwny: AT+LEDTOG
Ty możesz ustalić własne w dowolnej innej formie i bez używania znaku plusa. Mogły by to być więc np. WL, WY, TG lub nawet pojedyncze litery. Zachęcam jednak do stosowania dłuższych i z przedrostkiem AT+ by trzymać się konwencji komend AT.
Ponieważ chciałem pokazać jak używać funkcji z parametrem, stąd dla obsługi tych przycisków utworzyłem funkcję wyslij_komende, która jako argument otrzymuje ciąg znaków komendy AT, a który jest podstawiany do zmiennej lokalnej at_komenda:
Funkcja wysyła ciąg znaków komendy AT i jako ostatni znak wysyła bajt końca tekstu (null, czyli zero).
Dzięki zastosowaniu wspólnej funkcji bloki obsługi poszczególnych przycisków diody LED są bardzo proste:
Przycisk rozłączenia Bluetooth
Jako ostatnią zaprogramujemy obsługę przycisku Rozłącz połączenie Bluetooth.
Po kliknięciu tego przycisku nastąpi więc:
- Rozłączenie modułu Bluetooth.
- Pokazanie przycisku: Lista dostępnych urządzeń Bluetooth
- Ukrycie komponentu VerticalAligment1 i zawartych w nim innych komponentów.
- Przypisanie komponentowi Label1 (miejsce na komunikat z mikrokontrolera) pustego ciągu znaków, czyli skasowanie zawartego w tym komponencie tekstu powitania mikrokontrolera.
Prawda, że poste? :-)
Do pobrania
Poniżej do pobrania aplikacja w wersji:
- projekt AI2 App Inventor: LED_MASTER.aia (kopia)
- gotowa aplikacja: LED_MASTER.apk (kopia)
Układ testowy
Teraz zabierzemy się za przygotowanie układu mikrokontrolera i programu, który pozwoli nam sterować diodą. Do testów wykorzystałem moduł HC-05, który szczegółowo opisałem w artykule: HC-05 (Bluetooth) - Informacje podstawowe
Schemat
Schemat jest bardzo prosty:
Na schemacie moduł HC-05 podłączony jest stosownie do posiadanej przeze mnie wersji adaptera. W Twoim przypadku piny mogą być inaczej rozmieszczone.
Funkcje diod LED:
- LED1 to dioda, którą będziemy sterować za pomocą aplikacji.
- LED2 to dioda statusu połączenia Bluetooth - jeśli świeci, to oznacza że połączenie jest nawiązane.
Jedynym elementem, który wymaga wytłumaczenia jest dzielnik rezystorowy złożony z rezystorów R2 i R4. Dzielnik ten odpowiada za konwersję poziomu sygnału nadawania TxD modułu USART mikrokontrolera, do poziomu 3,3V+0,4V jaki toleruje na pinie TxD moduł HC-05 o czym pisałem obszernie w artykule: HC-05 (Bluetooth) - Informacje podstawowe
Bez dzielnika (lub innego konwertera napięć) mikrokontroler ustawiając stan wysoki na pinie TxD (5V) może doprowadzić do uszkodzenia pinu RxD modułu HC-05.
Dzielnik złożony jest z rezystorów R2 (4,7k) oraz R4 (10k), dzięki czemu obniża on napięcie na pinie RxD modułu HC-05 do maksymalnego poziomu:
A dlaczego na sygnale RxD nie ma takiego samego dzielnika? Ponieważ to pin TxD modułu HC-05 steruje poziomem sygnału na tym połączeniu, czyli wartość maksymalna napięcia nie przekroczy napięcia jego zasilania, czyli 3,3V.
Powstaje jednak dodatkowe pytanie: Czy 3,3V wystarczy, by ATmega8 prawidłowo rozpoznała stan wysoki na wejściu RxD?
Zerkamy do dokumentacji mikrokontrolera ATmega8 (tak samo jest w ATmega8A):
i stwierdzamy, że parametr ten jest podany w odniesieniu do napięcia zasilania mikrokontrolera. Obliczamy więc jaka to będzie wartość przy zasilaniu z 5V:
i stwierdzamy, że mikrokontroler poprawnie rozpozna jedynkę już od 3V, a ponieważ jedynka na wyjściu TxD modułu HC-05 będzie miała 3,3V oznacza to, że w tę stronę (TxD z HC-05 do RxD w mikrokontrolerze) nie musimy dokonywać żadnej konwersji poziomów logicznych.
Program
Ostatnim elementem całego projektu jest program umieszczony w mikrokontrolerze. Jako wzorzec wykorzystamy program, za pomocą którego omawiałem obsługę interfejsu USART z wykorzystaniem przerwań: RS-232 (UART, USART, terminal)
Program jest bardzo dobrze komentowany więc bez problemu zorientujesz się jak działa.
LED_MASTER.c
/* * LED_MASTER.c * * Opis: Program do testowania aplikacji LED_MASTER v.1.0 * Szczegóły: http://mikrokontrolery.blogspot.com/2011/03/android-bluetooth-LED-MASTER.html * * Mikrokontroler: ATmega8, Atmega8L, ATmega8A * Fusebity: Low:E1, high:D9 (fabryczne, wewnętrzny generator RC 1MHz) * * Created: 2014-10-30 * Author: Dondu * */ #include <avr/io.h> #include <avr/interrupt.h> #include <string.h> #include <avr/pgmspace.h> #include <avr/sleep.h> //=== Flagi ==================== //flaga globalna informująca main() o odebraniu komendy do dalszej analizy volatile unsigned char odb_flaga = 0; //=== Komendy AT ==================== #define AT_ILOSC_ZNAKOW 12 //maksymalna długość komendy wraz ze znakiem \n //tablica wzorców komend AT //UWAGA!!! //1. Każda komenda w tablicy wzorców musi kończyć się znakiem null //2. Podczas wysyłania komend AT za pomocą Bluetooth komenda także powinna //być kończona znakiem: \n const char wzorce_komend[][AT_ILOSC_ZNAKOW] PROGMEM = { "AT+START\n", "AT+LEDON\n", "AT+LEDOFF\n", "AT+LEDTOG\n"}; //Oblicz ilość wprowadzonych wzorców komend AT #define AT_ILOSC_WZORCOW (sizeof(wzorce_komend)/AT_ILOSC_ZNAKOW) //=== Bufor odebranych komend ==================== char bufor_odb[AT_ILOSC_ZNAKOW + 1]; //bufor volatile char at_odebrano_znakow = 0; //indeks znaku w tablicy bufora //=== Bufor nadawczy (wysyłany tekst) ==================== #define BUFOR_NAD_IL_ZNAKOW 40 //bufor wysyłanego tekstu do smartfona - przykładowy tekst bez polskich liter char bufor_nad[BUFOR_NAD_IL_ZNAKOW] = "Tu ATmega8 - potwierdzam polaczenie :-)"; //-------------------------------------------------------------- void usart_inicjuj(void) { //Definiowanie parametrów transmisji za pomocą makr zawartych w pliku //nagłówkowym setbaud.h. Jeżeli wybierzesz prędkość, która nie będzie //możliwa do realizacji otrzymasz ostrzeżenie: //#warning "Baud rate achieved is higher than allowed" //Nie lekceważ go!!! #define BAUD 9600 //9600bps standardowa prędkość transmisji modułu HC-05 #include <util/setbaud.h> //linkowanie tego pliku musi nastąpić //po zdefiniowaniu BAUD //ustaw obliczone przez makro wartości UBRRH = UBRRH_VALUE; UBRRL = UBRRL_VALUE; #if USE_2X UCSRA |= (1<<U2X); #else UCSRA &= ~(1<<U2X); #endif //Ustawiamy pozostałe parametry modułu USART //U W A G A !!! //W ATmega8, aby zapisać do rejestru UCSRC należy ustawiać bit URSEL //zobacz także: http://mikrokontrolery.blogspot.com/2011/04/avr-czyhajace-pulapki.html#avr_pulapka_2 //standardowe parametry transmisji modułu HC-05 UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0); //bitów danych: 8 //bity stopu: 1 //parzystość: brak //włącz nadajnik i odbiornik oraz ich przerwania odbiornika //przerwania nadajnika włączamy w funkcji wyslij_dane() UCSRB = (1<<TXEN) | (1<<RXEN) | (1<<RXCIE); } //-------------------------------------------------------------- ISR(USART_RXC_vect) { //przerwanie generowane po odebraniu bajtu za pomocą USART //indeks tablicy odbiorczej static int bufor_odb_ind = 0; //zapamiętaj odebraną liczbę bufor_odb [bufor_odb_ind] = UDR; //koniec komendy AT? (znak null, czyli zero) if (bufor_odb [bufor_odb_ind] == 0x00) { //tak, odebrano znak końca komendy odb_flaga = 1; //ustaw flagę odbioru komendy - potrzebna dla main() at_odebrano_znakow = bufor_odb_ind; //zapamiętaj ilość odebranych znaków bufor_odb_ind = 0; //ustaw indeks na początek bufora odbiorczego }else{ //nie, to nie jest ostatni bajt komendy bufor_odb_ind++; //indeks bufora na następny wolny bajt //czy przekroczono długość bufora? if (bufor_odb_ind >= AT_ILOSC_ZNAKOW){ //tak przekroczono, czyli tekst odebrany nie jest komendą //zaczynamy więc od początku bufor_odb_ind = 0; } } } //-------------------------------------------------------------- ISR(USART_UDRE_vect){ //przerwanie generowane, gdy bufor nadawania jest już pusty, //odpowiedzialne za wysłanie wszystkich znaków z tablicy bufor_nad[] //indeks bufora nadawania static int bufor_nad_ind = 0; //sprawdzamy, czy bajt do wysłania nie jest znakiem końca tekstu (czyli zerem) //i czy nie dotarliśmy już do końca tablicy bufora nadawania if((bufor_nad[bufor_nad_ind] != 0) && (bufor_nad_ind < BUFOR_NAD_IL_ZNAKOW)){ //są jeszcze znaki do wysłania //załaduj znak do rejestru wysyłki i ustaw indeks na następny znak UDR = bufor_nad[bufor_nad_ind++]; }else{ //osiągnięto koniec napisu w tablicy bufor_nad[] UCSRB &= ~(1<<UDRIE); //wyłącz przerwania pustego bufora nadawania //co zakończy nadawanie //zeruj indeks bufora nadawania bufor_nad_ind = 0; } } //-------------------------------------------------------------- void wyslij_dane(void){ //funkcja rozpoczyna inicjuje wysyłanie danych //na wszelki wypadek upewnij się, że bufor nadawania USART jest pusty while (!(UCSRA & (1<<UDRE))); //bufor jest pusty można wysłać //włącz przerwania pustego bufora UDR, co rozpocznie transmisję //aktualnej zawartości bufora UCSRB |= (1<<UDRIE); //Wysyłką danych zajmie się funkcja przerwania ISR(USART_UDRE_vect) } //-------------------------------------------------------------- void at_komenda_reakcja(unsigned char at_komenda_nr){ // Funkcja przełączająca reakcję na odebraną i rozpoznaną // komendę AT wg kolejności w tablicy wzorcowej wzorce_komend[] switch(at_komenda_nr){ case 0: //AT+START wyslij_dane(); break; case 1: //AT+LED_ON PORTB |= (1<<PB0); //włącz LED break; case 2: //AT+LED_OFF PORTB &= ~(1<<PB0); //wyłącz LED break; case 3: //AT+LED_TOG PORTB ^= (1<<PB0); //zmień stan LED na przeciwny break; // i tak dalej } } //-------------------------------------------------------------- void at_komenda_sprawdz(void){ //zmienna pomocnicza unsigned int nr_rozpoznanej_komendy; //zgaś flagę odebrania komendy odb_flaga = 0; //Pętla przeszukująca tablicę wzorców komend i porównująca wzorzec //z odebraną komendą. Komenda spoza tablicy wzorców jest ignorowana. //Funkcja strncasecmp_P() porównuje ciąg znaków ASCII zawarty w tablicy //bufor_odb[] umieszczoną w pamięci SRAM z wybranym wzorcem z tablicy //wzorce_komend[] która znajduje się w pamięci FLASH. //Funkcja strncasecmp_P() nie rozróżnia dużych i małych liter, //w związku z czym ich wielkość nie ma znaczenia przy wydawaniu komend //przez USART (Bluetooth), czyli smartfona. //rozpoczynamy od początku tablicy wzorców nr_rozpoznanej_komendy = 0; //dla kolejnych komend z tablicy wzorców do{ //sprawdź, czy zgadza się ilość znaków odebranej komendy z badanym wzorcem if(at_odebrano_znakow == (strlen_P(wzorce_komend[nr_rozpoznanej_komendy])-1)){ //-1 ponieważ //do porównania nie bierzemy znaku końca tekstu //tak, ilość znaków zgodna //sprawdź więc, czy rozpoznałeś właściwą komendę porównując znak po znaku //odebrany tekst (umieszczony w buforze) z wybraną komendą wzorcową if(!strncasecmp_P(bufor_odb, wzorce_komend[nr_rozpoznanej_komendy], at_odebrano_znakow)){ //rozpoznano komendę AT at_komenda_reakcja(nr_rozpoznanej_komendy); //reaguj na odebraną komendę //przerwij wykonywanie pętli while ponieważ już rozpoznaliśmy // odebraną komendę break; } } //przejdź do następnej komendy w tabeli wzorców komend nr_rozpoznanej_komendy++; }while(nr_rozpoznanej_komendy < AT_ILOSC_WZORCOW); } //-------------------------------------------------------------- int main(void) { //ustaw pin PB0 na wyjście dla testowej diody LED DDRB |= (1<<PB0); //inicjuj moduł USART (RS-232) usart_inicjuj(); //ustaw tryb snu na IDLE - można pominąć jeżeli nie będziesz //usypiał mikrokontrolera set_sleep_mode(SLEEP_MODE_IDLE); //włącz przerwania globalne sei(); while(1){ //tutaj Twój program .... //Czekamy na informację o odebraniu danej nie blokując mikrokontrolera //Jeżeli przerwanie poinformuje za pomocą ustawienia flago odb_flaga //oznacza to, że odebrano komendę i należy ją rozpoznać if(odb_flaga) at_komenda_sprawdz(); //w tym czasie można wykonywać dowolny program //umieść go tutaj lub przed if() powyżej //Usypiamy mikrokontroler, by zmniejszyć zużycie prądu. Ze snu wybudzi //jedno z dwóch używanych w niniejszym programie przerwań. //W swoim projekcie możesz nie wykorzystywać usypiania. sleep_enable(); sleep_cpu(); sleep_disable(); } }
Do pobrania
Projekt w Atmel Studio 6.2 oraz plik hex dla F_CPU=1MHz: LED_MASTER.zip (kopia)
Problem znaków zapytania przy prezentacji liczb
W przypadku prezentowania liczb w postaci kodów ASCII możesz się natknąć na problem pojawiającego się w zamian jedynie znaku zapytania. Rozwiązanie problemu znajdziesz tutaj: Problem znaku zapytania podczas konwersji float do znaków ASCII
Podsumowanie
W powyższym przykładzie nawiązaliśmy połączenie smartfona z mikrokontrolerem przesyłając dane w obie strony. Poznałeś kolejne zasady używania bloków App Inventora, dzięki którym możesz teraz samodzielnie pisać własne proste lub bardziej zaawansowane aplikacje.
W mikrokontrolerach często wykorzystujemy timery do odmierzania jakichś odcinków czasu. Także w aplikacjach takie rozwiązania czasami się przydają w szczególności wtedy, gdy nie chcemy obciążać aplikacji zbędną pracą i możemy sobie pozwolić na pewne opóźnienie w stosunku do momentu wystąpienia zdarzenia, czyli w naszym przypadku otrzymania pierwszych danych.
Powodzenia w realizowaniu swoich aplikacji! :-)
Ferb! Wiem już co będziemy dzisiaj robili!
OdpowiedzUsuńPozdrowienie dla ekipy bloga!!!
Witam. Sygnaly rx i tx nie powinny byc podpiete rx-tx ? Na schemacie widnieje polaczenie tx-tx oraz rx-rx.
OdpowiedzUsuńWitam.
UsuńTak! Oczywiście :-)
Dziękuję za czujność - schemat poprawiłem.
Działa!!!!! Super!!!! Akurat robię robota i to rozwiązanie bardzo się przyda do jego zatrzymania, gdy dojedzie do końca trasy. Do tej pory używałem HC-05 tylko do debugowania programów, a tutaj proszę taka prościzna, a tyle radochy i otwierających się możliwości. App Inventor jest bajecznie prosty. Wielkie dzięki! Wpasowaliście się z artykułem idealnie dla mnie! Andrzej
OdpowiedzUsuńDzięki za poradnik.
OdpowiedzUsuńCzy do wyświetlania wartości liczbowych na ekranie telefonu również należy wybrać Label1, z tym, że zmienną globalną zainicjalizować wartością liczbową? Czy też do tego celu używa się innych bloków?
Chciałbym na ekranie telefonu wyświetlać wartości odczytywane przez mikrokontroler z czujnika temperatury, niestety sposób przedstawiony powyżej generuje na ekranie pytajniki. Będę wdzięczny za odpowiedź.
Pozdrawiam
Marcin
Cieszę się, że się przydaje :-)
UsuńJeżeli pole ma nie być edytowane, to etykiety Label są do tego właśnie celu. Możesz oczywiście wykorzystać także TextBox i wyłączyć mu właściwość Enabled. Wtedy pole będzie nieedytowalne i "wyszarzone", ale tekst widoczny
Problem znaków zapytania, to nie wina aplikacji, tylko programu mikrokontrolera: Problem znaku zapytania podczas konwersji float do znaków ASCII w celu wyświetlenia na np. LCD itp.
Również pozdrawiam i życzę udanych aplikacji :-)
Dodam jeszcze, że skoro używasz liczb zmiennoprzecinkowych, to można odciążyć mikrokontroler i te obliczenia zlecić aplikacji - jest tam zestaw bloków matematycznych Math, a obliczenia zmiennoprzecinkowe dla Androida, to tzw. pikuś :-)
UsuńDzień dobry. Czy jest możliwość sterowania tą diodą poprzez akcelerometr ? Widziałem różne projekty z jeżdżącymi pojazdami (tam dodatkowo PWM`em była sterowana prędkość). Mi chodziło by tylko o to aby przy np X >200 włączała się ta dioda. Jak musiałby wyglądać blok w App Inventorze ? Z góry dziękuję za pomoc.
OdpowiedzUsuńTak jest to możliwe.
UsuńŚwietny artykuł. Aż mnie zachęcił do sprawdzenia modułu BT ;)
OdpowiedzUsuńJedna drobna uwaga, bo ta herezja mnie strasznie męczy, proszę o oznaczanie napięcia przez "U", w odróżnieniu od innej wartości oznaczanej prze literę "I" (dwa wzory: napięcia końcowego obniżanego przez dzielnik i minimalnego napięcia na wejściu).
Dzięki :)
Vcc jest specjalnie zamiast U, ponieważ tak jest oznaczane napięcie zasilania w dokumentacji mikrokontrolera.
UsuńWitam. Chciałem od nowa skompilować program przy użyciu AVR Studio jednak mam albo problem z atmega8A albo z ustawieniem optymalizacji. Na jaką wartość powinna zostać ustawiona optymalizacja? F_CPU ustawione na 1000000. Program działa jednak czasem się zacina, dodam że wcześniej zrobiłem taki sam układ na Atmega8L i nie było problemu.
OdpowiedzUsuńOptymalizacja -Os
UsuńCześć, zrobiłem podobna apkę, lecz okazało sie ze jeden ekran to za mało. dodałem screen 2. przyciskiem przechodzę do drugiego ekranu z kolejnymi przyciskami lecz problem w tym ze w momencie przejscia na screen 2 rozłącza mi bluetooth :( czy ktoś ma jakiś pomysł ? stoję zafiksowany w miejscu i nie wiem jak dobrze rozwiązać problem.pozdrawiam
OdpowiedzUsuńWitam.
UsuńNiestety drugi screen, to jakby osobny byt. Dlatego menu należy wykonać z dwóch layout-ów umieszczonych w jednym screen-ie. Do layout-ów należy powrzucać odpowiednie elementy, które mają w nich być.
Jeden z layoutów należy ukryć. Przełączanie między nimi zrobić za pomocą przycisków, które ustawią odpowiednio widoczność jednego z layout-ów.
Layout-ów noże być oczywiście więcej :)
heh:D genialne, dziękuję za podpowiedz. Pozdrawiam
UsuńATtiny2313 też działa (po małej zmianie)
OdpowiedzUsuńSuper :)
UsuńCześć. Mam mały problem ze sterowaniem mikroprocesorem (ATMega 8) aplikacja i program działają tylko problem polega na wyborze z aplikacji i zatrzymania bieżącego programu :( Rozwijając temat bez podłączonego modułu bluetooth procesor świeci całym paskiem (taśma RBG) na niebiesko (steruje procesor) po podłączeniu bluetooth powinien przez taśmę iść zielony pasek (10 pikseli). Problem polega na tym, że w tym momencie po wybraniu na aplikacji zapala się na chwilę zielony "wężyk" i gaśnie (nadal pali się niebieski) po kolejnych wciśnięciach na aplikacji przycisku przesuwa się pokolei. Więc dwa problemy:
OdpowiedzUsuń1. Zamknięcie programu (niebieski pasek) po podłączeniu modułu do aplikacji oraz
2. Przesuwanie się zielonego "węża" po jednokrotnym wciśnięciu przycisku, a nie jak do tej pory (po wyłączeniu niebieskiego) przesuwanie się go po jednym pixelu po każdym kliknięciu w apce.
Mogę podesłać kod źródłowy w C++ lub załączyć filmik z widocznym problemem.
Pozdrawiam
Robal
Witam. W jaki sposób wyświetlić na ekranie smartfona stan diody. Chodzi mi o potwierdzenie zapalenia i o stan wyłączony?
OdpowiedzUsuń