.:Matrix:. Inserito: 27 aprile 2008 Segnala Inserito: 27 aprile 2008 Un saluto a tutti gli iscritti del forum.La dallas un po di tempo fa tirò fuori delle sonde di temperatura digitali con protocollo 1wire.Sono semplici da gestire e molto precise (12bit di risoluzione).Ho un piccolo problema per trasformare il valore decimale della temperatura.Praticamente ho un valore, per la parte decimale, che va da 0h a Fh e che dovrei traslare da 0 a 9.Come posso implementarla?Grazie
Livio Orsini Inserita: 27 aprile 2008 Segnala Inserita: 27 aprile 2008 Se vada 0 a F in decimale vai da 0 a 15. Ti serve una conversione binario-BCD.Attenzione però che il 18B20, che conosco bene come il 18S20, da in uscita un codice compreso tra FC90h (-55C) e 07D0h (+125C) quindi la conversione va eseguita su 2 bytes e dopo aver effettuato il complemento se riconosciuto un valore negativo
.:Matrix:. Inserita: 27 aprile 2008 Autore Segnala Inserita: 27 aprile 2008 Ciao Livio,grazie per aver risposto così rapidamente.Il problema è più complesso di quanto potrebbe sembrare.Il fatto sta nella corrispondenza che i valori che rappresentano i decimali hanno un peso di 0,06125 gradi e per un grado ci sono 16 possibili posizioni intermedie.Quindi non basta semplicemente, come tu mi hai indicato e come io avevo già provato a fare, convertire il valore da BIN a BCD, ma bisognerebbe instaurare una sorta di proporzione tra le due scale. (0-15 e 0-10)Non so se sono stato chiaro nella spiegazione..:Luigi:.
Livio Orsini Inserita: 28 aprile 2008 Segnala Inserita: 28 aprile 2008 No, per niente.Hai un numero su 2 bytes. 0000h ===> 0C, 07D0h ==> 125C equivalenti a 2000 counts per 125C, cioè 0,0625C per count.Il primo passo, dopo aver letto la temperatra è verificare se è 1xxx xxxx xxxx xxxx (negativo) o 0xxx xxxx xxxx xxxx (positivo). Se il numero è positivo moltiplchi direttamente per 625 (se lavori in real con il "C" è semplice, altrimenti devi sudare un poco ). Ora devi eseguire sia una divisione, sia un'operazione di modulo (quello che si indica con %). Converti i risultati delle due operazioni da binario in BCD e avrai parte intera e parte decimale pronte per la visulaizzazione.Se la lettura è negativa devi prima effeture un'operazione di complemento.
.:Matrix:. Inserita: 28 aprile 2008 Autore Segnala Inserita: 28 aprile 2008 Ciao Livio,scusami, ma se io sono stato poco chiaro, ora tu enunci dei misteri veri e propri.:-)Allora per ricapitolare, se ho un valore positivo delo moltiplicarlo per 625 e poi dividerlo per quanto?Io ho fatto una prova dividendo i due byte per 16 e, scartando l'ultimo nibble, ottengo direttamente il valore di temperatura da visualizzare.Il mio problema rimaneva l'ultimo nibble che contiene il valore decimale però con valori da 0 a F e non da 0 a 9.Comunque, benvenga se il metodo da te proposto mi semplifica la vita.Devi solo spiegarmi meglio le operazioni da effettuare.Grazie.Luigi.
Livio Orsini Inserita: 28 aprile 2008 Segnala Inserita: 28 aprile 2008 (modificato) Stiamo parlando entrambi del DS18B20? IO mi riferisco a questo dispositivo.Considerando solo la parte positiva hai una misura che parte da 0 e arriva a 125C suddivisa su 2000 livelli discreti (counts) che in esadecimale si scrive 7D0.1C vale 16 counts, cioè 10h. Se a te non interessano i decimali di grado scarta pure il nibble meno significativo, puoi scartare anche il nibble più significativo che è sempre zero. In pratica shifti a destra di 4 i due bytes (divisione per 16) ed ottieni un solo byte con numeri compresi tra 0 e 7D <==> 0-125.A questo punto devi convertire da binario in BCD.Domanda sai eseguire la conversione? Se no dimmi quale linguaggio usi e ti metto on line la semplice routine di conversione BinBCD (è un classico).Se invece vuoi anche i decimali devi salvare il nibble meno significativo, moltiplicare per 625 e dividere, ovviamente, per 10000 (o per 1000, o per 100 o per 10, o niente dipende dalla risoluzione che vuoi ottenere) che è poi la procedura che ti ho descritto prima con riferimento al "C" (più semplice). A questo punto converti la parte intera da binario a BCD ed ottieni i decimali da visualizzare.Puoi anche fare una procedura molto grezza ma funzionale. Sommi 625 tante volte quanto vale il numero contenuto nel nibble dei decimali (for n=0, n<=x ==> y=y+625), tenendo presente che sono decimillesimi di grado.COn una sola cifra compreso tra 0 e Fh puoi visualizzare solo temperature tra 0 e 15C, oppure tra 16 e 255 (125). Modificato: 28 aprile 2008 da Livio Orsini
.:Matrix:. Inserita: 28 aprile 2008 Autore Segnala Inserita: 28 aprile 2008 Perfetto Livio, sei stato molto esauriente nella spiegazione.Come linguaggio uso ASM, ed avevo già implementato la divisione per 16 ed ho anche implementato una routine di conversione BIN-BCD.Il valore intero della temperatura, lo visualizzo già sul display.Il problema erano solo i decimali.Infatti, in base alle ultime indicazioni che mi hai fornito, per avere una visualizzazione dei decimi di grado dovrei moltiplicare l'ultimo nibble per 625 per poi dividerlo per 1000.Provo a fare queste operazioni e ti faccio sapere il risultato.P.S. dimenticavo:sto avendo difficoltà nella lettura del codice a 64bit della sonda, nel senso che se effettuo la lettura del codice, dopo non mi effettua più la conversione della temperatura (44h).Probabilmente sbaglio qualcosa nella sequenza dei comandi:- inizializza sonda (impulso di reset seguito da impulso di presenza con relativa routine di mancato rilevamento della sonda);- scrivi 33h (comando per leggere il codice);- leggi 8 byte (il codice ritornato dalla sonda);- inizializza sonda- scrivi CCh (salta la rom)- scrivi 44h (avvia la conversine della temperatura)- inizializza sonda- scrivi CCh- scrivi BEh- leggi 8 byte (legge la scratchpad)Dove è l'errore?Grazie.
Livio Orsini Inserita: 29 aprile 2008 Segnala Inserita: 29 aprile 2008 (modificato) Ti allego il "C" commentato della mia funzione per leggere la temperatura, il dispositivo è il DS18S20; differisce per precisione e formattazione dei dati ma i comandi sono identici.RIcordo che, dopo uno "sleep" del micro alla ripresa era necessario leggere 3 volte la temperatara perchè non smepre i primi due valori erano corretti. Mi ero riproposto di indagare a fondo il problema, poi il progetto è passato in secondo piano, visto che così funzionava (è, purtroppo, la normalità ) byte const srchrom = 0xf0; //comando "search ROM" byte const rdrom = 0x33; //comando "read ROM" byte const mtchrom = 0x55; //comando "match ROM" byte const skprom = 0xcc; //comando "skip ROM" byte const conv_t = 0x44; //comando "converti temperatura" byte const rd_dat = 0xbe; //comando "leggi i dati dalla memoria" void tem_conv(int *pnt)//lettura temperatura e memo in array punyato da "pnt" { int1 b_ack; int i, dato; b_ack = On_reset(); //invio comando di reset al DS18S20 if ( b_ack == FALSE) { dato = skprom; //invio il comando "skip ROM" DStx_byte(dato); // scrivi byte dato = conv_t; //invio il comando "converti" DStx_byte(dato); // scrivi byte do { dato = DSrx_byte(); // leggi byte }while (dato =! 0xff); set_tris_a(0b111111001);//A1 e A2 ==> output, altri input bit_set(port_a,1); //forza a "1" la linea DQ delay_us(250); set_tris_a(0b111111011); // tutti input On_reset(); delay_us(250); dato = skprom; //invio il comando "skip ROM" DStx_byte(dato); delay_ms(250); dato = rd_dat; //invio comando "leggi i dati" DStx_byte(dato); for ( i=0; i<2; i++) { *(pnt+i)=DSrx_byte(); } } else { *pnt = 0; //non cè presenza del dispsoitivo *(pnt+1) = 0; //non cè presenza del dispsoitivo } } Modificato: 29 aprile 2008 da Livio Orsini
.:Matrix:. Inserita: 29 aprile 2008 Autore Segnala Inserita: 29 aprile 2008 Grazie Livio,proverò, proverò e proverò Vedremo se alla fine funziona...Luigi.
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