Čidlo teploty DS18B20

Zdravím, potřeboval bych poradit jak vypočítat teplotu na jedno desetinné místo. Jedná se o DS18B20 nastavený na 10bit převod, tj. rozlišení 0.125 stupně. Komunikace je v pořádku, čtení scratchpadu taky, jenom nemohu přijít na přepočet těch dvou byte ve kterých je uložena teplota. Díky za každou (rozumnou) radu.
Ještě bych chtěl dodat, v datasheetu je napsáno že výstupní hodnota je ve stupních celsia, ale po převodu z BIN na DEC to ukazuje nesmysl.

když se podíváš do datash., tak teplotu přijmeš ve dvou Bytech - a zrovna 18B20 má: celé st.C rozdělené, tj. ve vyšším Bytu 4 nižší bity a v nižším Bytu 4 vyšší bity = celé st.C, a desetiny já zrovna prepocitávám z 4 nižších bitů. Je tozřejmé z datasheetu str. 3. Napiš mi na můj email - je v mém profilu - pošlu ti , jak jsem to řešil já.

Pro urychlení - je tu moje rutina:

;tohleto je pokracovani rutiny pro prepocet prijmutych 2 Bytes
;na Teplotu v celych st.C, a prepocet 4 bitu na Desetiny
;take vyhodnoceni znamenka

mov	a,#0beh 	;čtení minule nasnimanych hodnot
call	DS18Write	;
call	DS18Read
mov 	R2,a    	;uschová nizsi prijaty Byte
call	DS18Read
mov 	R1,a    	;uschová vyssi prijaty BYTE
		;----- vyhodnoceni znamenka
anl	A,#0F0H	
jz	Kladne		;A=0 = kladne
mov	A,R1		;A>1 = zaporne
cpl	A
mov	R1,A
mov	A,R2
cpl	A
mov	R2,A		;------ uprava na cele kladne stupne C
setb	Minu		;1= zaporneho znamenko
sjmp	Dal

Kladne: clr Minu ;0=kladne znamenko
Dal: mov a,R2 ;TeplL - uprava na cele kladne st.C
anl A,#0F0H
swap a
mov R0,A
mov a,R1 ;TeplH
anl A,#0FH
swap a
orl A,R0 ;teplota cele st.C v acc
ret
;-----------------------
Desetiny: ;------ uprava na vypocet desetin, setin,…
;v R2 je
mov 21h,R2 ; xxxx 1000 = 0.5 st.C 0.50
jb 0bh,Aet ; xxxx 0100 = 0.25 st.C 0.25
mov A,#0 ; xxxx 0010 = 0.125st.C 0.12
sjmp Bet ; xxxx 0001 = 0.0625st.C 0.06
Aet: mov A,#50 ;1/2 st.C
Bet: jb 0ah,Cet
mov b,#0
sjmp Det
Cet: mov b,#25 ;1/4 st.C
Det: add a,b
jb 09h,Eet
mov b,#0
sjmp Fet
Eet: mov b,#12 ;1/8 st.C
Fet: add a,b
jb 08h,Get
mov b,#0
sjmp Zet
Get: mov b,#7 ;1/16 st.C
Zet: add a,b
mov b,#10
div ab ;desetiny st.C v acc, setiny v B
;[zobrazuji jen desetiny]
ret

Celé stupně jsou tedy jasné, ale pořád nechápu co s tím desetinným místem které je, jak píšeš obsaženo v prvních čtyřech bitech nižšího byte. Z tvé rutiny to nějak nemohu vyčíst, protože programuji PIC a to ještě v C. Prosím tě tedy o napsání normální matematické operace, snad to pak pochopím. Jinak díky za informace a trpělivost se mnou.

Takže - pokud víš, jak na celé st.C, tak desetiny jsou obsažené v nižších 4 bitech nižšího Bytu, a to tak, že bit 3 je 0,5st.C, (pokud je v 1), bit 2 je 0,25st.C, bit 1 je 0,125 st.C a bit 0 je 0,0625 st.C (vždy, když jsou v 1). Takže to jen matematicky sečteš (50+25+12+6)/10=a vyjdou ti desetiny, … zobrazovat, nebo brát v potaz setiny a míň, asi nemá smysl… To se však týká jen DS18B20, jiné myslím mají jiné uspořádání - nejjednodušší je podívat se do Datash. datasheetcatalog.com/datashe … 8B20.shtml je tam tabulka a je to zřejmé. V případě, že se teplota dostane do mínusu, je to trochu jinak, přijaté Byty jsou negované, …
0000 0001 0110 0000 = 22,0 st.C
0000 0000 1000 1000 = 8,5 st.C
0000 0000 0001 0100 = 1,25 st.C
0000 0000 0000 0000 = 0 st.C
1111 1111 1111 1000 = -0,5 st.C
1111 1111 1101 0000 = -2,0 st.C
Prosím tě - stáhni si Datasheet.

