Komunikace s čidlem SHT21 - senzor ukazuje vyšší teplotu

Zdravim, mel bych dotaz, zda ma nekdo zkusenosti s cidlem SHT21?
Resim momentalne mereni teploty:
Napsal jsem komunikaci, cidlo odpovida, ale po prevedeni binarniho cisla, ktere mi cidlo posle a po prevodu podle daneho vzorce z datasheetu mi ukazuje teplotu 68°C.
Pri ochlazovani cidla merena teplota klesa, pri ohrivani roste, ale namerene hodnoty nejsou realne.

Spis se ptam zda s cidlem mel nekdy nekdo podobny problem, pripadne bych poslal zdrojak jak ten kod vypada, mozna ze by tam nekdo chybu vykoukal, ale at jsem to prosel xkrat, nenasel jsem.

Pak me jeste napadlo, zda to nemuze byt tim, ze bylo cidlo napajeno na plosnak pri max teplote 320°C (cca 30sec) a v datasheetu ma uvedene maximum 260°C (po dobu 30sec) - predpokladam ze v tom ale problem nebude, ty soucastky toho vetsinou snesou mnohem vic.

Dekuji za jakekoliv rady.

:arrow_right: administrator: přejmenováno z "komunikace s cidlem SHT21"

co AREF interní(externí) není tam problém při převodu?

Muzete mi vice nastinit co tim myslite? Jedna se totiz o cidlo s cislicovym vystupem, takze zadnou referenci neresim. Z cidla dostanu 16b cislo, ktere pak prevadim podle vzorce z datasheetu na dekadickou hodnotu ve °C. Mozna jsem ale jen spatne neco pochopil (nebo prehledl ohledne te reference) z datasheetu a to je ten problem, proto prosim o vysvetleni.
Dekuji

hodnotu snímáš na ADC? jak to máš zapojené? jaký MCU?

Jedna se o Megu16. Cidlo pouziva I2C komunikaci. Takze ma sck a data. Vyvod data mam pripojen na jednom pinu megy a sck na druhem pinu megy.
Cidlo pozadam o data a pak je s kazdym sck maskuji, posouvam a ukladam do promenne. Takze odectu vsech 16b, ktere pak prevedu na dekadickou hodnotu °C].

no a ten příjem není náhodou jen 10b ADC? já bych zkusil klasicky odečíst konstantu na reálnou hodnotu pokd můžeš porovnat nějakým ex mněřákem teploty

No ja nevim, mozna tomu problemu tolik nerozumim, ale rekl bych ze to ADC neovlivnuje. Tak cidlo mi s kazdym hodinovym pulsem posle jeden bit. Ja mam vytvorenou 16b promennou. Do ni postupne vymaskuji prvnich 8b, pak vyslu ACK (dle datashhetu), posunu tech 8b o 8 mist doleva a prictu k tomu opet dalsich 8 vymaskovanych bitu - tim dostanu 16b cislo, ktere pak prevadim v procesoru.
Nic s ADC preci nedelam, to uz je zajisteno v samotnem cidle. Ja uz pouze ctu cislicovou hodnotu.

