Skocz do zawartości

BTM222 i android.


Bieluus

Pomocna odpowiedź

Witam,

Zabrałem się za bluetootha - aplikacje na androida napisałem zgodnie z samplem androida (http://developer.android.com/guide/topics/connectivity/bluetooth.html), łączę się z BTM222 bez problemu, wysyłam do niego znak "0" - bądź jakikolwiek inny, problem posiadam w tym że mam aplikacje na atmege8 która ma zapalać i gasić diodę - coś prostego bo dopiero zaczynam z BT. Obsługę USART przepisałem z datasheeta dostosowując do swoich potrzeb - i cały program wygląda następująco:


#include <avr/io.h>
#include <util/delay.h>               
#define F_CPU 1000000L



#define BAUD 19200
#define MYUBRR F_CPU/16/BAUD-1

void USART_Init( unsigned int ubrr)
{
/* Set baud rate */
UBRRH = (unsigned char)(ubrr>>8);

UBRRL = (unsigned char)ubrr;

/* Enable receiver and transmitter */

UCSRB = (1<<RXEN)|(1<<TXEN);

/* Set frame format: 8data, 1stop bit */

UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)|(0<<UCSZ2);
}


unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}



int main(){


unsigned char recive;
DDRB=0x01;

USART_Init(MYUBRR);

PORTB=0x01;

while(1){
recive = USART_Receive;

if(recive == '128'){
PORTB=0x00;
}

}




return 0;
}

Lecz wtedy nic sie nie dzieje ;/ Oczywiscie w if'ie ustawiałem mase różnych wartości i nic ;/ Czy ktoś mógłby mi powiedzieć co robie źle? Oczywiście podłączylem nóżki TXD do RXD atmegi i RXD do TXD. Nie wiem czy mam coś nie tak z modułem, czy to jakaś całkowicie inna rzecz z którą się jeszcze nie postkałem. Proszę o pomoc 😉

Link do komentarza
Share on other sites

Przepisałeś kod ale chyba nie z tego "datasheeta". ATmega8 ma specjalny bit dostępu do rejestru UCSRC. Zajrzyj tam jeszcze raz.

Przy okazji: korzystając z UARTa warto od razu prawidłowo ustawić kierunki linii RXD i TXD w procesorze. Z odbiornikiem Ci się udało (po resecie jest wejściem) ale gdy zechcesz coś nadać, będzie kłopot.

Przy okazji 2: jaki ma sens porównywanie zmiennej o długości 8 bitów (char) z czymś takim: '128' ? Tam może być tylko jeden znak, np: '0' skoro zera (w ASCII) się spodziewasz.

A jeśli nie masz pewności czy w ogóle coś z BT przychodzi, podłącz mu na wyjście LEDa z opornikiem (od plusa zasilania do wyjścia odbiornika) - od razu będzie widać.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Może faktycznie coś pomieszałem z tymi rejestrami... ;/ Masz racje co do kierunków RXD i TXD, nie pomyślałem o tym w "ten sposób" - chodzi mi chodzi tylko o odbiornik na razie. Co do porównywania - no właśnie nie wiem 😃 mam jeszcze takie jedno, banalne pytanie - lecz już trochę "głupieje".

Czy jeżeli z androida wysylam byte o wartości '0' to atmega8 odbierze też (unsigned char) o wartosci '0' ??

Link do komentarza
Share on other sites

Nie wiem czy do końca rozumiesz co piszesz. W konwencji języka C (a takim się posługujesz w tym wątku) apostrofy otaczające jeden znak są stałą typu char a więc '0' będzie bajtem o wartości 0x30. Jeśli to masz na myśli, to nie widzę powodów dla których Android nie miałby wysłać takiego znaku - to normalny znak ASCII. Natomiast jeśli myślisz o wartości 0x00 to nie wiem. Były systemy operacyjne (DOS np) które w trybie znakowym bajtu NULL nie chciały wysyłać. W każdym razie powinieneś odróżniać '0' od 0x00 i od "0", co w C znaczy znowu coś innego.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Nie no wiem że to są różne znaki, rozumiem ich różnice. Chcę właśnie wysłać char'a o wartośći '0'. Lecz jeżeli chodzi o elektronikę i mikrokontrolery to jestem początkujący i tego nie ukrywam. Dzięki za wskazówki - mam nadzieję że to już rozwiąże sprawe 🙂

