Newsgroup: it.hobby.elettronica.digitale
Titolo: Consigli su comunicazioni seriali

Ciao,
ho due situazioni che mi danno problemi e magari mi sapete dare qualche 
dritta. Sto usando un PIC18F4520 @ 40 MHz (x4 PLL) con un'UART hardware 
e una software. Entrambe le seriali lavorano a 19200 bps. Uso il 
compilatore della CCS.
Situazione 1
Alla UART hw è connesso un link seriale verso un PC, a quella sw una 
bussola elettronica. Devo realizzare un collegamento trasparente, ovvero 
il software su PC che dialoga con la bussola non deve accorgersi che in 
mezzo c'è un PIC. Quindi devo "semplicemente" inoltrare i dati da una 
porta all'altra e viceversa.
Ci sono due strade: inoltrare ogni singolo byte oppure ricevere l'intera 
stringa (terminata da \r\n) prima di inviarla sull'altra porta. Nel 
primo caso non funziona nulla perché spendo troppo tempo nella routine 
di interrupt e mi perdo dati per strada. Con il secondo metodo le cose 
vanno meglio nel senso che i dati vengono correttamente inoltrati ma il 
programma non funziona, non "vede" la bussola.
Come si procede di solito?
Sitauzione 2
Consideriamo la stessa architettura di prima. Stavolta però dobbiamo 
realizzare una sorta di telemetria. La bussola ogni 200 ms invia i suoi 
dati al PIC. Quest'ultimo sempre ogni 200 ms circa deve inviare i dati 
della bussola e altri provenienti da sensori al PC. NON posso 
agganciarmi alla bussola per iniziare la trasmissione perché se si 
guastasse perderei la telemetria.
Ho provato a usare un timer per inviare i dati verso il PC mentre in 
maniera indipendente la routine di interrupt sulla seriale riceve i dati 
dalla bussola. Ma non funziona: dopo un attimo si inchioda tutto... o 
meglio si verificano corruzioni nei dati.
Anche qui, come conviene gestire gli interrupt e le seriali software in 
questi casi? E conviene ricevere carattere per carattere o l'intera stringa?
Grazie!
Marco / iw2nzm
ps. non posso usare un micro con due seriali hw (che sarebbe l'ideale) 
perché sono vincolato a usarne uno pin-to-pin compatibile con il 
PIC18F4520 e se non ho visto male non ce ne sono di analoghi con la 
doppia uart.

 stringa?
In questo caso sembra che la bussola faccia da "master", cioè sia il nodo che 
inizia la comunicazione sulla seriale mediante l'invio di un pacchetto di dati. 
Non ho capito, però, se sul PC hai un tuo software oppure un software 
proprietario che non puoi toccare (così m'è sembrato nella Situazione 1).
Nel caso di software proprietario, come hai intenzione di gestire (lato PC) i 
dati addizionali dei sensori, quindi non compatibili con il protocollo della 
bussola e del software proprietario?
Nel caso di tuo software, hai molta libertà e puoi fare quello che vuoi.

 Nel caso di tuo software, hai molta libertà e puoi fare quello che vuoi.
Troppa libertà :)
Era proprio una domanda generica per evitare di seguire strade che alla 
lunga si possono rivelare sbagliate. Forse ho però trovato la soluzione 
migliore: con un timer decido quando inviare i dati all'host. Tra una 
trasmissione e l'altra interrogo io la bussola (che può funzionare in 
modalità strobe anziché in automatico) e quindi gestisco un solo link 
seriale alla volta.
Ciao e grazie ancora
Marco / iw2nzm

 seriale alla volta.
Allora perchè non usare la modalità strobe anche nella Situazione 1?

 Allora perchè non usare la modalità strobe anche nella Situazione 1?
Perché in quel caso non dipende da me ma dal programma del produttore. 
Durante la calibrazione la bussola viene messa in modalità automatica 
per un certo tempo e poi vengono effettuate delle interrogazioni.
Ma appunto non posso intervenire in questa fase...
Ciao e grazie della pazienza!
Marco / iw2nzm