(ale mozna jsem jen natvrdlej a neco mi uniklo :slight_smile:

přiznam to čidlo neznam a napájení podle datašetu je 3,3V od toho se odvozuje výpočet máš ho na 3,3V?

Podle datasheetu k memu cidlu SHT21 ctu:

Supply Voltage: min:2,1V typ:3,0V max:3,6V
Cidlo napajim pres odporovy delic napetim 3,2V, coz by problem byt nemel. Nikde v datasheetu jsem nenasel ani prepocet teploty podle napajeni (jak tomu bylo u verze SHT11).

Predpokladam ze tady problem tedy nebude.

Muzes prosim poslat ty cisla co ti dava senzor pri komunikaci a co ti dava po pouziti toho vzorce?
Napis jake pouzivas rozliseni a jestli hold master nebo no hold master
Prosim pro overeni jeste posli co si myslis ze posilas do senzoru
Diky

Takze pri mereni teploty mi cidlo posle pri pokojove teplote toto binarni cislo:
1010 1010 0111 0000,
po pouziti vzorce a pretipovani na char dostanu cislo: 70 (overeno i pomoci kalkulacky, ze to ma vyjit 70,14).
Rozliseni je defaultni, takze 14b a rezim No Hold Master

A do senzoru posilam:

[code]#define mer_teplotu 0xf3
#define i2c_adr_w 0b10000000
#define i2c_adr_r 0b10000001

start_sekvence();
zapis_byte(i2c_adr_w);
zapis_byte(mer_teplotu);
_delay_ms(1000);
start_sekvence();
zapis_byte(i2c_adr_r);
_delay_ms(1000);
start_sekvence();
zapis_byte(i2c_adr_r);

teplota |= precti_byte(0)<<8; //precteni prvnich 8 bitu dat (MSB)
teplota |= precti_byte(1); //precteni druhych 8 bitu dat (LSB)
stop_sekvence();

teplota &= ~0x0003; //vymaze posledni 2 bity ()
t = -46.85 + 175.72/65536 * (float)(teplota);[/code]

A samotne funkce vypadaji takto:

[code]#define sht_sck0 {PORTD&=0b11111110;}
#define sht_sck1 {PORTD|=0b00000001;}
#define sht_data0 {PORTD&=0b11111101;}
#define sht_data1 {PORTD|=0b00000010;}

void start_sekvence(void)
{
DDRD|=0b00000011; //nastaveni bitu sck a data na vystupni

sht_sck1;
sht_data1;
sht_data0;
_delay_us(10);
sht_sck0;
_delay_us(10);
}

void stop_sekvence(void)
{
DDRD|=0b00000011; //nastaveni bitu sck a data na vystupni

sht_sck0;
sht_data0;
sht_sck1;
_delay_us(10);
sht_data1;
_delay_us(10);
}

unsigned char zapis_byte(unsigned char hodnota)
{
unsigned char maska, err = 0;
DDRD|=0b00000010; //nastaveni linky (sht_data) na vystup
for (maska=0x80; maska>0; maska>>=1) //maskovani
{
//vymaskovana hodnota-zapis log0 or 1 na sber.
if (maska & hodnota) {sht_data1;}
else {sht_data0;}
_delay_us(1);
sht_sck1; //clk pro sbernici
_delay_us(5); //drzeni clk v log0
sht_sck0; //shozeni clk
_delay_us(1);
}
DDRD&=0b11111101; //nastaveni linky (sht_data) na vstup
sht_sck1; //9. clk pro ACK
_delay_us(1);
err=bit_is_set(PIND, PD1); //pokud neprijde ACK -> err=1
sht_sck0;
_delay_us(20);
return err;

}

unsigned char precti_byte(unsigned char ack)
{
unsigned char maska, merena_hodnota = 0;
DDRD&=0b11111101; //nastaveni linky (sht_data) na vstup
for (maska=0x80; maska>0; maska>>=1) //maskovani
{
sht_sck1;
_delay_us(5);
if (PIND & 0b00000010)
merena_hodnota=(merena_hodnota | maska);
sht_sck0;
_delay_us(1);
}

DDRD|=0b00000010;		//nastaveni linky (sht_data) na vystup
if(ack==0)
{ sht_data0; }
else
{ sht_data1; }	
_delay_us(1);
sht_sck1;
_delay_us(5);
sht_sck0;
sht_data1;
DDRD&=0b11111101;		//nastaveni linky (sht_data) na vstup
_delay_us(20);
return merena_hodnota;

}[/code]

Dekuji moc za ochotu.

Mohl bys napsat jaké byly ty dva přijaté bajty, ze kterých jsi vypočítal 68 st C ?

Edit: Pozdě.

Možná by bylo dobré přečíst i CRC a zkontrolovat jestli souhlasí.

Druhá věc: ve funkci zapis_byte() máš kontrolu přijetí ACK, tak bych ji v hlavním programu využil.

Kdyz si vypisu error, tak mi to hodi 0, coz by melo byt ok.
Divne vsak je, ze kdyz vynecham cas kodu kde posilam pri cteni jako odpoved AKC:

DDRD|=0b00000010; //nastaveni linky (sht_data) na vystup if(ack==0) { sht_data0; } else { sht_data1; } _delay_us(1); sht_sck1; _delay_us(5); sht_sck0; sht_data1; DDRD&=0b11111101; //nastaveni linky (sht_data) na vstup _delay_us(20);

Tak se vysledna hodnota teploty nemeni. Stale mi to vypisuje nerealne hodnoty kolem 70°C plus minus podle toho jaka je skutecna teplota.
Pokusama jsem zjistil, ze mi cidlo odecita a prijima adresy i pri sck=0.

To je hodně divné.
Zkus ještě ten CRC.
Přijmi tři bajty místo dvou a všechny tři sem napiš.

Tak po vypsani 3x8b to vypada takto:

10100000 11111100 - teplota
11111111 - crc

S tim, ze ten kontrolni soucet mi to vzdy posle 8 logickych jednicek a teplotu to posila dost chaoticky. Stalo se mi trebas ze mi to poslal teplotu jen 13b, nekdy 9b a to uplne jinych nez trebas orizly puvodni 16b cislo teplotni.

Takze opravdu nevim co je spatne, zacinam to pomalu davat za vinu prilis vysoke teplote pri ktere byl cip pajen.

Tak problem zrejmne vyresen, toto cele tema se muze asi smazat, jelikoz v nem neni nic prinosneho.
Prisel jsem na to, ze je cidlo asi vazne poskozene. Zkusil jsem nove cidlo SHT11, komunikace take po I2C a slape jak hodinky.