[ Dodano: 21-03-2013, 09:23 ]

Dalej nie działa tak jakbym chciał ;/ Mam jeszcze takie jedno pytanie, czy sprawdzanie tego co przyszło z BTM222 w ogóle ma sens aby to było w if'ie? Czy musi to być na przerwaniach? Podłączyłem diodę tak jak mi polecił Marek, i widać że coś przychodzi - lecz procek nie reaguje. Może po prostu if nie trafia wtedy kiedy przychodzi sygnał?

Link do komentarza
Share on other sites

To jeszcze jedna poszlaka: w podstawieniu do zmiennej receive używasz nazwy funkcji ale bez nawiasów. Taki zapis oznacza użycie wskaźnika do funkcji a nie wartości przez nią zwracanej. Mom zdaniem w ogóle nie dochodzi do wywołania funkcji a kompilator robi tam zwykłe podstawienie (być może z komunikatem o niezgodności typów) 16-bitowego wskaźnika zrzutowanego niejawnie na char.

EDIT: I jeśli nadal nie działa to pokaż cały poprawiony kod, bo nie wiemy co pozmieniałeś.

Link do komentarza
Share on other sites

Dzięki Marek! nie wiem jak mogłem to przegapić. Teraz dioda gaśnie, ale tylko jak się łącze i jak się rozłączam. Nic się nie dzieje na to że wysyłam do BTM'a znak "1". Jednak mają być ( " " ) bo tylko wtedy się coś dzieje. A to mój kod:


#include <avr/io.h>
#include <util/delay.h>               
#define F_CPU 1000000L



#define BAUD 19200
#define MYUBRR F_CPU/16/BAUD-1

void USART_Init( unsigned int ubrr)
{
/* Set baud rate */
UBRRH = (unsigned char)(ubrr>>8);

UBRRL = (unsigned char)ubrr;

/* Enable receiver and transmitter */

UCSRB = (1<<RXEN)|(1<<TXEN);

/* Set frame format: 8data, 1stop bit */

UCSRC = (1<<URSEL)|(0<<USBS)|(1<<UCSZ0)|(1<<UCSZ1);
}


unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}



int main(){


unsigned char recive;
DDRB=0x01;
DDRD=0x01;
USART_Init(MYUBRR);

PORTB=0x01;

while(1){
recive = USART_Receive();

if(recive == "1"){
	PORTB=0x00;
	_delay_ms(500);
}else{
PORTB=0x01;
}

}




return 0;
}

Link do komentarza
Share on other sites

Wydaje mi się że powinno być

if(recive == '1')

Jeżeli coś jest umieszczone w ' ' oznacza pojedynczy znak, a " " oznacza ciąg znaków, który zakończony jest liczbą 0x00;

Link do komentarza
Share on other sites

Chyba jednak nie do końca rozróżniasz apostrofy od cudzysłowów. Przy porównaniu ze stałą "1" (zamiast z '1') tak naprawdę porównujesz ze wskaźnikiem do tej niejawnie zadeklarowanej stałej umieszczonej gdzieś w pamięci danych RAM. Tutaj kompilator porówna twoją zmienną z młodszym bajtem adresu tej stałej czyli pewnie z liczbą w okolicach 0x60 bo tam się zaczyna obszar stałych/zmiennych w RAMie. Jakieś przypadkowe bajty a nawet dłuższe "śmieci" bez bitu stopu mogą się zdarzać na wejściu odbiornika gdy coś włączasz lub wyłączasz. Ponieważ nie sprawdzasz bitów błędów odbiornika (a w szczególności Frame Error) i wszystko co się odbierze bierzesz za dobrą monetę - to trochę tłumaczy dziwne zachowanie tego nieszczęsnego if-a.

Proponuję jednak krótki powrót do kilku pierwszych rozdziałów podręcznika C w celu odświeżenia wiadomości o stałych (to żaden wstyd) oraz włączenie i uważne czytanie ostrzeżeń kompilatora. Niemożliwe, byś to przeoczył mając warningi włączone. Po kompilacji musisz być pewien, że wszystko co do Ciebie napisał tandem kompilator-konsolidator jest jasne a ewentualne ostrzeżenia pomijasz ze zrozumieniem i świadomością zagrożeń. Samo wygenerowanie kodu HEX nie jest dowodem, że program jest zgodny z konwencją języka i z Twoim zamysłem. Nie mówiąc już o jego prowidłowym działaniu.

