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