ATMega32 a bluetooth

Dobrý den,
Vždy jsem si vymýšlel nějaké programy s čipem ATMega32, kde jsem připojoval různá tlačítka atd… Strašně rád bych se také dozvěděl, jak tento čip ovládat na dálku pomocí bluetooth. Chtěl bych zkusit primitivní vozítko.

A tady je problém - nemám tušení co a jak. Co si všechno pořídit? Ke kterým potrům co připojit? Jak se co programuje, nastavuje, atd… Čím ovládat? Napadlo mě mobilním telefonem. Na jedné stránce jsem si našel program na mobil v javě, ten ovšem na můj LG nefunguje, funguje pouze pro nokie. Prostě nevíte o nějakém návodu jak takovéto věci sestavit a zprovoznit?

A možná ještě jedna otázka na závěr - jaké jsou další způsoby dálkového ovládání, byly by lepší než bluetooth?

Nech B.T. odpočívat a zkus klasicke RC tedy PPM. Přijímač i vysílač zakoupíš v modelářských potřebách…

Dobře, od BT upustím, ale mohli byste mi tedy prosím poradit dále?

O RC modely jsem se nikdy nezajímal takze mi PPM nic neříká. Už jsem hledal něco na internetu jak to vypadá atd., jenže nějaký přesný popis jak s tím pracovat jsem nikde nenašel. Nevěděli byste něco o tom, kde bych ho našel? A jaký PPM by se mi hodil na jednoduché vozítko? Jak se vůbec programuje ten vysílač a kam zapojit přijímač? To není otázka přímo na vás. Prostě spousta otázek, odpovědi hledám, ale bylo by lepší vědět kde přesněji.

Z RC primaca ti lezie sirkovo modulovany signal. Pricom doba, kedy je signal v logH ti udava, v akej polohe je packa na vysielaci (alebo volant na tych pistolovych vysielacoch). Ked mas packu na vysielaci v jednej krajnej polohe, signal je v logH 1ms (jednu milisekundu). V druhej krajnej polohe su to 2ms. Stredna poloha je 1,5ms atd… Jedna perioda signalu ma 20ms a potom sa signal opakuje. Servo/regulator motora potom signal prevedie na uhol natocenia/otacky.
Pokial vysielac pripojis na procesor, budes musiet merat cas, kolko je signal v logH.
ebldc.com/wp-content/uploads/2009/08/servo_rc_pwm.jpg

Financne je to narocnejsie ako bluetooth, ale zas ti to usetri pracu s programovanim nejakeho user interface ci uz pre telefon alebo PC. Pokial budes kupovat zanovny vysielac, vynde ta to na 10+ euro, pokial novy tak 30+ euro. Bluetooth modul sa da na ebay kupit aj za 5€, a pokial nemas na PC bluetooth tak dongle ta vyjde na 2€. Bluetooth sa k procesoru pripaja na UART a programove komunikujes ako s terminalom na PC.

:arrow_right: administrator: přiloženy externí soubory
servo_rc_pwm.jpg

Na malé vzdálenosti (v místnosti) bývají dobré i infračervené přenosy. Při silném vysílači a odrazech od překážek je dobrá kvalita příjmu nezávisle na viditelnosti. Lze využít komponenty pro IR dálkové ovladače. Nebo už hotové moduly (dálkový ovladač k nějaké TV + do vozítka hotový modul IR přijímače a jen reagovat na povely z něj).

Co jsem se koukal na ty serva tak se mi to docela drahý, ale co nadělám. A na youtube je hromada videí jak serva kontrolovat, takže v tom by nebyl problém se něčemu přiučit.

Nad možností ovládání pomocí dálkového ovládání například k TV či DVD jsem také přemýšlel, nemusel bych si pak dělat dálkové ovládání, to mi přijde jako hezký nápad, dokonce jsem to již viděl v jedné práci kterou sem si našel na internetu.

Na některé IR přijímače jsem se již koukal a cenově jsou na tom dobře oproti ostatním způsobům. Vykoukal jsem, že tyto přijímače mají jen jeden datový pin, což by snad pro mě nebylo tolik složité, ovšem pár věcí bych potřeboval vědět.

  • Přijímače mají určitou frekvenci, ale když jsem si prohlížel pár dálkových ovládání doma, žádný údaj o frekvenci jsem nenašel. Asi tam ani nemá být, jenže jak ho tedy zjistím?
  • Teď možná plácnu blbost, ale předpokládám, že každé tlačítko je “zakódované” pomocí jedniček a nul, ty bych vyčetl jak? Existuje na to nějaký měřič?