Po opóźnieniu które wstawiłeś zrób może powrót portu do stanu 0x01 bo tak to nie wykryjesz dwóch po sobie przychodzących znaków '1'.

EDIT: Przepraszam, Harnaś napisał to samo ale krócej i szybciej 🙂 Robię kilka rzeczy na raz na dwóch komputerach i nie zwróciłem uwagi na wcześniejszą odpowiedź.

Link do komentarza
Share on other sites

No rozumiem, lecz sposób Harnaśia mi nie działa. Nic się nie dzieje. Dla mnie też ten sposób z '1' jest bardziej logiczny ponieważ wysyłam znak i znak chcę porównać no ale jakimś cudem właśnie reaguje tylko przy " ". Bardzo możliwe że to właśnie te błędy o których piszesz Marek. Programuje już dobre 3-4 lata (głownie w javie i teraz dopiero "wracam" do C) lecz z czymś takim osobiście pierwszy raz się spotykam 🙂

Link do komentarza
Share on other sites

"Sposób Harnasia" jest jedyny słuszny. Nawet jeśli coś Ci działa z cudzysłowami to zapewne już sam rozumiesz, że to przypadek. Tutaj mogą być wyłącznie apostrofy, wstaw je tam "na stałe" i zacznij szukać błędu gdzie indziej.

Zacznij od początku. Sprawdź taktowanie procesora. Czy aby na pewno jest 1MHz? Wystarczy wygenerować np. 1s impuls za którymś porcie za pomocą funkcji _delay_ms() i zmierzyć to woltomierzem. Odróżnisz sekundę od dwóch.

Pod ręką masz nadajnik zawsze dobrych znaków - swój własny procesor. Zapętl TXD do RXD, nadaj coś i zobacz czy to samo się odebrało. Zawsze dobrych bo nadajnik i odbiornik pracują z tą samą prędkością i w tym samym formacie.

To samo możesz zrobić z BT. Po zapętleniu powinien odsyłać te same znaki z powrotem. Czy tak jest? Prawie na 100% tak ale lepiej się upewnić.

Czy na pewno BT nadaje na 19200? A poza tym co to za prędkość przy zegarze procesora 1MHz? Mi nijak nie wychodzi dobry (czyli w miarę całkowity) podzielnik. Policzyłeś to? Błąd jest ogromny. Może warto zejść (choćby tylko do testów) na 1200?

itd..

Link do komentarza
Share on other sites

Zrobiłem tak jak mówiłeś, jak wyślę '1' to otrzymuje '1', procesor mam bez zewnętrznego kwarcu i czas wynosi ok 1s przy _delay_ms(1000); nie wiem dokładnie o jakie obliczenia Ci chodzi? O te do rejestru UBRR?? Zmieniałem prędkość BT od najmniejszej do największej i tez to nic nie pomogło. Trudno, na dziś już skończę i zacznę jutro - i tak Ci bardzo dziękuję za wszelkie rady i uwagi 🙂

Link do komentarza
Share on other sites

"Zrobiłem tak jak mówiłeś, jak wyślę '1' to otrzymuje '1'.. "

Rozumiem, że przy zapętleniu procesora, tak? To miało sprawdzić Twoje funkcje wysyłania i odbierania. Są OK - cieszymy się.

"nie wiem dokładnie o jakie obliczenia Ci chodzi?"

Tak, chodzi mi o obliczenia które za Ciebie wykonuje preprocesor kompilatora. Każdesz mu przecież policzyć wartość wpisywaną do rejestru UBRR. (1E6/16/19200)-1 daje w wyniku ok. 2.25. Jak coś takiego wygląda w UBRR który jest przecież "całkowity"? Jak 2? No to masz błąd 8.5% wynikający z samego tylko złego podziału. Do tego dochodzi oscylator RC. Producent gwarantuje 3% dokładności przy 5V i 25 stopniach. Nazywanie tego źródła "calibrated" jest trochę na wyrost ale cóż, nie Ty pierwszy tego nie zauważasz. Na końcu danych katalogowych są wykresy zmian częstotliwości - zjazd z 5V do 3V powoduje zmianę o kolejne 5%. Nie wiem jak jest u Ciebie z zasilaniem ale moim zdaniem wybór 19200 jest błędem. UART procesora 1MHz działa sensownie do 4800 lub do 9600 przy ustawionym bicie U2X. Pamiętaj, że błąd 5% to różnica połowy czasu nadawania jednego bitu (50%) na bicie nr 10 a to dyskwalifikuje łącze, bo nie jesteś w stanie prawidłowo odebrać nawet jednego znaku (START+8 bitów+STOP = 10bitów).

