Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    142

    [Java] Dubbio su acquisizione stringhe da seriale

    Ciao a tutti,
    non è la prma volta che uso la libreria javax.comm per acquisire/scrivere dati da/su porta seriale, però è la prima volta che mi interessa acquisire in modo continuo un flusso di stringhe ad una certa velocità (fino ad ora avevo sempre acquisito una singola risposta).

    Lo strumento collegato alla seriale trasmette 20 stringhe ogni secondo, io al più avrò bisogno di 10 valori per ogni secondo (posso permettermi di perderne uno ogni 2).

    Per poter far partire e fermare l'acquisizione ho utilizzato la classe Thread e fin qui non pare ci siano problemi, ma veniamo al dunque.

    codice:
    .....
            public synchronized void run ()
            {
                String temp = new String();
                while ( run ){
                    System.out.println ( "start thread");
                    byte[] buffer = new byte[15];
                    int len = -1;
                    try
                    {
                        while ( ( len = this.in.read(buffer)) > -1 )
                        {
                            int segno = contatore ++;
                            String data = data();
                            temp = segno + "\t" + new String(buffer) + "\t" + data;
                            JFrame01.datiLetti.add(temp);
                            WriteTxtFile(temp);
                            if (!run)
                                break;
                            if (!JFrame01.inLettura)
                                attendi();
                        }
                    }
                    catch ( IOException e )
                    {
                        e.printStackTrace();
                    }
                }
            }
    .....
    1. problema
    I dati letti dalla porta seriale li salvo su un ArrayList (e per ora in fase di sviluppo in un file di testo) con annesso il tempo in cui il dato è stato ricevuto:

    codice:
    public static String data() {
            System.out.println ( " Nuova data ");
            GregorianCalendar gc = new GregorianCalendar();
            SimpleDateFormat sdf =new SimpleDateFormat("dd/MM/yyyy - HH:mm:ss:SSS");
            return  sdf.format( gc.getTime() ) ;
        }
    Non mi spiego come mai ottengo in output diversi valori con lo stesso tempo :master:

    codice:
    contatore \t StringaRx (che finisce con un a capo) \t Tempo
    codice:
    362	$11    40     
    	13/10/2009 - 14:13:19:803
    363	$11    40     
    	13/10/2009 - 14:13:19:803
    364	$11    40     
    	13/10/2009 - 14:13:19:803
    365	$11    40     
    	13/10/2009 - 14:13:19:803
    366	$11    40     
    	13/10/2009 - 14:13:19:803
    367	$11    40     
    	13/10/2009 - 14:13:19:803
    368	$11    40     
    	13/10/2009 - 14:13:19:803
    369	$11    40     
    	13/10/2009 - 14:13:19:803
    370	$11    40     
    	13/10/2009 - 14:13:20:006
    371	$11    40     
    	13/10/2009 - 14:13:20:006
    372	$11    40     
    	13/10/2009 - 14:13:20:006
    373	$11    40     
    	13/10/2009 - 14:13:20:006
    374	$11    40     
    	13/10/2009 - 14:13:20:006
    375	$11    40     
    	13/10/2009 - 14:13:20:006
    376	$11    40     
    	13/10/2009 - 14:13:20:006
    377	$11    40     
    	13/10/2009 - 14:13:20:006
    378	$11    40     
    	13/10/2009 - 14:13:20:006
    il contatore viene incrementato, ma il tempo no!


    2. problema
    A volte memorizzo delle risposte strane che sembrano violare il protocollo.... ma in realtà sembrano delle buone stringhe di risposta ma spezzate ( notate l'assenza dei caratteri a capo o la loro posizione sbagliata)

    con 2 $ e senza il /r
    codice:
    273	$$11    40     	13/10/2009 - 14:13:17:57
    codice:
    339	0     
    $11    4	13/10/2009 - 14:04:56:030
    codice:
    273	$0     
    $11   1	13/10/2009 - 13:57:36:917
    274	40     
    $11   1	13/10/2009 - 13:57:36:917
    Se utilizzo un monitor di porte seriale questi pastrocchi non ci sono e vi chiedo: è colpa del mio codice? Dovrei acquisire meglio considerando il CR (/r) il fine stringa?
    Qualcuno riesce a darmi qualche dritta?

    Grazie

  2. #2
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    142
    Il problema del tempo è dovuto al fatto che faccio girare il mio Thread senza alcuno sleep... in questo modo processo diverse volte lo stesso valore ( la velocità dipenderà dalla cpu?! )

    Quindi il problema 1 è risolto inserendo:

    codice:
                            int x = 25;
                            try {
                                Thread.sleep(x);
                            } catch (InterruptedException ex) {
                                Main._log.error(("Errore sleep"));
                            }
    prima della fine del ciclo while nel metodo run().


    Mi rimane da sistemare il problema 2.

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da som
    Il problema del tempo è dovuto al fatto che faccio girare il mio Thread senza alcuno sleep... in questo modo processo diverse volte lo stesso valore ( la velocità dipenderà dalla cpu?! )
    No non è questa la questione!

    Originariamente inviato da som
    Quindi il problema 1 è risolto inserendo:

    Thread.sleep(x);

    prima della fine del ciclo while nel metodo run().
    No, sbagliato ... nel senso che .... non ha senso!

    Vuoi sapere quale è il vero problema?

    codice:
    while ( ( len = this.in.read(buffer)) > -1 )
        ....
        .... new String(buffer) ....
    La read(), tecnicamente, può tranquillamente leggere meno della lunghezza del buffer ... ma tu poi lo usi sempre per "intero" e quindi ti ritrovi dati "sporchi"/vecchi.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  4. #4
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    142
    Vuoi sapere quale è il vero problema?
    Certo

    Effettivamente non ero proprio convinto, ma abbastanza disperato! ... ti ringrazio davvero per l'interessamento.

    Dunque secondo te risolvo con :

    codice:
    ... new String(buffer,0,len) ...
    Domani proverò e ti farò sapere.

    grazie

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    142
    Non cambia nulla

    anche prendendo solo parte del buffer spesso tiro su dello sporco....


  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da som
    Non cambia nulla

    anche prendendo solo parte del buffer spesso tiro su dello sporco....
    C'è anche un'altra questione da considerare. Quando si trasforma una sequenza di byte in un String (e viceversa), bisogna sempre tenere in considerazione le questioni sui charset/encoding. Con new String(buffer,0,len) viene usato il charset di "default" della piattaforma ... quale sia, dipende. Ma il flusso di byte che ricevi codifica caratteri in quale charset???

    Anche facendo:
    temp = segno + "\t" + new String(buffer,0,len) + "\t" + data;

    tu però non sai "quanto" legge (come ho detto la read() può leggere al massimo la lunghezza dell'array di buffer). Quindi prendere pezzetti così a caso e comporre una stringa mettendo in mezzo dei tab e altro quasi sicuramente non è appropriato.

    Originariamente inviato da som
    è colpa del mio codice? Dovrei acquisire meglio considerando il CR (/r) il fine stringa?
    Come è fatto il protocollo lo devi sapere tu molto bene. È fatto "a righe" di testo?? Allora prendere tu pezzetti di stringhe in quel modo sopra non è la cosa migliore/appropriata.
    Incapsula l'InputStream in un InputStreamReader (specificando anche il charset) e poi a sua volta incapsulalo in un BufferedReader, che ha il readLine(). Insomma ... è a righe il protocollo? Leggi "a righe"!!
    Se il protocollo fosse es.: una unità di informazione inizia con $ e finisce con % (es. $blabla%$bloblo%), allora non servirebbe usare BufferedReader. Si dovrebbe usare direttamente InputStreamReader, leggere 1 carattere per volta (o a blocchi di caratteri) e fare tu un "parsing" per cercare l'inizio e la fine.

    Insomma, devi sapere tu quali sono le informazioni, come sono formate/delimitate ecc... e in base a quello la tecnica di lettura può cambiare radicalmente!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    142
    Originariamente inviato da andbin
    Allora prendere tu pezzetti di stringhe in quel modo sopra non è la cosa migliore/appropriata.
    Incapsula l'InputStream in un InputStreamReader (specificando anche il charset) e poi a sua volta incapsulalo in un BufferedReader, che ha il readLine(). Insomma ... è a righe il protocollo? Leggi "a righe"!!
    Leggendo a righe con il BufferedReader è tutta un'altra storia! Niente più righe spezzate e sporco (giusto una risposta ogni tot comincia per $$ invece che per $ ma non è un problema). Grazie per la dritta andbin...io mi ostinavo ad usare la read ed il buffer


    codice:
    InputStreamReader isr = new InputStreamReader(in);
    BufferedReader br = new BufferedReader (isr);
    ....
    String s;
    while ((s  = br.readLine() ) != null)
       {
            segno = contatore ++ ;
            temp = segno + "\t" + s + "\t" + data();
            System.out.println(temp);
           ......
    }
    Altra cosa: lo sleep non serve.. anzi crea problemi di ritardi nell'acquisizione dei dati.

    Comunque continuo a non capire un output di questo tipo:

    codice:
    ...
    419        $11    12             15/10/2009 - 08:53:00:456
    420        $11    12             15/10/2009 - 08:53:00:456
    421        $11    12             15/10/2009 - 08:53:00:456
    422        $11    12             15/10/2009 - 08:53:00:456
    423        $11    10             15/10/2009 - 08:53:00:456
    424        $11    10             15/10/2009 - 08:53:00:456
    425        $11     5             15/10/2009 - 08:53:00:456
    426        $11     5             15/10/2009 - 08:53:00:456
    ....
    Il contatore è incrementato, il dato che mi interessa è stato letto bene... ma il tempo di ricezione è uguale al millesimo
    A me quel tempo serve che sia associato in modo corretto alla risposta ricevuta.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.