Našel jsem si jeden návod jak zjistit kód tlačítek, který má i druhou část, ovšem využívá zobrazování pomocí LCD displeje, který nemám.
extremeelectronics.co.in/code-li … -avr-mcus/

Hledám hledám dál a stále předem děkuji za odpovědi.

ak si zozenies IR primac na 38 kHz, tak budes na 99 percent schopny prijat signal z DO. Mam doma asi 20 ks DO, a vsetky funguju s 38 kHz primacom. Kod aky tlacitko vysiela zistis budto podla vyrobcu. Napr. sony pouziva SIRC protokol, velmi casto sa v DO pouziva RC5. Nejake protokoly a teoriu najdes na: sbprojects.com/knowledge/ir/index.php Tam som hladal ja, ked som skusal IR. Druhy a podla mna istejsi sposob je, ze si pripojis primac k procesoru, procesor pripojis k pocitacu. Procesorom budes sledovat, aky signal ti ide z primaca, teda jednotlive bity, kolko trvaju logicke urovne v bite. To si budes posielat z procesora do pocitaca na terminal. Napr:
napr.

H L 1.bit: 2400 600 2.bit: 1200 600 3.bit: 600 600
Tie casy nemusia presne sediet, ale budes aspon priblizne vediet, ake bity vysiela DO, no a potom si to mozes porovnat s nejakou tabulkou trebars z linku ktory som prilozil, a budes vedet ze DO vysiela SIRC protokol, atd… Casovanie ozaj nemusi presne sediet, napriklad ked je niekde napisane, ze log1 sa reprezentuje ako 1200us High a 600 Low, DO moze vyslat aj 1950us High a 605us Low. Treba to teda zohladnit nejakou toleranciou.

Ak mas nejaky dvojkolesovy podvozok s motorcekmi a netreba ti cuvat, na riadenie ti stacia dva tranzistori. Nemusis kupovat servo. Alebo aj iny podvozok s motorcekom. Na hranie ti postaci aj servo z ebay za 2,5€.

Abych procesor připojil k počítači potřeboval bych podle všeho sériový port pokud jsem to správně vyčetl, bohužel já mám jen notebook a zde není. Což mě přivádí k tomu že si to zřejmě budu muset udělat jinde, protože prioritní by pro mě bylo využívat šipky.

Jinak narazil jsem ještě na tuhle stránku, vytáhl si náhodný ovladač a koukal se na ty kódy. Tohle tedy vystupuje z vysílače?

remotecentral.com/cgi-bin/codes/philips/r24080_0/

Zajímala by mě ještě jedna věc - znáte nějakou stránku kde by byly příklady na dálkové ovládání pomocí IR přizpůsobeny k tomu, že by kódy byly napsány v jazyku C a ne v assembleru? Nic proti němu nemám jen tady bych ho radši nepoužíval. Pár jich mám, viz. ten tutoriál o kterém jsem psal, jenom by byl dobrý návod hezky od začátku.

To jsem zapomněl uvést, například s tímhle ovladačem bych to ovládal, to jen pro zajímavost:

tsnova.cz/p26923-dalkovy-ovladac-video-panasonic-n2qajb000088/

priznam sa ze netusim co su to tam za cisla. Zrejme su to tie kody, ale neviem ako su reprezentovane.

Pokial nemas ziaden prevodnik na komunikaciu, mozes si este skusit spravit zo zvukovky jednoduchy osciloskop. Vystup z primaca pripojis cez odporovy delic na vstup mikrofonu. Na zobrazenie si pohladaj nejaky softik, ako napr. soundcard scope. Neodpal si ale zvukovku, treba zvolit vhodny odporovy delic. Je to vstup na mikrofon, neviem ake napätie znesie (0,5V max?), ale z mikrofonu ide slaby signal. Viem ze to funguje, ale za pripadne skody nenesiem ziadnu zodpovednost.

Tazko povedat aky signal vysiela tvoje DO. Najlepsie by bolo si ten signal pozriet.