Sory - v předešlém příspěvku se mi tam vloudila chybička v záporných teplotách. Takže, pokud bude teplota záporná (pozná se podle vyššího Bytu, začíná 1… , tzn. údaj tepl. je negovaný, takže já nejdřív zjistím, zda nejvyšší bit je jedna, pak je teplota záporná a oba Byty neguji a dále klasicky prepočítám - jak je zmíněno výše. Takže, pokud je tepl. záporná:
1111 1111 1010 0111 = -5,5 st.C
1111 1110 1101 0011 = -18,75 st.C

Promiň za to zpoždění, dostal jsem se k tomu až dnes a vypadá to že už desetiny zobrazuje správně, děkuji za vysvětlení.

Dovolí si upozornit na 2 školácké chyby:

  1. Negace wordu není totéž co postupná negace jeho bytů. Negace je vyjádřena takto A´= 0 - A. Takže při odečítání AL´= 0 - AL vznikne výpůjčka, která se musí odečíst v následující operaci: AH´= 0 - AH - Cy.
    Negaci wordu lze provést tak, že se udělá jedničkový komplement jeho bytů a word se incrementuje.

  2. Číslo 0b111111111010.0111 není -5,5! Záporná čísla se vyjadřují jako doplněk do 0, takže musí platit:

0b111111111010.0111 ;možná -5,5
0b000000000101.1000 ;učitě +5,5


0b111111111111.1111 ;součet není 0 ale -1/16

Převod na desetiny je tak jednoduchý, že se divím, že to tu nikdo nezmínil. Když pominu binární tečku v oněch 2 bytech, dostanu teplotu 16x vyšší. Stačilo by vydělit 16, ale v oboru celých čísel se desetiny zahazují, resp. vyjádří se zbytkem po dělění. Ten stačí vynásobit 10 a desetiny stupně jsou na světě. V céčku by to šlo třeba takhle:

int BinTeplota; //teplota z DS18B20
char Teplota[6]; //teplota vyjářena řetězcem
Teplota = IntToStr(BinTeplota*10/16);

Pak už jen stačí před poslední znak vepsat desetinou čárku.

Díky za radu, vyzkouším a napíšu jak to dopadlo.

Vše funguje jak má, děkuji “pane” Technik.

Zdravím, po nějaké době zase stavím snímač teploty, tentokrát venkovní a tak potřebuji i zápornou teplotu. A tady si nevím rady, pokud teplota klesne pod nulu, na displeji je stále nulová hodnota. Teplota do plusu se zobrazuje normálně.
Funguje to někomu s měřením do mínusu ?

Musí to fungovat úplně stejně. Čidlo Zkrátka vrací 16ti násobek a to jak v kladných tak v záporných hodnotách. Je to PŘÍMO INT. Není potřeba udělat nic jiného, než načíst ony 2B ze scratchpadu a poskládat je do intu (signed int), který pak můžeš převést na string.
Sice jsem to netestoval, ale není důvod aby to nefungovalo.
Jukni sem: https://forum.mcontrollers.com/t/kratka-dema-pro-avr/1829/1
Je to pro avr, ale to nic nemění na způsobu ždímání dat ze senzoru. Zajímá tě poslední funkce v ds18b20.c (DS_MULTI je násobitel, pokud bude = 10, dostaneš teplotu 10x větší).
Když to nedáš do kupy, přihoď svoji fukci, která má na starost čtení scratche a vracení teploty.

Ja som to riešil a ide to v poho. Tu je kus kodu pre citanie cidla a prepocet. Je to trochu divocina, zobrazujem to cez multiplex na 7-segmentovke takze su tam aj prevody na zobrazenie a casove slucky na cakanie na multiplex. Snad sa z toho vysomaris, ak bude treba pomoct, napis.

[code]//Čtení čidla 1
RESET(&PORTB,0);
t = 1;
while (t)
{
}
Ow_Write(&PORTB,0,0xCC);
t = 1;
while (t)
{
}
Ow_Write(&PORTB,0,0xBE);

//Načtení obsahu scratchpadu do a1[0] - a1[9]
t = 1;
while (t)
{
}
for(a1=0;a1<9;a1++)
{
scratchpad[a1]=Ow_Read(&PORTB,0);
}

Temp = scratchpad[1]<<8|scratchpad[0];
Znam = Temp & 0x8000;
Teplota = Temp >> 1;

//Zobrazení teploty čidla 1
// Lcd_Out(1,1,"t1 = ");

if (Znam)
{
	Temp = (Temp ^ 0xFFFF) + 1;
	Teplota = Temp >> 1;
	text[0] = '-';
	a = znak[10];
}
else
{
	if (Teplota/100)
     {
		text[0] = (Teplota/100) + 48;
		a = znak[1];
	 }
	else
	 {
	 	text[0] = ' ';
		a = znak[11];

	 }
}
	text[1] = (Teplota/10)%10 + 48 ;
	b = (Teplota/10)%10;
	b = znak**;
	if ((b == znak[0]) & (a != znak[1]) ) b = znak[11];
	text[2] = (Teplota%10) + 48 ;
	c = (Teplota%10);
	c = znak[c] + 0x80;

	Teplota = Temp <<3; 

//Výpočet setin
setiny = (Teplota & 0x000F);
setiny = setiny * 625;

//výpočet pro zobrazení setin
text[4] = setiny/1000 + 48;
d = setiny/1000;
d = znak[d];
[/code]

Ako rutine pre pracu s DS1820 pouzivam v prilohe**
OneWire.h (1.62 KB)