[...]
Per la porta hw, il micro ha un buffer interno di un paio di caratteri che 
ti consentono un minimo di libertà.
Su questa porta devi implementare un buffer circolare con ricezione in 
interrupt, in pratica ogni carattere che ricevi lo metti in un buffer in 
memoria, che andrai poi a svuotare a mano a mano che invierai i caratteri in 
trasmissione.
Nelle seriali software, la parte più critica è la ricezione, in quanto se 
perdi il campionamento esatto sullo start bit o hai ritardi durante la 
ricezione del byte, poi puoi avere tutto il carattere errato.
Lavorare a 19200, significa avere ogni bit della durata di circa 50ns.
Per avere un buon funzionamento della seriale sw la ccs indica un polling 
almeno di 10 volte per ogni bit da campionare.
Se devi ricevere dalla porta sw, significa cioè che ogni 5ns il tuo software 
deve passare per un ciclo tipo:
if (kbhit(PC)) {
 chr=fgetc(PC);
    pc_buffer[pc_buffer_next_in] = chr;
    if(++pc_buffer_next_in == PC_BUFFER_SIZE)
      pc_buffer_next_in = 0;
  }
Opeterei quindi per il collegamento della bussola alla porta hw.
Con il ccs per la porta hw devi utilizzare una configurazione tipo:
#use 
rs232(baud=19200,parity=E,xmit=OUT_SER1_TX,rcv=IN_SER1_RX,bits=8,stream=COMPASS,ERRORS)
la direttiva ERRORS è importante (guarda la versione del compilatore che 
utilizzi e relativo manuale)
Per la porta sw
#use 
rs232(baud=19200,parity=N,xmit=OUT_SER3_TX,rcv=IN_SER3_RX,bits=8,stream=PC,SAMPLE_EARLY,ERRORS)
la direttiva SAMPLE_EARLY mi ha risolto alcuni problemi in ricezione.
Importante poi l'utilizzo della funzione kbhit() che ti consente di vedere 
se c'è un carattere nel buffer e solo in tal caso prelevarlo con la getc(),
che essendo bloccante, ti impedirebbe altrimenti di continuare il ciclo del 
programma fino alla ricezione del successivo carattere.
In una mia applicazione basata su un 18F8722, utilizzo le 2 seriali interne 
(9600), bus i2c (100kHz), e 2 seriali sw (9600) contemporaneamente.
Il tutto convive e funziona bene, ho dovuto però fare lavorare il micro a 
40MHz, altrimenti non 'ci stavo dentro' con i tempi.
Roberto P. 

 Ma appunto non posso intervenire in questa fase...
Capito...

 Opeterei quindi per il collegamento della bussola alla porta hw.
Roberto, ma in questo caso il problema dovrebbe semplicemente "specchiarsi". 
Anche il PC, a quanto pare, può inviare dei byte in modo asincrono e cioè quando 
l'utente (o il software) vuole configurare la bussola.
Se usi la seriale sw lato PC semplicemente sposti il problema sul lato PC.
Oppure non ho capito il tuo ragionamento.

 essere interrotti.
Posso provare, tanto si fa rapidamente e si vede se risolve il problema.
Ciao e buona (fine) domenica
Marco / iw2nzm

 a 40MHz, altrimenti non 'ci stavo dentro' con i tempi.
Per quello anche io ho deciso subito di andare a 40 MHz.
Ciao e grazie anche a te per l'intervento!
Marco / iw2nzm

 Per quello anche io ho deciso subito di andare a 40 MHz.
A 40MHz si consuma di più e si emettono più distrubi, che in fase di misura 
per la compatibilità sarebbe stato meglio evitare...
Roberto P. 

 misura per la compatibilità sarebbe stato meglio evitare...
Nel mio caso non mi risulta vi siano certificazioni. Si tratta di un 
unico sistema a uso interno della ditta.
Ciao!
Marco / iw2nzm

 dovrebbe limitare a reindirizzare l'isr alla funzione che hai dichiarato.
Se il compilatore fosse perfetto si...tant'è che siamo giunti alla versione 
4.053...
Se provi a visualizzare il codice misto asm e c, a volte può capitare di 
vedere 'cose strane'.
Questo anche con compilatori + blasonati, quali Hitec, IAR e a volte lo 
stesso C18.
Roberto P.