Na to, jak fungujou IR protokoly se podívej třeba sem :

sbprojects.com/knowledge/ir/index.php
users.telenet.be/davshomepage/

Jsou tam popsaný jednotlivý protokoly včetně časování atd.

Podle toho jsem programoval svou knihovnu pro IR ovladače. Funguje celkem univerzálně pro většinu ovladačů. Neumí protokol RC5, ten je potřeba dekódovat trošičku jinak.

Přečetl jsem a seznámil se s tím trošku. Pokud by celé to měření zahrnovalo programování knihovny, tak to jsem vskutku v koncích. Jak jsem říkal, jsem nováček a doteď jsem jakž takž držel krok ale teď už jsem slušně pozadu. Zřejmě by se mi hodila nějaká již hotová knihovna, například jako zde:

extremeelectronics.co.in/code-libraries/using-ir-remote-with-avr-mcus/
extremeelectronics.co.in/code-libraries/using-ir-remote-with-avr-mcus-part-ii/

jenže to by zřejmě zahrnovalo pořídit si i displej a kódy vyčíst, navíc DO používané tam je jiné. V podstatě co bych si zjistil kdybych si na PC zobrazil průběh? 0 a 1, jenže s těmi naložit jak? V podstatě nejhorší na tom je, že moje představa je program “zaifovat”, samozřejmě že ne doslova, jen něco na ten způsob, ale nevím jak se data přijímají a co s nimi, když bych na to neměl knihovnu.

Mám prostě jen spoustu otázek a vypadá to že když se jedna zodpoví objeví se další. Zřejmě by se mi hodila nějaká knihovna i se všemi kódy na čip ATMega32 a prostě všechno, co je na to potřeba. Nemyslím přímo nějaký set, klidně návod, ale pokud možno krok po kroku.

:arrow_right: administrator: příspěvek byl upraven

Nechápu proč se mi to nechce poslat. Nechtěl jsem spamovat, jen jsem doufal že další už půjdou. Přitom nevím jestli se odešle aspoň toto.

V tagu URL bylo zalomení řádku. Opravil jsem to.

Ano, keby ten priebeh vidis, videl by si, ako je zakodovana jednotka, ako nula, ako vyzera cely ovladaci kod.
Kniznicu ti odporucit neviem. V tomto dokumente su snad nejake info o tvojom DO. lirc.sourceforge.net/remotes/panasonic/N2QAJB000051
Ma to trocha odlisne oznacenie, ale je to pre DVD, tak by to mohlo byt ono. Mas tam napisane ako vyzera jednicka, nula, header, kolko bitov ma kod. Bohuzial netusim co znamena ptrail, ani pre_data. Mozno sa to vysiela za riadiacim kodom.

V skutocnosti ide z primaca signal negovany. Ked nan DO nevysiela, ide z primacaneustale jednotka. Jednotka, nula a header vyzeraju tak ako v pripojenej priloha. To je podla toho dokumentu. Signal potom vyzera tak, ze pride ti header, za nim 16 bitov kodu a potom pauza 74387 us (ak tam teda niesu pripojene tie pre_data, ktore neviem co znamenaju).

Program mozes potom napisat tak, ze budes cakat, kedy sa ti na pine, na ktorom mas pripojeny primac neobjavi log0. To bude znamenat, ze primac prijal nejaky signal. Budes pocitat, kolko bude ta nula trvat. Potom sa ti signal prepne do log1, zase budes pocitat, kolko trva, az sa ti zas neprepne do nuly. Ak nula trvala cca 3461us a jednotka cca 1822 us, prijal si header, mozes ocakavat prikazove bity. Pokial si header neprijal, bol to plany poplach alebo nejaka ian chyba, musis dalej cakat na header. Kod z DO sa vzdy zacina headerom. Pokial neprimes header, tak o zvysok sa nestaraj. Ked si prijal header, tak mozes rovnakym sposobom zistovat dlzku nasledovnych logickych urovni a podla dlzky vyhodnotit, ci to bola jednotka a ci nula. Jednotlive bity si bude zapisovat do nejakej premennej (pokial sa za headerom vysiela len 16 bitovy prikaz, staci ti uint16_t, co je 16 bitovy unsigned int). Potom prijaty bit porovnas s kodom z toho dokumentu (napr. arrov_up je napisana ako 0xA1AC), a ked ano, vykonas dany pohyb. Alebo na zaciatok rozsvietis/zhasnes led.

