DS1621 hőmérő - hibás hőfok?

Processing/Wiring (illetve C) nyelvű programozási fogások, tippek. (AVR-Duino, Arduino, EthDuino, Diecimila, Severino, Nano, LilyPad)
Válasz küldése
Avatar
Giorgio
DrótVégénSzéndarab
Hozzászólások: 18
Csatlakozott: 2008. január 26. szombat, 7:00

Hozzászólás Szerző: Giorgio »

Sziasztok!
Egy ismert probléma megoldását szeretném kérni tőletek.
Adott egy DS1621 hőmérőm és mindig kb. 2 fokkal többet mutat, mint a valódi. Utána olvastam és több elméletet kipróbáltam már, de nincs eredmény, ezért döntöttem a teljes kód beszúrása mellett. Az I2C fgv-ekről annyit, hogy az összes állapothoz tartozó TWSR érték megfelelő, csak most a próba alatt ezt nem szedtem ki. A TempUpdate a főprogramból kerül meghívásra x időnként. Az alap jelenleg az, hogy Done bit ell, ha OK, mehet a 1shot és a Start konverzió, majd várok egy kicsit, újra Done bit ellenőrzés és érték kiolvasás. DE ez nem kalács. Előre is köszi a segítséget és bocsi a c miatt, de nem hinném, hogy ez gondot okozna nektek.

Kód: Egész kijelölése


#define I2C_START TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
#define I2C_EN TWCR = (1<<TWINT)|(1<<TWEN)
#define I2C_STOP TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
#define I2C_ACK_EN TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA)
#define I2C_ACK	while (!(TWCR & (1<<TWINT)))

int I2Ccommand,I2Caddress,I2Cdata,I2CClockStatus,I2Chibajel,bflag;
int i,TH,TL; 

int TempUpdate()

{
	I2CBusy(144,0xAC);				// busy flag ellenőrzés
	if(bflag == 128)				// konverzió kész, kezdődhet a mérés
		{							// vagy a hőmérséklet értékek kiolvasása
//		PORTC = 1;					// vizuális ellenőrzés 
		I2C1shot(144,0xAC,1);		// 1shot
		I2Cstart(144,0xEE);			// Start Convert
		I2CBusy(144,0xAC);
		if(!(bflag == 128))			// itt még nincs kész a konverzió (ez csak
//			PORTC = 0;				// próbának szúrtam be: rendben
									// működik az I2CBusy függvényem)
									// vizuális ellenőrzés 
		_delay_ms(1000);			// várok ezerrel, a konvetálás
									// befejezéséhez (teszt üzemmód)
		I2CBusy(144,0xAC);			// busy flag ellenőrzés
		if(bflag == 128)			// itt már kész a konverzió
			{
//			PORTC = 2;				// vizuális ellenőrzés 
			_delay_ms(100);			// kis delay, hogy lássam is
			I2CTempRead(144,0xAA);	// hőmérséklet értékek kiolvasása
			}
//		PORTC = 0;					// vizuális ellenőrzés 
		}
	else
		;

	itoa(TH, LcdText+17,10);		// kijelzés 
	if(TL == 128)
		TL = 5;

	itoa(TL, LcdText+20,10);
	memcpy(LcdText+19,".",1);
	memcpy(LcdText+22,"C",1);
	LcdText[21] = 223;
}


int I2Cstart(int I2Caddress, int I2Ccommand)
{		
	I2C_START;
	while (!(TWCR & (1<<TWINT)))	// START
	;
	TWDR = I2Caddress;	// SLA + W
	I2C_EN; 
	while (!(TWCR & (1<<TWINT)))
	;
	TWDR = I2Ccommand;	// Command
	I2C_EN;
	while (!(TWCR & (1<<TWINT)))
	;
	I2C_STOP;	// STOP
}


int I2C1shot(int I2Caddress, int I2Ccommand, int I2Cdata)
{	
	I2C_START;
	while (!(TWCR & (1<<TWINT)))
	;
	TWDR = I2Caddress;	// Slave address + 0
	I2C_EN; // SLA+W 
	while (!(TWCR & (1<<TWINT)))
	;
	TWDR = I2Ccommand;	// Access Config
	I2C_EN;
	while (!(TWCR & (1<<TWINT)))
	;
	TWDR = I2Cdata;	// 1 shot
	I2C_EN;
	while (!(TWCR & (1<<TWINT)))
	;
	I2C_STOP;
}