"Zmieniałem prędkość BT od najmniejszej do największej i tez to nic nie pomogło"

Pytam dla pewności: ale zmieniałeś to razem ze zmianą szybkości procesora, ponowną kompilacją i programowaniem FLASHa, tak? Jeśłi problem leży tylko w podzielniku, to dla mniejszych prędkości powinno być lepiej. Jeśli rozjechany jest wewnętrzny generator procesora, zmnieszenie baud rate poniżej 4800 pomoże ale tylko trochę - to chyba jasne.

Zrób tak:

Jeśli coś w ogóle odbierasz to nie zasadzaj się na konkretny kod tylko zrób loopback przez UART: odbieraj jak leci i wysyłaj to co odebrałeś z powrotem przez BT. Daj znać co widzisz. Po wynikach będzie można coś powiedzieć o ew. różnicy prędkości. Wysłając znak '0' wysyłasz wartość 0x30 zaczynając od najmłodszego bajtu. Teraz myśl jak UART. Na początku jest bit startu=0, potem 4 zera, dwie jedynki i znów dwa zera. Bit stopu równy 1 zamyka transfer znaku. Jeśli w dodatku wypuszczałbyś odebrany przez UART znak na port 8-bitowy to miałbyś od razu widok tego co zobaczył Twój UART. Jeśli będzie pracował lekko za szybko, te dwie jedynki przesuną się w stronę starszych bitów i zobaczysz np. 0x60 lub nawet 0x70 bo rozciągną się na 3 bity. Jeśli UART będzie się "ślimaczył", jedynki przesuną się w stronę przeciwną i odbierzesz np. 0x18 lub nawet coś z ustawionym tylko jednym bitem np. 0x08. Duże błędy w ustawieniach spowodują, że albo odbierzesz znak np. 0xFF lub 0xFE - gdy całe twoje 0x30 odbierze się jako jeden wielki bit startu i co najwyżej pierwszy bit danych lub odwrotnie - odbierzesz dwa znaki, pierwszy prawie same zera np. 0x80 lub wręcz 0x00 a drugi ("zrobiony" z tych dwóch najstarszych zer znaku '0') jako coś pośredniego. Dla lepszej analizy napisz kod który odbiera tylko jeden, pierwszy znak i pokazuje go na porcie a potem zawisa w nieskończonej pętli while(1). W sumie sprowadza się to trochę do zrobienia oscyloskopu dla ubogich 🙂

Na pewno sam wyczaisz co jest nie tak tylko ustaw najpierw sensowną prędkość, np. 1200. Bez tego wszelkie eksperymenty nie mają sensu bo już na starcie jest źle.

  • Lubię! 1
Link do komentarza
Share on other sites

Tak otrzymywalem '1' przy zapętleniu UART procesora.

Jak zmieniałem prędkość BT no to oczywiście że wgrywałem skompilowany hex do flasha ze zmianą prędkosci. Zawsze mam podłączony programator w takich sprawach. Ale nie wiedziałem że UBRR jest całkowity ;/ No to już rozumiem swój błąd. Dzięki wielkie za pomoc! Spróbuje dziś coś podziałać i dam znać co i jak

Link do komentarza
Share on other sites

Dopiero dziś się tym zająłem bo wczoraj miałem zajęty dzień na uczelni - ale działa! 😃 Wielkie dzięki Marek, gdyby nie Ty to nawet nie wpadłbym pewnie na to że to przez ten UBRR. Ustawiłem sobie jeszcze kwarc 12Mhz i włączyłem prędkość tak dopasowaną że miałem prawie idealnie całkowity wynik - i działa 🙂 Jeszcze raz wielkie dzięki!!

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.