Objevil jsem zajímavou stránku - letsmakerobots.com - často jsou to projekty typu "my first robot", ale některé stojí za povšimnutí. Projel jsem téměř všechna videa a abych nemusel později znovu hledat ta zajímavá, dám je i sem. Po kliknutí na jméno robota se můžete dozvědět další podrobnosti na původní stránce.
Multipurpose Robot: XRB3
Edward
ForfraBagfra
Tento kousek je zajímavý svou konstrukcí - způsobem zatáčení.
neděle 25. ledna 2009
středa 7. ledna 2009
Komunikace po RS485
Konečně se mi podařilo zprovoznit komunikaci mezi moduly. Pro tento účel jsem navrhl jednoduchý komunikační protokol, respektive knihovnu. Zatím funguje v zjednodušené verzi. Mám totiž hotové jen dva moduly, takže mě ještě nic nedonutilo zprovoznit MPCM (Multi-processor Communication mode).
Takto (zatím) vypadá obsluha komunikace v řídicím (master) modulu:
Nejprve se vytvoří pole dat o 30 prvcích. To se potom uloží do paketu, odešle a čeká se na příjem paketu, nebo na timeout. Na lcd se vypisují statistiky komunikace: počet odeslaných paketů, přijatých, paketů s vadných kontrolním součtem, počet chyb rámce, počet timeoutů. Za pomocí těchto údajů jsem provedl test - viz níže. Knihovna bude po doplnění o MPCM ke stažení na stránkách projektu.
Takto vypadá obsluha komunikace v podřízeném (slave) modulu:
Řídicí modul zatím umí jen posílat a přijímat pakety, bez toho, aby s nimi cokoliv dělal. Slave modul zase reaguje jen na pakety P_ECHO, které pošle zpět. Pro test mi to ale stačilo.
Nastavoval jsem různé rychlosti přenosu a měřil úspěšnost echa (přijatých/odeslaných*100) a chybovost příjmu (chyba crc/přijatých*100). Kupodivu se výsledky zlepšovaly se zvyšující se rychlostí. Čekal jsem spíše opačný výsledek.
Graf úspěšnosti echa:

Graf chybovosti příjmu:
Takto (zatím) vypadá obsluha komunikace v řídicím (master) modulu:
while (1) {
// vytvoření a inicializace pole dat
uint8_t data[30], i;
for(i=0; i<30;i++) data[i] = i*2;
// vytvoření paketu
makePacket(&comm_state.op,&data,30,P_ECHO,10);
// zakázání příjmu
CLEARBIT(UCSR1B,RXEN1);
// přepnutí na vysílání
C_SETBIT(RS485_SEND);
// poslání prvního bytu - ostatní se vysílají automaticky
sendFirstByte(&UDR1,&comm_state);
// čekání na odeslání paketu
while(comm_state.send_state != PS_READY);
// přepnutí na příjem
C_CLEARBIT(RS485_SEND);
// povolení příjmu
SETBIT(UCSR1B,RXEN1);
comm_state.send_state=PS_READY;
// čekání na odpověď
while(comm_state.receive_state != PR_PACKET_RECEIVED && comm_state.receive_state!=PR_TIMEOUT);
comm_state.receive_state = PR_READY;
}
Nejprve se vytvoří pole dat o 30 prvcích. To se potom uloží do paketu, odešle a čeká se na příjem paketu, nebo na timeout. Na lcd se vypisují statistiky komunikace: počet odeslaných paketů, přijatých, paketů s vadných kontrolním součtem, počet chyb rámce, počet timeoutů. Za pomocí těchto údajů jsem provedl test - viz níže. Knihovna bude po doplnění o MPCM ke stažení na stránkách projektu.
Takto vypadá obsluha komunikace v podřízeném (slave) modulu:
while(1) {
// přepnutí na příjem
C_CLEARBIT(RS485_SEND);
// čekání na příjem paketu
while(comm_state.receive_state != PR_PACKET_RECEIVED);
// rozhodnutí podle typu paketu
switch(comm_state.ip.packet_type) {
case P_ECHO: {
C_FLIPBIT(LED);
// vytvoření ECHO paketu
makePacket(&comm_state.op,&comm_state.ip.data,comm_state.ip.len,P_ECHO,0);
// zakázání příjmu
CLEARBIT(UCSRB,RXEN);
// přepnutí na odesílání
C_SETBIT(RS485_SEND);
// odeslání prvního bytu
sendFirstByte(&UDR,&comm_state);
// čekání na odeslání paketu
while(comm_state.send_state != PS_READY);
// přepnutí na příjem
C_CLEARBIT(RS485_SEND);
// povolení příjmu
SETBIT(UCSRB,RXEN);
comm_state.send_state = PS_READY;
} break;
} // switch
comm_state.receive_state = PR_READY;
}
Řídicí modul zatím umí jen posílat a přijímat pakety, bez toho, aby s nimi cokoliv dělal. Slave modul zase reaguje jen na pakety P_ECHO, které pošle zpět. Pro test mi to ale stačilo.
rychlost přenosu | úspěšnost echa [%] | Chybovost příjmu [%] |
9600 | 75 | 14 |
14400 | 79 | 13 |
38400 | 89 | 5 |
76800 | 97 | 2 |
250000 | 98 | 0 |
Nastavoval jsem různé rychlosti přenosu a měřil úspěšnost echa (přijatých/odeslaných*100) a chybovost příjmu (chyba crc/přijatých*100). Kupodivu se výsledky zlepšovaly se zvyšující se rychlostí. Čekal jsem spíše opačný výsledek.
Graf úspěšnosti echa:

Graf chybovosti příjmu:

Štítky:
avr,
komunikační protokol,
rs485
pátek 2. ledna 2009
Atmega8 - USART
Dneska mě pro změnu vypekla atmega8 v modulu MotorControl. Během dopoledne jsem napsal poměrně univerzální knihovnu pro plánovaný komunikační protokol. Pak jsem celé odpoledne zjišťoval, proč nemůžu přenést mezi dvěma moduly ani jeden jediný byte. Na elektronice je prostě okouzlující ta různorodost chyb. Člověk píše program, škrábe vlasové spoje mezi cestami na desce, opravuje přerušené cesty... No zkrátka sranda. A hlavně je naprosto geniální to, že chyba může být buď v programu, nebo v návrhu elektroniky, nebo v provedení (studeňák atd.), nebo může vznikat kombinací několika chyb (nejlépe z různých jmenovaných oblastí). To je pak zábava :-)
Aby ten zápisek byl k něčemu, zkusím popsat v čem byl zakopaný pes. U atmega8 totiž sdílí registr UBBRH a UCSRC stejnou adresu. Pokud zapisujete do jednoho z těchto registrů, rozhoduje hodnota bitu URSEL o tom, do kterého z nich se bude zapisovat. Viz. citace z datasheetu (strana 152):
Zdánlivě hloupost, ale trochu mě to potrápilo...
Aby ten zápisek byl k něčemu, zkusím popsat v čem byl zakopaný pes. U atmega8 totiž sdílí registr UBBRH a UCSRC stejnou adresu. Pokud zapisujete do jednoho z těchto registrů, rozhoduje hodnota bitu URSEL o tom, do kterého z nich se bude zapisovat. Viz. citace z datasheetu (strana 152):
The UBRRH Register shares the same I/O location as the UCSRC Register. Therefore some special consideration must be taken when accessing this I/O location.Takže jak má správně vypadat nastavení USARTu?
When doing a write access of this I/O location, the high bit of the value written, the USART Register Select (URSEL) bit, controls which one of the two registers that will be written. If URSEL is zero during a write operation, the UBRRH value will be updated. If URSEL is one, the UCSRC setting will be updated.
// 9600bd, 8n2
UBRRL = 103;
UBRRH = 0;
UCSRA = (0<<U2X)|(0<<MPCM);
UCSRB = (0<<UCSZ2)|(1<<TXCIE)|(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
UCSRC = (1<<URSEL)|(1<<USBS)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|(1<<UCSZ1)|(1<<UCSZ0);
Zdánlivě hloupost, ale trochu mě to potrápilo...
Přihlásit se k odběru:
Příspěvky (Atom)