Mikrokontrolery - Jak zacząć?

... czyli zbiór praktycznej wiedzy dot. mikrokontrolerów.

środa, 23 marca 2011

Bluetooth + Android: LED MASTER - sterujemy diodą


Autor: Dondu

LED MASTER - Aplikacja Android sterująca diodą poprzez Bluetooth.
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:
  1. przedstawić się w postaci komunikatu tekstowego,
  2. 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:


LED MASTER v.1.0 - Ekran początkowy.


Po kliknięciu przycisku listy urządzeń pojawia się wykaz sparowanych ze smartfonem:


LED MASTER v.1.0 - Wybór urządzenia Bluetooth.


Po wybraniu właściwego (w moim przypadku HC-05) schowany zostaje przycisk otwierania listy, a w jego miejsce pojawiają się inne:

LED MASTER v.1.0 - Połączono.


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:


LED MASTER v.1.0 - Potwierdzenie połączenia.


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:


LED MASTER v.1.0 - App Inventor - Ekran projektowania.


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:


LED MASTER v.1.0 - App Inventor - Ekran projektowania komponentu HorizontalArrangement2.
HorizontalArrangement2

LED MASTER v.1.0 - App Inventor - Ekran projektowania komponentu VerticalArrangement1.
VerticalArrangement1

LED MASTER v.1.0 - App Inventor - Ekran projektowania komponentu HorizontalArrangement3.
HorizontalArrangement3

LED MASTER v.1.0 - App Inventor - Ekran projektowania komponentu TableArrangement1.
TableArrangement1


Aby jeszcze dokładniej zobrazować zależności pomiędzy rozmieszczeniem komponentów, przygotowałem pokolorowany screen:


LED MASTER v.1.0 - App Inventor - Wzajemne położenie komponentów.


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:


LED MASTER v.1.0 - App Inventor - Blok ListPicker.BeforePicking


Następnie należy zareagować na wybranie urządzenia z listy ListPicker1:


LED MASTER v.1.0 - App Inventor - Blok ListPicker.AfterPicking


Po wybraniu urządzenia Bluetooth wykonane zostaną wg kolejności:
  1. 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.
  2. Włączenie widoczności pozostałych komponentów zawartych w komponencie VerticalArrangementr1.
  3. Wyłączenie widoczności przycisku listy urządzeń Bluetooth (ListPicker1).
  4. Wysłanie do mikrokontrolera komendy:  AT+START
  5. 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:


LED MASTER v.1.0 - App Inventor - 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:


LED MASTER v.1.0 - App Inventor - Blok Clock1.Timer


Blok ten:
  1. 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.
  2. sprawdza, czy są jakieś dane do odebrania (>0). Jeśli nie, to poniższe czynności nie są wykonywane.
  3. 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 .
  4. po zakończeniu pętli (odebraniu wszystkich znaków) pokazuje odebrany ciąg znaków ładując go do komponentu Label1.
  5. 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
Dlaczego takie? Bo tak sobie wymyśliłem :-)

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:

LED MASTER v.1.0 - App Inventor - Blok funkcji wyslij_komende


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:


LED MASTER v.1.0 - App Inventor - Blok reakcji na przyciski diody LED.



Przycisk rozłączenia Bluetooth

Jako ostatnią zaprogramujemy obsługę przycisku Rozłącz połączenie Bluetooth.


LED MASTER v.1.0 - App Inventor - Blok reakcji na przycisk rozłączenia Bluetooth.


Po kliknięciu tego przycisku nastąpi więc:
  1. Rozłączenie modułu Bluetooth.
  2. Pokazanie przycisku: Lista dostępnych urządzeń Bluetooth
  3. Ukrycie komponentu VerticalAligment1 i zawartych w nim innych komponentów.
  4. Przypisanie komponentowi Label1 (miejsce na komunikat z mikrokontrolera) pustego ciągu znaków, czyli skasowanie zawartego w tym komponencie tekstu powitania mikrokontrolera.
co łącznie spowoduje przywrócenie stanu jak przy włączeniu aplikacji.

Prawda, że poste? :-)


Do pobrania

Poniżej do pobrania aplikacja w wersji:





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


LED MASTER v.1.0 - Układ testowy na płytce stykowej wraz ze smartfonem.



Schemat

Schemat jest bardzo prosty:


LED MASTER v.1.0 - Schemat układu testowego.


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:


Wzór rezystorowego dzielnika napięcia.


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):


ATmega8 - Minimalne napięcie stanu wysokiego.


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:


ATmega8 - Obliczenie minimalnego napięcia stanu wysokiego.


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! :-)


Oceń artykuł.
Wasze opinie są dla nas ważne, gdyż pozwalają dopracować poszczególne artykuły.
Pozdrawiamy, Autorzy
Ten artykuł oceniam na:

19 komentarzy:

  1. Ferb! Wiem już co będziemy dzisiaj robili!
    Pozdrowienie dla ekipy bloga!!!

    OdpowiedzUsuń
  2. Witam. Sygnaly rx i tx nie powinny byc podpiete rx-tx ? Na schemacie widnieje polaczenie tx-tx oraz rx-rx.

    OdpowiedzUsuń
    Odpowiedzi
    1. Witam.
      Tak! Oczywiście :-)
      Dziękuję za czujność - schemat poprawiłem.

      Usuń
  3. 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ń
  4. Dzięki za poradnik.
    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

    OdpowiedzUsuń
    Odpowiedzi
    1. Cieszę się, że się przydaje :-)

      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 :-)

      Usuń
    2. 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ń
  5. 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ń
  6. Świetny artykuł. Aż mnie zachęcił do sprawdzenia modułu BT ;)

    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 :)

    OdpowiedzUsuń
    Odpowiedzi
    1. Vcc jest specjalnie zamiast U, ponieważ tak jest oznaczane napięcie zasilania w dokumentacji mikrokontrolera.

      Usuń
  7. 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ń
  8. 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ń
    Odpowiedzi
    1. Witam.

      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 :)

      Usuń
    2. heh:D genialne, dziękuję za podpowiedz. Pozdrawiam

      Usuń
  9. ATtiny2313 też działa (po małej zmianie)

    OdpowiedzUsuń
  10. 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:
    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

    OdpowiedzUsuń

Działy
Działy dodatkowe
Inne
O blogu




Dzisiaj
--> za darmo!!! <--
1. USBasp
2. microBOARD M8


Napisz artykuł
--> i wygraj nagrodę. <--


Co nowego na blogu?
Śledź naszego Facebook-a



Co nowego na blogu?
Śledź nas na Google+

/* 20140911 Wyłączona prawa kolumna */
  • 00

    dni

  • 00

    godzin

  • :
  • 00

    minut

  • :
  • 00

    sekund

Nie czekaj do ostatniego dnia!
Jakość opisu projektu także jest istotna (pkt 9.2 regulaminu).

Sponsorzy:

Zapamiętaj ten artykuł w moim prywatnym spisie treści.