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:

9 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ń

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.