Lettura e scrittura su più porte seriali.

di il
18 risposte

Lettura e scrittura su più porte seriali.

Ciao, ho scritto un programma in C++ con Visual studio. Leggo e scrivo tranquillamente sulla porta com. il problema sorge quando voglio leggere su più porte contemporaneamente. Le letture avvengono in maniera molto lenta e non ad ogni ciclo. Ho provato a dividerlo in più thread ma il risultato è lo stesso. Se per ogni porta realizzo due programmi separati il problema non si presenta. Avete qualche suggerimento?

18 Risposte

  • Re: Lettura e scrittura su più porte seriali.

    Mah ... molto probabilmente dipende da come hai impostato il codice.
  • Re: Lettura e scrittura su più porte seriali.

    Prima di postare il codice vi chiedo se avete un consiglio di dove andare a parare (non chiedo che mi postiate un codice completo, magari una o due righe di suggerimento). Preciso che ho provato anche a far aprire e chiudere le porte (com1 e com7) ad ogni lettura senza nessun giovamento. Comunque vi risulta possibile leggere più porte (o file) in sequenza senza ritardi nell'esecuzione?
  • Re: Lettura e scrittura su più porte seriali.

    Per avere un aiuto magari dovresti chiarire meglio quello che fai; a cosa ti colleghi tramite le porte seriali? A dei dispositivi a cui devi mandare dei comandi e leggerne le risposte oppure a dei dispositivi che periodicamente spediscono dati e tu li devi solo raccogliere?
    La lettura come la esegui? Ci sono dei dispositivi che vanno in timeout?
  • Re: Lettura e scrittura su più porte seriali.

    Collego due Arduino che mandano e ricevono array di caratteri. Appena riesco posto il codice di apertura del colgamento.
  • Re: Lettura e scrittura su più porte seriali.

    Salve. Ho ripreso in mano questo codice. Abbassando il timeout ovviamente il rallentamento svanisce. Tuttavia se ho due letture consecutive su due porte diverse e la prima non manda dati la seconda aspetta che arrivi qualche cosa dalla prima per rispondere. Ho capito che è una questione di scelta di lettura sincrona o asincrona. Comunque come impostereste il codice per fare in maniera che uno non debba aspettare l'altro per inviare i dati ?
  • Re: Lettura e scrittura su più porte seriali.

    Devi usare - correttamente - più thread.
  • Re: Lettura e scrittura su più porte seriali.

    Già provato. Comunque una porta aspetta l'altra. Solo se compilo due programmi separati il problema non sussiste. Ma io vorrei fare un unico exe.
    Qual è il sistema per far in modo che se su una porta non arriva niente la lettura vada avanti sull'altra porta?
  • Re: Lettura e scrittura su più porte seriali.

    Ma tu come esegui la lettura?
  • Re: Lettura e scrittura su più porte seriali.

    mantovanidavide ha scritto:


    Comunque una porta aspetta l'altra.
    Allora non ti servono i thread ...

    Però avevi scritto prima

    leggere su più porte contemporaneamente

    quindi nessuno aspetta nessuno.

    Quindi, che vuoi dire esattamente con "una porta aspetta l'altra"?

    Secondo me, se usi la WaitCommEvent e due thread, risolvi.
    Solo se compilo due programmi separati il problema non sussiste.
    E come fai, nei programmi separati, a fare in modo che una porta attendi l'altra??
    Qual è il sistema per far in modo che se su una porta non arriva niente ...
    Questa frase non ha senso ... non arriva niente "per quanto tempo" ?
  • Re: Lettura e scrittura su più porte seriali.

    Ma poi

    1) a cosa sei collegato (Arduino, ok, ma che tipo di hardware, quali informazioni ...)

    2) a quale velocità e con quali parametri

    3) quanti dati ti attendi nell'unità di tempo

    4) che ne fai dei dati (memorizzati o visualizzati in tempo reale?)
  • Re: Lettura e scrittura su più porte seriali.

    Questo è la funzione di Apertura delle porte:
    void initSerialPort(int seq,const LPCWSTR port){
    	// Imposto i valori per i Timeout
    	cto[seq].ReadIntervalTimeout = 500;
    	cto[seq].ReadTotalTimeoutMultiplier = 500;
    	cto[seq].ReadTotalTimeoutConstant = 500;
    	cto[seq].WriteTotalTimeoutMultiplier = 500;
    	cto[seq].WriteTotalTimeoutConstant = 500;
    
    	// Inizializzo la porta seriale
    	serialport[seq] = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
    	// Imposto il Timeout
    	SetCommTimeouts(serialport[seq], &cto[seq]);
    
    	// Imposto le proprietà della connessione
    	if (serialport[seq] == INVALID_HANDLE_VALUE)
    		return;
    	DCB prop[2];
    	GetCommState(serialport[seq], &prop[seq]);
    	prop[seq].BaudRate = CBR_9600;
    	prop[seq].Parity = NOPARITY;
    	prop[seq].ByteSize = 8;
    	prop[seq].StopBits = ONESTOPBIT;
    	if (!SetCommState(serialport[seq], &prop[seq]))
    		serialport[seq] = INVALID_HANDLE_VALUE;
    	return;
    }
    Questa è il codice di lettura nel thread principale :
    LPCWSTR porta =L"com1";
    initSerialPort(0,porta);
    .......
    
    	do {
    				ReadFile(serialport[0], ch, 1, &CS, NULL);
    				if (CS == 1) {
    					hdg[ind] = ch[0];
    					ind++;
    				}
    				else ind = 2;
    			} while (ind < 2);
     
    Aggiungo le porte che mi servono e di conseguenza accodo codici di lettura per ogni porta.
    L'apertura delle porte avviene all'inizio del thread. Poi si entra in un ciclo che continua fino alla chiusura del programma.
    Questo per dirti che non ho commesso l'errore di aprire le porte all'infinto.
    il while fa in modo che io riceva esattamente tre caratteri per formare la stringa hdg che io utilizzerò per codificare gli ordini da inviare al simulatore di volo.
    Quindi formo una stringa da interpretare. Non devo salvarla da nessuna parte solo utilizzarla.
    Qui vedi un time out di 500 che va bene per una porta. Mettendo a 0 i valori la lettura su più porte è immediata.
    Tuttavia le stringhe escono tutte assieme quando tutte le porte hanno dati da inviare.
    Arduino manda un carattere alla volta.
    Il tutto avviene in tempo reale. (ovvaimente per noi umani non per il processore).
    Non ho un numero fisso di dati da ricevere. Se ci sono ad esempio due schede collegate ne uso comunque una alla volta. Non muovo due encoder contemporaneamente su due schede diverse.
    Alla tua domanda "non arriva niente per quanto tempo" rispondo: non è questione di tempo. Appena l'ultima porta ha dei dati da inviare arrivano in ordine tutti. Ma io ho bisogno che agiscano indipendentemente una dall'altra
    In pratica ho bisogno di un "no-blocking code" funzionante.
    Il fare programmi separati per ogni porta usata aggira il problema di dover attendere la fine della lettura di una porta per passare ad un'altra cosa che appunto voglio evitare.
    Ti ringrazio per la pazienza.
  • Re: Lettura e scrittura su più porte seriali.

    Guarda ... io non metterei un ciclo nel programma principale.

    Creerei due thread separati dal principale e lavorerei con la WaitCommEvent.
  • Re: Lettura e scrittura su più porte seriali.

    Studio, provo e posto i risultati. Grazie
  • Re: Lettura e scrittura su più porte seriali.

    Al momento sono riuscito ad arrivare al punto che la funzione waitcommevent mi restituisce "i/o pending". Ma se a questo punto imposto un Readfile non legge nulla. Suggerimenti ?
Devi accedere o registrarti per scrivere nel forum
18 risposte