Tu kniznicu z linkov, ktore si uviedol pracuje s timerom, s externym prerusenim, ale mozno by sa dala upravit. A nemusis pouzivat display. Namiesto toho, aby si prijaty kod vypisal na disp, tak ho porovnas a ak sa zhoduje tak rozsvietis/zhasnes led.

:arrow_right: administrator: přiloženy externí soubory
Panasonic-N2QAJB000051.txt (3.29 KB)

V jednom příspěvku jste mi říkal o toleranci, ale to při zjišťování protokolů. Když znám konkrétní DO, tak toleranci dělat nemusím?

Ohledně uint16_t, to mi zní hezky, ale jedna otázka. Ať hledám co hledám, práci s ním nedokážu najít. Myslím tím nějaký příkaz, který by mi například po tom, co přečtu všechny 1 a 0 a vyčtu například F, přidal k proměnné právě to F například na první místo, tedy nultý bit, při dalším přečtení přidám na první bit atd… Řekněme že bych ještě vymyslel nějak to časování, to se mi v hlavě rýsuje a s nějakými nepřesnostmi bych se na vás dyštak obrátil. Jde mi jen právě o tohle. Nejsem si zrovna jistý, jestli jsem to uvedl správně a srozumitelně. Je dost možné, že takto to ani nefunguje. Jinak bych chtěl velice poděkovat za ten obrázek.

nejaku toleranciu musis brat do uvahy. To urcite. napr 10us. V tej kniznici z linku ktory si sem dal sa pouziva tolerancia ± 10 percent. Casovanie nebude nikdy presne, keby nepouzijes nejaku toleranciu, tak na 99,9 percenta nebudes schopny vyhodnotit prijaty udaj.

Co sa tika toho prevodu z bin do hex: V gcc nemusis robit prevod, ak chces porovnavat dve cisla. Ked si budes ukladat tie prijate bity do typu uint16_t, mozes to rovno porovnat s hex hodnotou. Napriklad uz spominany kod pre arrov_up, ktory je 0xA1AC, vyzera v binarnom tvare takto: 0b1010000110101100 (snad som sa pri opisovani nepomylil :smiley:).

[code]//deklaracia premennej
uint16_t prijatyKod = 0;

