Sensori digitali Ds18b20 Introduzione Il sensore DS18B20 è un integrato della Dallas semiconductors Fornisce una temperatura in gradi Celsius L’uscita è un segnale digitale di 9-12 bit Ogni DS18B20 ha un codice seriale univoco a 64-bit, che permette di fare funzionare più sensori sullo stesso bus 1-Wire®. E’ possibile usare fino a 100 sensori su una linea di lunghezza che potrebbe arrivare fino a 300m, quindi, è facile utilizzare un solo microprocessore per controllare molti DS18B20 distribuiti in un’ampia area. Schema a blocchi Generalità Il sensore DS18B20 comunica tramite il protocollo 1-Wire®, un protocollo standard che permette di usare un solo filo di comunicazione (e massa) per il colloquio con un microprocessore centrale. E’in grado di misurare temperature da -55°C a 125°C con una precisione di 0.5°C nella gamma compresa tra -10°C a +85°C. Un'altra caratteristica del DS18B20 è la capacità di funzionare senza un’alimentazione esterna. L'alimentazione preferibilmente è assicurata tramite la resistenza di “Pull up” sulla linea 1-Wire®; quando il bus è alto, viene caricato un condensatore interno (c), che a sua volta fornisce l'alimentazione necessaria al dispositivo allorquando il bus si trova basso. Questo metodo di prelevare l'alimentazione dal bus 1-Wire® viene classificata come "alimentazione parassita.” Questo metodo si utilizza nel caso in cui il sensore è posto lontano dal sistema di acquisizione. In alternativa il DS18B20 può anche essere collegato ad un’alimentazione esterna. Come si vede dalla figura a pag 1, i pin laterali sono per GND e Vcc, il pin centrale è il sensore. Nella pagina successiva c’è lo schema per i collegamenti DS18b20 con Arduino DS18b20 con i pic Misure di temperatura • La temperatura può essere misurata a 9, 10, 11, 12 bit corrispondenti agli incrementi di 0.5, 0.25, 0.125, 0.0625, rispettivamente. • L’accuratezza nella lettura è di 0.5 C in un range tra -10 C e +85 C Memoria EEPROM • Dallo schema a blocchi dl sensore si nota che esso è dotato di una memoria scratchpad, cioè veloce ma di tipo EEPROM • 2 byte di memoria sono per la temperatura • Il byte 0 e il byte 1 sono usati rispettivamente per la Tl (LSB) e la Th (MSB) • I byte 2 e 3 forniscono l’accesso ai byte 0 e 1 • Il byte 4 è di configurazione • I byte 5, 6,7 sono di uso interno e non possono essere sovrascritti • Nel byte 8 c’è il codice CRC generato per ogni conversione secondo il polinomio scritto nella ROM Configurazione • Il byte di configurazione è strutturato nel seguente modo: R0 R1 R2 R3 R4 R5 R6 R7 1 1 1 1 1 0 R0 R1 Risoluzione Tempi conv 0 0 9 93.75 ms (tconv/8) 0 1 10 187.5 ms (tconv/4) 1 0 11 375 ms (tconv/2) 1 1 12 750 ms(tconv) Registri per la temperatura Registri per la temperatura • I registri per la temperatura fanno da memoria tampone per l’output seriale. • Hanno la capacità di 1 Byte ciascuno per il totale di 2 Byte. • Come si vede, i 5 bit più significativi indicano il segno della temperatura;1 indica i valori <0, 0 i valori >0. • I 4 bit meno significativi sono le cifre decimali • Dal IV bit al X bit si indicano i valori interi della temperatura. • In più, permette l’accesso ai registri da 1 byte per i trigger di allarme massimo e minimo TH e TL, questi registri sono allocati in EEPROM non volatile, viene mantenuta così l’informazione anche in assenza di alimentazione. • La memoria EEPROM contiene anche un registro per il settaggio della risoluzione Memoria ROM • La ROM a 64-bit immagazzina il codice seriale univoco del dispositivo per permettere la trasmissione seriale di più dispositivi su un bus unico. • La memoria ROM è di 64 bit così strutturata: CRC Codice identificativo Family code 8 bit 48 bit 8 bit Il polinomio generatore della CRC è x^8+x^5+x^4+1 Flag di errore • Quando il micro inizia a dialogare deve inviare sulla linea un "impulso di reset" che consiste nel mettere la linea a ZERO e mantenerla per un tempo compreso fra i 480 e i 960us. Dopo l'impulso di reset il micro si mette in ascolto. A questo punto la sonda, dopo avere interpretato l'impulso di reset risponde con un impulso di presenza che consiste nel mettere la linea a ZERO a partire da 15-60us dall'impulso di reset e per un tempo compreso fra i 60 e i 240us. • Il flag errore vale UNO se il micro non ha trovato la sonda, ovvero se non vi è stato alcun impulso di “presence” sulla linea. • Appena il flag di errore vale 0, inizia la comunicazione vera e propria. Dopo l'inizializzazione il bus-master, cioè il micro, può finalmente dialogare con la sonda Sequenza di comandi per la lettura della temperatura • • • • • • • • • • • 1) Il master invia un impulso di reset sul bus 2) I vari slave rispondono con il “Presence Pulse” 3) Il master invia un comando “Mach ROM” 0×55 4) Il master invia la ROM del sensore che vuole leggere 5) Il master invia il comando 0×44 per la conversione di temperatura 6) Il master invia un nuovo impulso di reset 7) Gli slave rispondono con il “Presence Pulse” 8) Il master invia un comando “Mach ROM” 0×55 9) Il master invia la ROM del sensore che vuole leggere 10) Il master invia un comando 0xBE per leggere la memoria del sensore 11) Il master legge i 9 bytes della memoria e lo slave li invia sequenzialmente. Protocollo in dettaglio • • Reset SEARCH ROM(f0h) Appena il sistema viene alimentato, il master bus si attiva per il riconoscimento della ROM • READ ROM (33h) Viene utilizzato quando c’è un solo slave sul bus. In questo caso non si utilizza searh ROM. • MATCH ROM(55h) Una volta letta la ROM, il master viene indirizzato verso un bus slave specifico. Un solo slave alla volta può rispondere al segnale. • Skip ROM (0xcc) Subito dopo l'inizializzazione il master bus invia alla sonda un comando che si chiama "SKIP ROM" XCC. Quando la sonda riceve questo comando sa che subito dopo deve attendersi un comando diretto ad essa che riguarda le sue funzioni di "sonda". Il comando “SKIP ROM” dice alla sonda di "saltare"'invio del codice univoco da 64 bit che nel nostro caso è perfettamente inutile avendo a che fare con una sola sonda. • ALARM SEARCH (Ech) Questa operazione è simile all’operazione di search ROM eccetto il fatto che solo gli slave con allarme possono rispondere • Start conversion(0x44) Esiste anche all’occorrenza, una "configuration word" che può essere programmata e una memoria in cui memorizzare un valore di temperatura in base al quale la sonda può fare da allarme settando un flag quando la temperatura supera tale valore, in questo caso non è stato utilizzata questa. opzione. Dopo il comando "converti temperatura" (OX44) la sonda ha esaurito il suo ciclo di operazioni e ha bisogno di essere reindirizzata. La routine principale quindi dovrà eseguire di nuovo un impulso di reset per inizializzare nuovamente la sonda. Protocollo • READ SCRATCHPAD (OXBE) Si legge la "SCRATCHPAD" cioè la memoria in cui viene memorizzato l'ultimo valore di temperatura convertito. I invia il comando "LEGGI SCRATCHPAD" OXBE, il quale dice alla sonda che subito dopo dovrà inviarci il dato di temperatura. I dati dell'uscita DS18B20 sono in gradi centigradi e sono memorizzati a 16 bit nel registro di temperatura . Viene effettuata la lettura del dato che ci viene inviato a partire dal bit meno significativo e continua fino al nono byte (Byte 8 – CRC). Inoltre abbiamo il flag di controllo rappresentato dal bit 0 del registro "errore". Nel caso in cui tale bit valga 1 il contenuto dei temp1 e temp2 è da ignorare perchè la sonda non è presente anche se le istruzioni di lettura vengono comunque eseguite. • WRITE SCRATCHPAD (Beh) Questo comando porta il master a scrivere 3 byte nella memoria scratchpad: nel byte 2 il valore di Th, nel byte 3 il valore di Tl e nel byte 4 la configurazione Protocollo • COPY SCRATCHPAD [48h] Copia i valori dei byte 2,3,4 nella EEPROM • RECALL E2 [B8h] Operazione automatica • READ POWER SUPPLY [B4h] Indica il tipo di alimentazione se esterna o con potenza parassita DS18B20 con Arduino • #include <OneWire.h> /* DS18S20 Temperature chip i/o */ OneWire ds(10); // on pin 10 void setup(void) { Serial.begin(9600); } void loop(void) { byte i; byte present = 0; byte data[12]; byte addr[8]; if ( !ds.search(addr)) { Serial.print("No more addresses.\n"); ds.reset_search(); delay(250); return 0; } Arduino Serial.print("R="); for( i = 0; i < 8; i++) { Serial.print(addr[i], HEX); Serial.print(" "); } if ( OneWire::crc8( addr, 7) != addr[7]) { Serial.print("CRC is not valid!\n"); return 0; } if ( addr[0] != 0x10) { Serial.print("Device is not a DS18S20 family device.\n"); return; } ds.reset(); Arduino ds.select(addr); ds.write(0x44,1); delay(1000); present = ds.reset(); ds.select(addr); ds.write(0xBE); Serial.print("P="); Serial.print(present,HEX); Serial.print(" "); for ( i = 0; i < 9; i++) { data[i] = ds.read(); Serial.print(data[i], HEX); Serial.print(" "); } Serial.print(" CRC="); Serial.print( OneWire::crc8( data, 8), HEX); Serial.println(); } Arduino DS18B20 con PIC • // LCD module connections sbit LCD_RS at RB4_bit; sbit LCD_EN at RB5_bit; sbit LCD_D4 at RB0_bit; sbit LCD_D5 at RB1_bit; sbit LCD_D6 at RB2_bit; sbit LCD_D7 at RB3_bit; sbit LCD_RS_Direction at TRISB4_bit; sbit LCD_EN_Direction at TRISB5_bit; sbit LCD_D4_Direction at TRISB0_bit; sbit LCD_D5_Direction at TRISB1_bit; sbit LCD_D6_Direction at TRISB2_bit; sbit LCD_D7_Direction at TRISB3_bit; // End LCD module connections // Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor: // 18S20: 9 (default setting; can be 9,10,11,or 12) // 18B20: 12 const unsigned short TEMP_RESOLUTION = 12; char *text = "000.0000"; unsigned temp; DS18b20 con i pic • void Display_Temperature(unsigned int temp2write) { const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8; char temp_whole; unsigned int temp_fraction; // Check if temperature is negative if (temp2write & 0x8000) { text[0] = '-'; temp2write = ~temp2write + 1; } // Extract temp_whole temp_whole = temp2write >> RES_SHIFT ; // Convert temp_whole to characters if (text[0] != '-') { if (temp_whole/100) text[0] = temp_whole/100 + 48; else text[0] = '0'; } text[1] = (temp_whole/10)%10 + 48; text[2] = temp_whole%10 + 48; // Extract tens digit // Extract ones digit // Extract temp_fraction and convert it to unsigned int temp_fraction = temp2write << (4-RES_SHIFT); temp_fraction &= 0x000F; temp_fraction *= 625; // Convert temp_fraction to characters text[4] = temp_fraction/1000 + 48; // Extract thousands digit text[5] = (temp_fraction/100)%10 + 48; // Extract hundreds digit text[6] = (temp_fraction/10)%10 + 48; // Extract tens digit text[7] = temp_fraction%10 + 48; // Extract ones digit } // Print temperature on LCD Lcd_Out(2, 5, text); PIC • void main() { ADCON1 = 0b00000110; // all ADC ports digital TRISE.B2 = 1; // Configure RE2 pin as input Sound_Init(&PORTD, 0); //assignment of port and initialization Sound_Play(880, 1000); // Play Sound at 880 Mhz for 1 sec Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // Clear LCD Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off Lcd_Out(1, 1, " Temperature: "); Lcd_Chr(2,13,223); // Print degree character, 'C' for Centigrades // Different LCD displays have different char code for degree // If you see greek alpha letter try typing 178 instead of 223 Lcd_Chr(2,14,'C'); // Main loop do { // Perform temperature reading Ow_Reset(&PORTE, 2); Ow_Write(&PORTE, 2, 0xCC); Ow_Write(&PORTE, 2, 0x44); Delay_us(120); // Onewire reset signal // Issue command SKIP_ROM // Issue command CONVERT_T PIC • Ow_Reset(&PORTE, 2); Ow_Write(&PORTE, 2, 0xCC); Ow_Write(&PORTE, 2, 0xBE); // Issue command SKIP_ROM // Issue command READ_SCRATCHPAD temp = Ow_Read(&PORTE, 2); temp = ((Ow_Read(&PORTE, 2)) << 8) + temp; // Format and display result on Lcd Display_Temperature(temp); Delay_ms(500); //alarm stage..... if(*text>=38) { Sound_Play(880, 1000); // beep ini..1 seconds delay_ms(500); } else if (*text<=38) { } } } while (1); PIC