Livio Orsini Inserita: 10 aprile 2010 Segnala Share Inserita: 10 aprile 2010 Il buffer lo dimensioni tenendo conto della velocità di trasmissione e dell'intervallo di tempo masimo che può intercorrere tra du routines di servizio.Io, solitamente definisco un buffer di 10 caratteri, ma è solo per mia abitudine.Altro caso se sai che ogni trasmissione termina con un carattre di chiusura ed una lunghezza massima ben precisa. Tipico, ad esempio, il caso di Modbus dive hai 128 caratteri. Qui definisci un buffer di max 128. La routine di servizio la lanci solo quando hai ricevuto il carattere di fine; il test lo fai nella routune di servizio dell'interrupt. Se invece non hai lunghezze di trasmissione standard o caratteri di fine tx, allora devi lanciare la routine di ricezione ad intervalli più o meno ciclici; mentre svuoti il buffer devi inbire l'interrupt di ricezione onde evitare sovrapposizioni. Link al commento Condividi su altri siti More sharing options...
Edge Inserita: 10 aprile 2010 Autore Segnala Share Inserita: 10 aprile 2010 Ecco, questo per esempio non lo facevo.Bè, quello che so è che se un comando va a buon fine, si conclude sempre con un OK seguito da un CRLF, altrimenti un ERROR seguito da CRLF. Questo controllo quindi lo posso fare con un IF nella routine di servizio giusto? Basta che controlli se prima di CRLF c'è un OK o un ERROR.SalutiEdge Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 10 aprile 2010 Segnala Share Inserita: 10 aprile 2010 Certo. Poi alzi il flag di EOT (End Of Transmission) e se c'è OK alzi anche il flag di DataOK.Poi dal main e da altro programma con flag EOT vero lanci la routine di ricezione dove svioterai il buffer e abbasserai i flags. Link al commento Condividi su altri siti More sharing options...
Edge Inserita: 10 aprile 2010 Autore Segnala Share Inserita: 10 aprile 2010 Oh, bene. Ho capito!Spero sia la volta buona. A parte che sono un "testone" di natura e ci ragiono 1000 molte e mi dovete scusare. SalutiEdge Link al commento Condividi su altri siti More sharing options...
kappa47 Inserita: 12 aprile 2010 Segnala Share Inserita: 12 aprile 2010 Se dici che la comunicazione tra PC e modem funziona (e ovviamente non c’è motivo di dubitarne) il problema, per esclusione, rimane nella routine che legge o meglio gestisce, il buffer Rx.Mi sembra che in un esempio del main che hai messo sul forum fai lo “switch” sul carattere: è’ più comodo e funzionale fare una macchina a stati e non il controllo sul singolo carattere;Ho fatto le routine per la gestione di un buffer circolare. typedef unsigned char u_char; // 0 < MAX_CHAR < 256 // ATTENZIONE !!! /* Definizione coda circolare di ricezione RS232 da interrupt */ struct tag_rx { u_char n_car; // numero car. in coda u_char ptr_rd; // puntatore lettura u_char ptr_wr; // puntatore crittura u_char car [MAX_CHAR]; // buffer u_char car_rd; // ultimo carattere letto }; /* Dichiarazione */ struct tag_rx coda_rx; /* Svuota coda di ricezione */ // Solo come inizializzazione void svuota_rx (void) { //INTCONbits.GIEH = 0; // Disable all interrupts high //INTCONbits.GIEL = 0; // Disable all interrupts low coda_rx.n_car = 0; coda_rx.ptr_rd = 0; coda_rx.ptr_wr = 0; //INTCONbits.GIEH = 1; // Enable all interrupts high //INTCONbits.GIEL = 1; // Enable all interrupts low } /* Legge un carattere dalla coda di ricezione */ /* Ritorna: 0x00 = nessun carattere in coda */ /* 0x01 = carattere presente (viene scritto in "car_rd") */ u_char read_rx (void) { u_char tmp; struct tag_rx *ptr_lg = &coda_rx; INTCONbits.GIEH = 0; INTCONbits.GIEL = 0; if (ptr_lg->n_car == 0) tmp = 0x00; else { ptr_lg->car_rd = ptr_lg->car[ptr_lg->ptr_rd]; if (++ptr_lg->ptr_rd >= (u_char)MAX_CHAR) ptr_lg->ptr_rd = 0; ptr_lg->n_car--; tmp = 0x01; } //INTCONbits.GIEH = 1; //INTCONbits.GIEL = 1; INTCON = INTCON | 0xc0; // meglio usare questa return (tmp); } /* Scrive un carattere nella coda di ricezione */ /* Deve essere chiamata da interrupt !!! */ void write_rx (u_char tmp) { struct tag_rx *ptr_lg = &coda_rx; if (++ptr_lg->n_car > (u_char)MAX_CHAR) ptr_lg->n_car--; else { ptr_lg->car[ptr_lg->ptr_wr] = tmp; if (++ptr_lg->ptr_wr >= (u_char)MAX_CHAR) ptr_lg->ptr_wr = 0; } } Ci sentiamo. Link al commento Condividi su altri siti More sharing options...
Edge Inserita: 12 aprile 2010 Autore Segnala Share Inserita: 12 aprile 2010 Eccomi kappa, ero fuori per lavoro e non ho risposto prima.Innanzitutto ti ringrazio per la pazienza. Bè, complimenti, sei un certo programmatore. Da noi si dice che "Mi mangi i risi in testa" . Allora, ci ho messo un pò a capire come l'hai fatto perchè non è così immediato e ci dovevo ragionare sù. Come avevi visto io l'ho implementato in maniera abbastanza "farraginosa". Poi ho provato ad implementarlo e ti posso dire con immenso piacere che funziona!!!Rimango però ancora col dubbio sul perchè devo per forza fare una gestione di questo tipo.Per esempio, non sò se hai seguito gli ultimi post che ho scritto, ma ho provato a fare una routine di interrupt molto semplice e ho seguito i consigli di Livio Orsini.Quando avviene l'interrupt copio il carattere ricevuto nel buffer di ricezione, verifico se l'ultimo carattere ricevuto è un CR seguito da un OK e se è VERO, allora alzo un flag di ricezione completata, altrimenti incremento il puntatore del buffer, e così via... Poi dal main faccio tutta la gestione.Nel main in un ciclo for verifico la stringa che è scritta nel buffer:if(buffer[contatore]=='K' && buffer[contatore-1]=='O')LCD_Out("OK");Questo ciclo for è inserito all'interno di un ciclo while e si attiva quando il flag di ricezione completata è a 1. Allora, questa gestione non funziona al primo colpo, ma bisogna che il comando che invio al modem venga inviato almeno un paio di volte.Se non ci fosse il ciclo while con cui faccio ripetere la procedura finchè non leggo OK, non funzionerebbe.Ma perchè?SalutiEdge Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 12 aprile 2010 Segnala Share Inserita: 12 aprile 2010 Bisogna sempre dividere il problema principale in sottoproblemi (da buon analista).1 - verificare se si invia sempre il comando corretto al modem. Se non è corretto...2 - se il comando è corretto verificare se e cosa risponde il modem.Se tutto è OK dovresti vedere un invio del comando al modem e la sua risposta relativa. Se a volte uno di questi comandi "cicca" ti spieghi il perchè non va Link al commento Condividi su altri siti More sharing options...
Edge Inserita: 12 aprile 2010 Autore Segnala Share Inserita: 12 aprile 2010 Mi hai dato una buona idea Livio.Ho realizzato un piccolo circuito di collegamento tra PIC, modem e Hyperterminal come supervisore del dialogo fra i due.In questo modo sono riuscito a vedere effettivamente tramite Hyperterminal le stringhe di comandi che si scambiano i due "rompiscatole".Effettivamente a volte capita che il modem non risponde ne con un OK e ne con un ERROR anche se il comando va a buon fine.Mistero svelato!SalutiEdge Link al commento Condividi su altri siti More sharing options...
kappa47 Inserita: 12 aprile 2010 Segnala Share Inserita: 12 aprile 2010 I motivi per cui il modem non risponde possono essere diversi.Mi vengono in mente questi:1) E’ uscito correttamente dalla procedura di power-on ?2) Non ha capito il comando per cui lo ignora.3) Il comando ha bisogno di “tempo” per essere effettuato (ad esempio ATD+numero telefonico). Link al commento Condividi su altri siti More sharing options...
Edge Inserita: 12 aprile 2010 Autore Segnala Share Inserita: 12 aprile 2010 Per quanto riguarda la procedura di power on, ne sono sicuro che funzioni, ad ogni modo seguo a menadito le specifiche sul datasheet di fornire un fronte 1-0 per almeno un secondo.Poi se controllo con un tester il pin RXD del modem si nota che passa da 0 a 2.8V una volta attivo.Per quanto riguarda le tempistiche dei comandi, mi pare strano per i comandi che uso, perchè per ora utilizzo comandi basilari come ATE0, AT+CPIN, AT+CFUN=1...Ad ogni modo sul datasheet ci sono anche le tempistiche dei comandi.Per quando riguarda che i comandi non vengano interpretati, può darsi, però a volte ho notato con il circuitino che prima ho fatto, è che il comando va a buon fine senza che ci sia OK come risposta.SalutiEdge Link al commento Condividi su altri siti More sharing options...
accacca Inserita: 13 aprile 2010 Segnala Share Inserita: 13 aprile 2010 (modificato) poichè hai un solo un segnale per accendere/spegnere il modem sarebbe buona cosa controllare lo stato leggendo l'output del modem che va a 2.8V quando si accende Così puoi sapere con certezza se è acceso o spento e agire di conseguenza.Come primissima cosa invia al modem solo AT\r\n serve al modem per stabilire il baudrate sulla seriale in modo automatico Dopo aver ricevuto OK invia ATZ per portare il modem in uno stato noto aspetta l'OK e poi parti con la configurazione.Prima di eseguire un'operazione verso la rete GMS/GPRS devi controllare almeno che il modulo sia registrato AT+CREG. All'accensione la registrazione può richiedere del tempo (secondi) quindi ti consiglio di controllare periodicamente lo stato della registrazione con il comando di prima.Il GM862 ha un output per un led che cambia blink quando il modulo è registrato puoi utilizzare quella indicazione per capire cosa succede.Mi lascia perplesso l'affermazione che il modem esegua un comando e non risponda io per esperienza già fatta sono del parere che l'interfaccia verso il modulo vada realizzata con i pullup che si alimentano dal modem quando si accende come spiegano sulla documentazione. Modificato: 13 aprile 2010 da accacca Link al commento Condividi su altri siti More sharing options...
Edge Inserita: 14 aprile 2010 Autore Segnala Share Inserita: 14 aprile 2010 Scusa accaca, ieri ero fuori per delle manutenzioni e non sono riuscito a rispondere.Allora, ieri sera ho rifatto delle prove e sono riuscito a farlo andare correttamente senza mai sbagliare lasciando il collegamento trai i due pin di RX (sia del PIC che del modem) sotto il collegamento dei due MAX transceiver, mentre i pin di TX gli ho collegati con una resistenza di pull-up e poi ci ho messo anche un diodo con il catodo rivolto verso il pin TX del PIC.Tutto funziona egregiamente se faccio questo collegamento. Anche perchè lo vedo in tempo reale da hyperterminal che cosa si scambiano pic e modem.Mi funziona anche senza creare buffer circolare.Se però ricevo una stringa su due righe del tipo:"Pinco pallino 123"OKe ho un buffer[MAX] con MAX=64, la stringa OK mi si sovrappone alla prima che ricevo, oppure nel buffer trovo un'unica stringa del tipo "Pinco pallino 123"CRLFOK ?SalutiEdge Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 14 aprile 2010 Segnala Share Inserita: 14 aprile 2010 Con un buffer di 64 caratteri non dovresti avere sovrapposizione, a meno di non aver svuotato il buffer in precedenza. Link al commento Condividi su altri siti More sharing options...
Messaggi consigliati
Crea un account o accedi per commentare
Devi essere un utente per poter lasciare un commento
Crea un account
Registrati per un nuovo account nella nostra comunità. è facile!
Registra un nuovo accountAccedi
Hai già un account? Accedi qui.
Accedi ora