.
.
.
//niekde v kode, ked su uz prijate vsetky bity je premenna prijatyKod = 0b1010000110101100;
.
.
.
//niekde dalej v kode
if (prijatyKod == 0xA1AC) { //rozsviet led[/code]
ako vidis, porovnavam typ uint16_t s hex cislom. A je to v poriadku.
Ak by si chcel predca len z toho uint16_t vidiet to hexa cislo, tak to 16 bitove cislo si rozdel na skupiny po styroch. Kazdu tu skupinu si potom mozes premenit na hexa cislo. Alebo si spusti windows kalkulatr, nastav si ho na programatorsky, a tam si zapis to binarne cislo. On ti ho prevedie na hexa.
Pri porovnavani v programe to ale nepotrebujes, a ak by si to chcel v hexa tvare pisat na display, tak myslim ze si to spravi fprintf funkcia (alebo taka nejaka, neviem, nepouzivam…)

Tak aspoň že se to nemusí převádět, i když to by byl jen menší problém :slight_smile: .
V předchozím dotazu jsem měl spíše na mysli to, že řekněme mám kód nějak takhle ( a doufám že nevadí že tam nebudou příkazy ) :

uint16_t prijatyKod = 0; 
.
.
.
program čeká dokud se na pinu neobjeví log0
když objeví, očekávej zhruba 3461us log0 a 1822us log1, jinak si nepřijal header a čekáš znova
v případě že header přijme, očekávej nuly a jedničky, které se skládají z intervalů logických nul a jedniček podle obrázků
**zapiš 1 či 0 do proměnné prijatyKod**
.
.
.
if (prijatyKod == 0xA1AC) {

}

předem se hned chci omluvit, jestli to jak jsem toto napsal se nedělá, já jen že takhle si učitel na programování v assembleru rozepisoval programy a stejně tak nám zadával testy, mě se to líbilo

Každopádně jde mi o to, že až přečtu na pinu 0 či 1, jak ji mám zapsat do proměnné prijatyKod? Předpokládám, že nejdřív se pošle nultý bit a poté další až do 15., jde jen o to že až přijmu nultý bit tak ho musím zapsat na správné místo, stejně tak ostatní.

Co se týče zbytku programu, podle toho co jsem tu všechno vyčetl se tento kód kromě toho if dá zřejmě do přerušení. Kousíčky kódu už bych měl :slight_smile:, jen co se týče počítání času v us, existuje takový příkaz, nebo musím využít časovač?

Cau, vzhledem k tomu ze asi zacinas tak bych zacal jednoduse a nemichal do toho zatim zadny preruseni a casovace…atd
nastrel kodu [code]
cekej dokud ir_in==0
cekej 1000us //1ms
je ir_in==1 ? ano -pryc z podprogramu , neni 1/2 header,chyba
ne cekej 1000us //2ms
je ir_in==1 ? ano -pryc z podprogramu , neni 1/2 header,chyba
ne cekej 1000us //3ms
je ir_in==1 ? ano -pryc z podprogramu , neni 1/2 header,chyba
ne cekej 400us //3.4ms
je ir_in==1 ? ano -pryc z podprogramu , neni 1/2 header,chyba
ne cekej 50us //3.45ms
je ir_in==1 ? ano -pryc z podprogramu , neni 1/2 header,chyba
ne cekej 5us //3.455ms
je ir_in==1 ? ano - pokracuj dal , 2/2 header
ne cekej 5us //3.46ms
je ir_in==1 ? ano - pokracuj dal , 2/2 header
ne cekej 5us //3.465ms
je ir_in==1 ? ano - pokracuj dal , 2/2 header
ne cekej 5us //3.47ms
je ir_in==1 ? ano - pokracuj dal , 2/2 header
ne pryc z podprogramu, neni 2/2 header,chyba

pokracujem dal
cekej 500us //0.5ms
je ir_in==0 ? ano -pryc z podprogramu , neni 2/2 header,chyba
ne cekej 500us //1ms
je ir_in==0 ? ano -pryc z podprogramu , neni 2/2 header,chyba
ne cekej 500us //1.5ms
je ir_in==0 ? ano -pryc z podprogramu , neni 2/2 header,chyba
ne cekej 315us //1.815ms
je ir_in==0 ? ano -pryc z podprogramu , prijata 2/2 header,vporadku
ne cekej 5us //1.820ms
je ir_in==0 ? ano -pryc z podprogramu , prijata 2/2 header,vporadku
ne cekej 5us //1.825ms
je ir_in==0 ? ano -pryc z podprogramu , prijata 2/2 header,vporadku
ne cekej 5us //1.830ms
je ir_in==0 ? ano -pryc z podprogramu , prijata 2/2 header,vporadku
ne pryc z podprogramu, neni 2/2 header,chyba
[/code]
takle se da napsat program pouze s if + else,
a odfiltrujes i ruseni ,na zacatek staci prijmout jen ten header za nej si dat rozsviceni ledky treba na 100ms, vyskousej …uvidis , pak muzes zacit dekodovat zbytek

Použít čekání může být jen na první pokusy, ale pak je třeba použít hw časovač. Při dlouhých prodlevách se nevychytají krátké impulsy a při krátkých prodlevách (jednotky us) se zas naopak uplatní zpoždění a nepřesnost kódu.

Možnosti:

  1. Asi nejsprávnější (nejpřesnější) řešení je vyvolávat přerušení časovače změnou hodnoty portu. Čtením hodnoty časovače se zjistí uběhlý čas. Současně je třeba obsluhovat i přerušení při přetečení čítače (time-out impulsu).

  2. Použít hw 16bitový čítač (nejlépe 1 tik = 1 us, ale může být jinak). Pro měření šířky pulsu se použije čekací smyčka, která si na začátku uchová hodnotu čítače, pak čeká (s opakovaným čtením portu) na příchod opačné hodnoty vstupu, znovu přečte časovač a rozdíl hodnot = uběhlý čas. Vzhledem k tomu, že při dlouhé prodlevě může nastat přetečení hodnoty časovače, tak buď se čte časovač i během čekání a při dlouhé prodlevě se skončí s time-outem, nebo časovač vyvolá přerušení a nastaví flag, že nastalo přetečení.

  3. Použije se inline assembler s kalibrovanou čekací smyčkou - je to jen pár instrukcí, lze snadno spočítat kolik která instrukce zabere času. Pak stačí jen čekat v loop smyčce na změnu portu, čítat registr a z jeho koncové hodnoty určit uběhlý čas. Je nutné opět řešit přetečení, např. že se registr dodekrementoval k nule. Inspirací může být zdrojový kód funkcí _delay_us z knihovny gcc-avr. Během čekání by nemělo nastati přerušení, vznikla by nepřesnost.

  4. Kompromis je kalibrovaná čekací smyčka v C. Ve smyčce se čeká na změnu pulsu, přitom se čítá proměnná (opět se sledováním přetečení) a z její koncové hodnoty se zjistí uběhlý čas - převodový koeficient se zjistí zkusmo měřením impulsu známé délky (nebo jednodušeji volat opakovaně s timeoutem). Je třeba počítat s tím, že jiné nastavení optimalizace překladače může kalibraci změnit a že případná obsluha přerušení může měření znepřesnit.

Organizace programu - v jedné proměnné uchovávat aktuální stav a impulsy načítat jednou univerzální funkcí (resp. 2 - pro 1 a 0), která měří šířku impulsu. Např. (jen náznakově):

[code]enum STAV {
STAV_ERR, // chyba nebo neznamy stav, cekani na 1
STAV_DELAY, // oddelovaci 1, mereni minimalni delky prodlevy
STAV_START, // ceka se na startovaci 0
STAV_SYN0, // probiha startovaci 0
STAV_SYN1, // probiha startovaci 1
STAV_DATA0, // probiha datova 0
STAV_DATA1, // probiha datova 1
STAV_OK // prijem kodu ukoncen
};

STAV stav;
int kod;
int maska;
int bity;

void Restart() // restart prijmu, ceka se na startovaci 0
{
stav = STAV_ERR;
kod = 0;
maska = 1;
bity = 0;
}

#define DELTA 10 // rozliseni citace v us (zvolit co nejmensi)
#define TIMEOUT 30000/DELTA
// Kalibrace - na portu nastavit stabilni hodnotu, funkci
// volat 50000x opakovane ve smycce s blikajici LED,
// dokalibrovat cekani ve funkci tak, aby blikalo presne po 1 sekunde
short Zmer0() // mereni delky 0 v desitkach us, cekani na 1
{
short citac = 0;
while ((port != 1) && (citac < TIMEOUT))
{
_delay_us(5); // prodleva se zkusmo doladi na DELTA
citac++;
}
return citac;
}
short Zmer1() // mereni delky 1 v desitkach us, cekani na 0
{
short citac = 0;
while ((port != 0) && (citac < TIMEOUT))
{
_delay_us(5); // prodleva se zkusmo doladi na DELTA
citac++;
}
return citac;
}

#define TIMESYN0MIN 3000/DELTA // minimalni delka syn0
#define TIMESYN0MAX 4000/DELTA // maximalni delka syn0
atd.

short delka;
Restart(); // restart prijmu
while (stav != STAV_OK)
{
switch(stav)
{
case STAV_ERR:
delka = Zmer0();
if (delka != TIMEOUT) stav = STAV_DELAY;
break;

case STAV_DELAY:
delka = Zmer1();
if (delka >= TIMEDELAY)
stav = STAV_START;
else
Restart();
break;

case STAV_START:
  delka = Zmer1();
  if (delka != TIMEOUT) stav = STAV_SYN0;
  break;

case STAV_SYN0:
  delka = Zmer0();
  if ((delka < TIMESYN0MIN) || (delka > TIMESYN0MAX))
    Restart();
  else
    stav = STAV_SYN1;
  break;

…atd.

 case STAV_DATA0:
   delka = Zmer0();
   if (delka == TIMEOUT)
     Restart();
  else
  {
     if (delka > TIME1) kod |= maska; // je to datovy bit 1
     maska <<= 1; // posun masky
     bity++;  // zvyseni citace prijatych bitu
     if (bity == 16) // jsou jiz vsechny datove bity
       stav = STAV_OK; // kompletni
     else
       stav = STAV_DATA1;
   }
   break;

[/code]