Převodník: Čtení teplotního čidla LM35DZ a zobrazení na LCD

Ahoj všichni už minimálně 2 týdny se snažím rozhýbat ad převodník ale nějak se nedaří. Už nevím co zkusit Může mne někdo polopatě s vysvětlivkami napsat kod pro cteni teploty z čidla a zobrazeni na sedmisegmentovce. Díky všem za rady.

:arrow_right: administrator: přejmenováno z "převodník"

Záleží na tom, jaké používáš čidlo.

cidlo je toto gme.cz/teplotni-cidla-s-analogovym-vystupem/lm35dz-p313-909/

Tak to se dá převodníkem bez problémů přečíst. Jaký používáš MCU ? A jaký chceš měřit teplotní rozsah ?

v Bascomu používam pro čtení 1WIRE

mcu je tento gme.cz/mikroprocesory-atmel-avr-mega/atmega8-16pu-p432-201/ a teplotni rozsah 0 až 50 stupňů

:arrow_right: administrator: příspěvek byl upraven

Tak to zkus třeba takhle :

        ldi Temp, (1<<REFS1)|(1<<REFS0)|(1<<ADLAR)				; Interní ref 2,56V, Zarovnat doleva, ADC0
        out ADMUX, Temp

        ldi Temp, (1<<ADEN)|(1<<ADFR)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)
		; Povolit ADC, FreeRunningMode, ADC int. enable, 125kHz prescaler
        out ADCSRA, Temp

        sbi ADCSRA, ADSC ; spustit ADC

Hodnotu AD převodu ukládám v přerušení :

ADC_INT: 					; ADC Conversion Complete Handler
		in Hodnota_AD ADCH
		reti

A ještě definice registrů :

.def Temp=R16
.def Hodnota_AD=R8

V programu používám registry jako proměnné, protože jich moc nepotřebuju, pokud by bylo třeba, lze hodnotu po přečtení z AD převodníku uložit do RAM. Navíc se spokojím jen s 8-bitovým převodem. Ve Tvém přípdě je to (v tomto nastavení) 0=0V 255=2,56V. Rozsah by se dal upravit buď zesílením signálu z čidla pomocí OZ tak, aby bylo při 0,5V (50 stupňů) = 2,50V na vstupu do převodníku. Pak dostáváš hodnotu AD převodníku/5 = teplota. Totéž bys dostal, pokud signál z čidla pošleš na AD přímo a pro AD převodník použiješ externí referenční napětí 0,512V.

Pokud nezesílíš signál, pak dostaneš 0V=0 a 0,5V = 50. Je pravda, že dostaneš hodnotu teploty bez nutnosti počítání, zase bude možná hodnota náchylnější ke zkreslení vlivem rušení.

Díky skusím se v tom zorientovat , zapoměl jsem napsat jestly by to nešlo v C

Nastavení AD převodníku :

ADMUX=(1<<REFS1)|(1<<REFS0)|(1<<ADLAR);
ADCSRA=(1<<ADEN)|(1<<ADFR)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) ;
ADCSRA|=ADSC;

Čtení hodnoty :

ISR(ADC_vect)
{
  Hodnota_AD=ADCH;
}

Deklarace proměnných :

unsigned char Hodnota_AD;

Proměnnou Hodnota_AD bych v tomto případě definoval jako globální.

Jinak ve Freerunning módu můžeš číst proměnnou ADCH kdykoliv během programu. Já jsem vytáhl kousek kódu, kde ADCH přečtu v přerušení a v přerušení od časovače pak ten registr šoupnu do OCR2 registru časovače. AD převodníkem zjišťuju okolní osvětlení a načtenou hodnotou pak pomocí PWM řídím jas LED displeje pro zobrazení, který se průběžně přizpůsobuje okolnímu osvětlení. Výhodou tohoto řešení je, že v registru mám poslední načtenou hodnotu okolního osvětlení, čtení AD převodníku nekoliduje s ukončením převodu a vzhledem k tomu, že refresh 4-místného displeje nechávám na časovači a v programu se o něj nestarám, tak se časovač zároveň stará i o jas displeje. Data pro displej pak v programu jen zapisuju do SRAM a o zbytek se postarají obsluhy přerušení.

OK díky moc zítra to odskouším a dám vědět jak to dopadlo

Nejdříve to nefungovalo tak jsem skusil změnit ADCSRA|=ADSC;//puvodní ADCSRA |=(1<<ADSC);//na toto jako jsou ostatní
stále to ještě nešlo tak jsem skusil přidat

sei();//povoluje globalní přerušení

a naskočila teplota.
Ale ještě nechápu jakto že se nemusí přepočítávat podle tohoto převodu u = ((long)adc*5000/1024);
a zobrazuje to přímo stupně?

  1. Gratukuju :
ADCSRA|=ADSC;
     změnít na 
ADCSRA |=(1<<ADSC);//na toto jako jsou ostatní

Jak nepoužívám C, tak mi tohle uniklo.

  1. Načítá se hodnota v přerušení. Povolit přerušení, když ho používáš jsem považoval za naprosto automatické, ale to je asi dané zkušenostmi - pak člověk některé věci bere za tak samozřejmé, že mu uniknou. Nicméně, není nutné jej používat a můžeš hodnotu z AD převodníku číst přímo v programu. Pak bys navíc nepovoloval přerušení od ADC (bit ADIE). Fungovalo by to stejně. Důvod, proč jsem použil přerušení už jsem Ti psal posledně.

  2. Proč nepotřebuješ přepočet :

Hodnota napětí se vypočítá jako U=ADCUref/1024 pro 10-bitový převod.
Čtením pouze ADCH čteš jen horních 8 (z deseti) bitů AD převodníku.
Tudíž přepočet je U=ADCH
Uref/256.
Uref je nastavené na interní referenci 2,56V.
Po dosazení je U=ADCH*2,56/256=ADCH/100 [V].
1 bit tudíž odpovídá 1/100V.
Čidlo používá rozlišení 10mV/1 stupeň C => 1 stupeň = 1/100V.
Pokud tedy platí, že 1 stupeň C = 1/100 V, pak platí, že Teplota = ADCH.

Ještě doplním :
Pokud bys četl převodník celý (tedy 10 bitů), dostaneš výpočet
U=ADC*2,56/1024=ADC/400. Při stejné maximální hodnotě dostáváš, rozlišení 1/4 stupně C. S určitou chybou danou přesostí převodníku a čidla. Lépe tedy můžeš zaokrouhlit teplotu na celé číslo :
Teplota=celá část z (ADC/4+0,5) nebo jak to napsat …

OK Díky moc za rady.