Pages: [1]   Go Down
Author Topic: Timeout su lettura calibro digitale  (Read 1013 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buongiorno a tutti.

Utilizzo una scheda Arduino Mega 2560 per leggere i dati da un calibro digitale della Mitutoyo con protocollo Digimatic ed inviare la lettura effettuata ad un PC tramite la porta seriale.

La routine di acquisizione è la seguente:

// --------------------------------------------------------------------------
int LetturaStrumentoDigimatic(req, clk, dat){
  digitalWrite(req, HIGH);
  for( i = 0; i < 13; i++ ) {
    k = 0;
    for (j = 0; j < 4; j++) {
      while( digitalRead(clk) == LOW) {
      }
      while( digitalRead(clk) == HIGH) {
      }
      k = k | (digitalRead(dat) && 0x1) << ( 3 - j);
    }
    byteDatiRilevamento = k;
  }
}
// --------------------------------------------------------------------------

La stringa ricavata dall'insieme byteDatiRilevamento viene inviata alla seriale e successivamente elaborata dal PC. Il tutto funziona perfettamente e non fallisce nessun invio.

L'unico problema è che se il calibro è spento (oppure il cavetto è scollegato) Arduino si blocca fino a quando non si riaccende il calibro (oppure si ricollega il cavetto).

Ho pensato di inserire la suddetta routine all'interno di un timeout di 1000ms inserendola in un ciclo while:


  T = millis();
  while((millis() - T) < 1000) {  

  ...

  digitalWrite(req, LOW);
  Serial.println("ERRORE");
  break;
  }

Ma non segnala il timeout e, quando riaccendo (o ricollego) il comparatore la lettura viene eseguita immediatamente come se nel proprio buffer il pin req sia ancora HIGH. Ovviamente il messaggio di errore non viene inviato.

Qualcuno mi può aiutare a districarmi?

Grazie mille.
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Non è facile. Dovresti secondo me sostituire i cicli while con dei check sul pin clk tramite la funzione pulseIn con un timeout a 1000 ms, ad esempio. Ma questo per entrambe le volte che leggi il cambio di stato di quel pin.
Ed uscire quando in nessuno dei 2 casi hai ottenuto risposta dal sensore.
Logged


BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21240
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Il programma resta nel loop "while( digitalRead(clk) == LOW) {       }" finche il pin resta LOW. lo stesso vale per il "while( digitalRead(clk) == HIGH) {      }"

Non puoi eseguire in quel tempo nessun altro codice.

Quel codice aspetta il pasaggio H-L del CLK e in quel momento legge il dat.
Puoi fare questo in diversi altri modi che non bloccano Arduino. Potresti per esempio controllare ripetutamente se c'é il passaggio H-L sul clock.

Ciao Uwe
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sì, concettualmente il problema è quello.

Ripendandoci, l'alternativa all'uso del pulseIn è l'utilizzo di un check con un doppio controllo sullo stato del pin e sul trascorrere del tempo.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie ragazzi,

proverò ad implementare ciò che mi avete suggerito, vi faccio sapere l'esito.

Grazie mille e ciao a tutti.
Logged

Italia, Cefalù
Offline Offline
Sr. Member
****
Karma: 0
Posts: 399
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

per curiosità, di che calibro si tratta? hai un pdf o un'immagine?
Logged

Milan, Italy
Offline Offline
Sr. Member
****
Karma: 0
Posts: 332
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao, puoi provare con

      int conta = 0;
      byte errore = 0;
      while( digitalRead(clk) == LOW) {
            conta++;
            if (conta > 5000) {
                errore = 1;
                break;
            }
      }
     if (errore == 0) {
           conta=0;
           while( digitalRead(clk) == HIGH) {
                conta++;
                if (conta > 5000) {
                     errore = 1;
                     break;
                }
           }
      }
      if (errore == 0) {
            k = k | (digitalRead(dat) && 0x1) << ( 3 - j);
            byteDatiRilevamento = k;
      }

forse c'è qualche problema con le parentesi ma penso che il concetto sia chiaro, rendere autosbloccanti delle funzioni bloccanti.
Poi ti gestisci l'errore come vuoi.

Alberto
« Last Edit: December 28, 2011, 12:33:23 pm by bigjohnson » Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie Alberto,

la tua procedura funziona correttamente, ho sistemato le parentesi e fatto delle prove; inoltre ho preferito aumentare il valore del conteggio. Infatti con i valori indicati nella procedura che segue posso effettuare letture consecutive senza problemi con frequenza fino ad una lettura al secondo.

  int conta = 0;
  byte errore = 0;

  digitalWrite(req, HIGH);
  for( i = 0; i < 13; i++ ) {
    k = 0;
    for (j = 0; j < 4; j++) {
      while( digitalRead(clk) == LOW) {
        conta++;
        if (conta > 16000) {
          errore = 1;
          break;
        }
      }
      if (errore == 0) {
        conta=0;
        while( digitalRead(clk) == HIGH) {
          conta++;
          if (conta > 16000) {
            errore = 1;
            break;
          }
        }
      }
      if (errore == 0) {
        k = k | (digitalRead(dat) && 0x1) << ( 3 - j);
      }
      byteDatiRilevamento = k;
    }
  }

Grazie mille e buon 2012 a te ed a tutti i visitatori/membri del forum!!!

P.S. Per z3us: Il calibro è il modello Mitutoyo serie 500 articolo 500-161-21 (puoi vederlo su www.mitutoyo.it).
Logged

Pages: [1]   Go Up
Jump to: