DS1820 - dlouhé vedení
Moderátor: Moderátoři
DS1820 - dlouhé vedení
Zapojení: ATTINY2313 + DS1820 4k7 upl.odpor, 3 vodičové připojení.
Při délce vedení cca 4m funguje odečítání teploty správně. Při délce vedení cca 10m dochází zvl. při záporné teplotě k chybě až 50%. Potřeboval bych poradit jeli chyba v délce vedení, či spíše v SW.
Zde je použitá rutina
void mereni()
{ asm WDR
Ow_Reset(&PORTd, 2); // Onewire reset signal
Ow_Write(&PORTd, 2, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTd, 2, 0x44); // Issue command CONVERT_T
delay_us(200);
Ow_Reset(&PORTd, 2);
Ow_Write(&PORTd, 2, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTd, 2, 0xBE); // Issue command READ_SCRATCHPAD
delay_ms(100);
TI=Ow_Read(&PORTd, 2);
delay_ms(100);
TI=(Ow_Read(&PORTd, 2) << + TI; //mereni vnitrni teploty
delay_ms(100);
if (TI & 0x8000) // check if temperature is negative
{tin[0] = '-'; TI = ~TI + 1;} else tin[0]='+';
TI=TI>>4;
tin[1] = (TI/10)%10 + 48; // Extract tens digit
tin[2] = TI%10 + 48; // Extract ones digit
asm WDR
Ow_Reset(&PORTd, 3); // Onewire reset signal
Ow_Write(&PORTd, 3, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTd, 3, 0x44); // Issue command CONVERT_T
delay_us(200);
Ow_Reset(&PORTd, 3);
Ow_Write(&PORTd, 3, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTd, 3, 0xBE); // Issue command READ_SCRATCHPAD
delay_ms(100);
TO= Ow_Read(&PORTd, 3);
delay_ms(100);
TO = (Ow_Read(&PORTd, 3) << + TO; //mereni venkovni teploty
delay_ms(100);
if (TO & 0x8000) //TOUTje TOPOM ve znacich
{tout[0] = '-'; TO = ~TO + 1; } else tout[0]='+';
TO=TO>>4;
tout[1] = (TO/10)%10 + 48; // Extract tens digit
tout[2] = TO%10 + 48; // Extract ones digit
acit=0;
asm WDR
return;
Při délce vedení cca 4m funguje odečítání teploty správně. Při délce vedení cca 10m dochází zvl. při záporné teplotě k chybě až 50%. Potřeboval bych poradit jeli chyba v délce vedení, či spíše v SW.
Zde je použitá rutina
void mereni()
{ asm WDR
Ow_Reset(&PORTd, 2); // Onewire reset signal
Ow_Write(&PORTd, 2, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTd, 2, 0x44); // Issue command CONVERT_T
delay_us(200);
Ow_Reset(&PORTd, 2);
Ow_Write(&PORTd, 2, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTd, 2, 0xBE); // Issue command READ_SCRATCHPAD
delay_ms(100);
TI=Ow_Read(&PORTd, 2);
delay_ms(100);
TI=(Ow_Read(&PORTd, 2) << + TI; //mereni vnitrni teploty
delay_ms(100);
if (TI & 0x8000) // check if temperature is negative
{tin[0] = '-'; TI = ~TI + 1;} else tin[0]='+';
TI=TI>>4;
tin[1] = (TI/10)%10 + 48; // Extract tens digit
tin[2] = TI%10 + 48; // Extract ones digit
asm WDR
Ow_Reset(&PORTd, 3); // Onewire reset signal
Ow_Write(&PORTd, 3, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTd, 3, 0x44); // Issue command CONVERT_T
delay_us(200);
Ow_Reset(&PORTd, 3);
Ow_Write(&PORTd, 3, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTd, 3, 0xBE); // Issue command READ_SCRATCHPAD
delay_ms(100);
TO= Ow_Read(&PORTd, 3);
delay_ms(100);
TO = (Ow_Read(&PORTd, 3) << + TO; //mereni venkovni teploty
delay_ms(100);
if (TO & 0x8000) //TOUTje TOPOM ve znacich
{tout[0] = '-'; TO = ~TO + 1; } else tout[0]='+';
TO=TO>>4;
tout[1] = (TO/10)%10 + 48; // Extract tens digit
tout[2] = TO%10 + 48; // Extract ones digit
acit=0;
asm WDR
return;
- ross4435897
- Příspěvky: 426
- Registrován: 10 lis 2009, 01:00
- Bydliště: Brno
// onewire
OneWireReset();
OneWireOutByte(0xcc);
OneWireOutByte(0x44);
PORTB |= _BV(DS_BIT);
DDRB |= _BV(DS_BIT);
_delay_ms(1000);
DDRB &= ~_BV(DS_BIT);
PORTB &= ~_BV(DS_BIT);
OneWireReset();
OneWireOutByte(0xcc);
OneWireOutByte(0xbe);
DSdata[0] = OneWireInByte();
DSdata[1] = OneWireInByte();
int16_t TReading = (int)(DSdata[1] << + DSdata[0];
SignBit = TReading & 0x8000;
if (SignBit) TReading = (TReading ^ 0xffff) + 1;
// vypocet teploty
TReading = (((6 * TReading) + TReading / 4)); // 2345 = 23.45 stupnu Celsia
... melo by tam byt minimalne 750ms
OneWireReset();
OneWireOutByte(0xcc);
OneWireOutByte(0x44);
PORTB |= _BV(DS_BIT);
DDRB |= _BV(DS_BIT);
_delay_ms(1000);
DDRB &= ~_BV(DS_BIT);
PORTB &= ~_BV(DS_BIT);
OneWireReset();
OneWireOutByte(0xcc);
OneWireOutByte(0xbe);
DSdata[0] = OneWireInByte();
DSdata[1] = OneWireInByte();
int16_t TReading = (int)(DSdata[1] << + DSdata[0];
SignBit = TReading & 0x8000;
if (SignBit) TReading = (TReading ^ 0xffff) + 1;
// vypocet teploty
TReading = (((6 * TReading) + TReading / 4)); // 2345 = 23.45 stupnu Celsia
... melo by tam byt minimalne 750ms
- Přílohy
-
- ATTINY13_termostat.c.txt
- (5.68 KiB) Staženo 116 x
Doporučil bych začínat třeba zde:
http://www.ebastlirna.cz/modules.php?na ... ht=ds18b20
http://www.ebastlirna.cz/modules.php?na ... ht=ds18b20
Pánové,
děkuji všem za rady a tipy.
I v tomto případě platilo staré programátorské pravidlo: při odstranění jedné chyby se do programu zanesou nejméně tři další!! Při úpravě programu a při změně DS18B20 za DS18S20 jsem zapoměl změnit posun o 4bity na posun poze 1 bitu. Chyba se při kladnývh teplotách neprojevuje, ale při záporných je to katastrofa.
děkuji všem za rady a tipy.
I v tomto případě platilo staré programátorské pravidlo: při odstranění jedné chyby se do programu zanesou nejméně tři další!! Při úpravě programu a při změně DS18B20 za DS18S20 jsem zapoměl změnit posun o 4bity na posun poze 1 bitu. Chyba se při kladnývh teplotách neprojevuje, ale při záporných je to katastrofa.
Ja tam dal dal tusim 1k, trochu to pomohlo, ale vyrazne se chybovost snizila az namotanim par zavitu privodnihu dratu na feritovy krouzek.
Mam vedeni cca 30m nestinenym kabelem vedenym vedle silovych (jina moznost nebyla) a uz neni problem. Obcas se jeste chybka vyskytne, ale ta se odfiltruje kontrolou CRC.
Mam vedeni cca 30m nestinenym kabelem vedenym vedle silovych (jina moznost nebyla) a uz neni problem. Obcas se jeste chybka vyskytne, ale ta se odfiltruje kontrolou CRC.
ferit si dal na přívodní drát napájení, nebo na ten drát co vedek od čidel?
Mě se nechtělo laborovat s kontrolou crc, tak sem udělal, že dám konvert a pak vyčtu z čidla hodnotu 3x zasebou a porovnám jestli jsou stejné. Pokud ne, tak začítám znovu a pracuju s hodnotou z minilého měření.
Dříve mi občas na lcd problikla nesmyslná hodnota, ale od téhle úpravy už nikdy.
Mě se nechtělo laborovat s kontrolou crc, tak sem udělal, že dám konvert a pak vyčtu z čidla hodnotu 3x zasebou a porovnám jestli jsou stejné. Pokud ne, tak začítám znovu a pracuju s hodnotou z minilého měření.
Dříve mi občas na lcd problikla nesmyslná hodnota, ale od téhle úpravy už nikdy.
Ferit jsem dal na datove vedeni, dival jsem se na to osciloskopem, bylo tam naindukovano hodne vf bordelu.
Mi se s tim crc taky nechtelo drbat, ale ty cidla jsou dost proflakle a tak nebyl problem najit na internetu kod kde to jiz nekdo napsal. Proste jsem jen rychle zkopcil kus kodu, fungovalo to a tak jsem to dal nekoumal. Bylo to tusim pro nejakou x51, jestli ti to bude k necemu, muzu ti ho najit.
Mi se s tim crc taky nechtelo drbat, ale ty cidla jsou dost proflakle a tak nebyl problem najit na internetu kod kde to jiz nekdo napsal. Proste jsem jen rychle zkopcil kus kodu, fungovalo to a tak jsem to dal nekoumal. Bylo to tusim pro nejakou x51, jestli ti to bude k necemu, muzu ti ho najit.