int I2CTempRead(int I2Caddress, int I2Ccommand)
{
	I2C_START; 
	while (!(TWCR & (1<<TWINT)))
	;
	TWDR = I2Caddress;	// Slave address + 0
	I2C_ACK_EN; // SLA+W 
	while (!(TWCR & (1<<TWINT)))
	;
	TWDR = I2Ccommand;	
	I2C_ACK_EN;  // ACKEN
	while (!(TWCR & (1<<TWINT)))
	;
	I2C_START; // REPEATED START
	while (!(TWCR & (1<<TWINT)))
	;
	TWDR = I2Caddress + 1;	//SLA + R
	I2C_EN;
	while (!(TWCR & (1<<TWINT)))
	;
	I2C_ACK_EN;
	while (!(TWCR & (1<<TWINT)))
	;
	TH = TWDR;
	I2C_EN;
	while (!(TWCR & (1<<TWINT)))
	;
	TL = TWDR;
	I2C_STOP;

	if((TH & 128) == 128)
		{
		memcpy(LcdText+16,"-",1);
		TH = TH - 1;
		TH = TH^255;
		}
	else
		memcpy(LcdText+16,"+",1);	
}


int I2CBusy(int I2Caddress, int I2Ccommand)
{	
	I2C_START; 
	while (!(TWCR & (1<<TWINT)))
	;
	TWDR = I2Caddress;	// Slave address + 0
	I2C_EN; // SLA+W 
	while (!(TWCR & (1<<TWINT)))
	;
	TWDR = I2Ccommand;	// configuration register
	I2C_EN;  
	while (!(TWCR & (1<<TWINT)))
	;
	I2C_START; // REPEATED START
	while (!(TWCR & (1<<TWINT)))
	;
	TWDR = I2Caddress + 1;	// SLA+R
	I2C_EN;
	while (!(TWCR & (1<<TWINT)))
	;
	I2C_EN;
	while (!(TWCR & (1<<TWINT)))
	;
	bflag = TWDR&128;
	I2C_STOP;
}
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Lehet hogy a chiped nem jó? Más fordítóval, más kóddal működik?
Ha a forrasztás sok idő volt, akkor a belső hőmérődióda károsodhatott....
Avatar
Giorgio
DrótVégénSzéndarab
Hozzászólások: 18
Csatlakozott: 2008. január 26. szombat, 7:00

Hozzászólás Szerző: Giorgio »

Köszi a tanácsokat. Kipróbáltam egy másik IC-t is, az is ugyanazt az értéket mutatja és "lehelésre", vagy újj-melegre reagál szépen. Egyébként DIP tokos, nem forrasztottam. Ma újra nekilendülök és, ha kiderül, mit rontottam el, akkor megírom.
Avatar
Giorgio
DrótVégénSzéndarab
Hozzászólások: 18
Csatlakozott: 2008. január 26. szombat, 7:00

Hozzászólás Szerző: Giorgio »

Kiderült, hogy semmit, legalábbis a programban. A két referencia hőmérőm volt pontatlan. Ez hogy fordulhatott elő, azt most hosszú lenne elmondani, de tanulság, hogy hasonló esetben a ref-hőmérőtök legyen pontos, különben három hétig kereshetitek a hibát.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

DS1820 chipet használni referenciának? (1 fok pontosság (jellemzően 0.2-t tudnak, reprodukálhatóan!))


Az I2C-s hőmérőből az LM75/TC75/TCN75 már szívatott meg.... (+/- 3 fok!)
Tuti termosztát: 17...23 fok :)
Avatar
kovacsna
Pákabűvész
Hozzászólások: 208
Csatlakozott: 2008. június 3. kedd, 6:00

Hozzászólás Szerző: kovacsna »

A DS1820-at már nem ajánlja a MAXIM. Helyette ez van: DS18S20 +-0,5C pontos.

DS600U? Pontos ez is, nagyon. Építettem már vele hőmérőt!
Vagy A osztályú PT1000.

Viszont lehet kapni , kalibrált, tized osztású, higanyos labor hőmérőt is! Nem olcsó (~10e), de tuti pontos!

Amúgy meg 0,5 foknál pontosabban, nagyon nehéz hőmérsékletet mérni...
Válasz küldése