Timeout su lettura calibro digitale

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.

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.

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

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.

Grazie ragazzi,

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

Grazie mille e ciao a tutti.

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

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

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).