logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

DS1820 - błędne odczyty przy nagłych zmianach temperatury z zamrażarki

pgp 16 Kwi 2006 17:57 1818 8
  • #1 2534696
    pgp
    Poziom 19  
    Posty: 412
    Pomógł: 6
    Ocena: 17
    Gdy do mojego DS1820 przyblizam coś bardzo zimnego ( z zamrazarki) to zaczyna wariować... Temperatury dochodzą do 140 stopni ... Moze ten czujnik źle reaguje na takie nagłe skoki ? A moze chodzi o wilgoć która sie z tego roztapia... Szkoda ze nie ma zimy - wystawiłbym za okno i przetestował...
  • #2 2535494
    Pituś Bajtuś
    Poziom 28  
    Posty: 934
    Pomógł: 137
    Ocena: 10
    A może po prostu procedura konwersji jest poprawna tyko dla dodatnich temperatur? Wrzuć ten kawałek programu który odczytane dane z czujnika przetwarza na postać widzialną dla człowieka...
  • #3 2536291
    pgp
    Poziom 19  
    Posty: 412
    Pomógł: 6
    Ocena: 17
    /////////////////////////////////////////////// czujnik temperatury - funkcje /////////////////////////////

    // OW_RESET - performs a reset on the one-wire
    // returns the presence detect. Reset is 480us Presence
    // another 70us later

    unsigned char ow_reset(void) // reset lini one wire
    {
    unsigned char presence=1;
    sbi(DDRD,3); //DQ = 0; //pull DQ line
    delay(245); // wystawienie na czas 490us "0" na linię 1w przez uC
    cbi(DDRD,3); //DQ = 1; // allow line to //powrót lini 1w do trybu wejścia
    delay(35); // wait for presence pulse(pochodzący od DS-a) //czekamy na ustabilizowanie lini
    if(bit_is_clear(PIND,3)) presence=0; //odczytujemy co wystawił na linię DS
    //get presence

    delay(220); // wait for end
    return(presence); // presence signal
    } // 0=presence, 1 = no part

    ///---------------------------------------------------------

    // READ_BIT - reads a bit from the one-wire bus. The delay
    // required for a read is 15us, so the DELAY routine won't work.
    // We put our own delay function in this routine in the form of a
    // for() loop.
    unsigned char read_bit(void)
    {
    unsigned char presence;
    sbi(DDRD,3); //DQ = 0; // pull DQ low to start timeslot

    cbi(DDRD,3);//DQ = 1; // then return high
    delay(10); // delay 20 us from start of timeslot
    if(bit_is_clear(PIND,3)) presence=0;
    if(bit_is_set(PIND,3)) presence=1;
    return(presence); // return value of DQ line
    }
    ///---------------------------------------------------------

    void write_bit(char bitval) //WRITE_BIT - writes a bit to the one-wire bus, passed in bitval.
    {
    sbi(DDRD,3); //DQ = 0; // pull DQ low to start timeslot
    if(bitval==1) cbi(DDRD,3); //DQ =1; // return DQ high if write 1
    delay(52); // hold value for remainder of timeslot - delay 104us
    cbi(DDRD,3);//DQ = 1;
    }

    ///---------------------------------------------------------

    unsigned char read_byte(void) // READ_BYTE - reads a byte from the one-wire bus
    {
    unsigned char i;
    unsigned char value = 0;
    for (i=0;i<8;i++)
    {
    if(read_bit()) value|=0x01<<i; // reads byte in, one byte at a time and then
    delay(61); // shifts it left wait for rest of timeslot
    }
    return(value);
    }

    ///---------------------------------------------------------

    void write_byte(char val) // WRITE_BYTE - writes a byte to the one-wire bus.
    {
    unsigned char i;
    unsigned char temp;
    for (i=0; i<8; i++) // writes byte, one bit at a time
    {
    temp = val>>i; // shifts val right 'i' spaces
    temp &= 0x01; // copy that bit to temp
    write_bit(temp); // write bit in temp into
    }
    delay(52);
    }

    ///---------------------------------------------------------

    void Read_Temperature(void)
    {
    char tmp[10];
    char temp_lsbyte,temp_msbyte;
    int k;
    cli(); //wyłączenie przerwań
    if(!ow_reset())
    {
    write_byte(0xCC); //Skip ROM
    write_byte(0x44); // Start Conversion
    delay(52);
    ow_reset();
    write_byte(0xCC); // Skip ROM
    write_byte(0xBE); // Read Scratch Pad

    for (k=0;k<9;k++){tmp[k]=read_byte();}

    temp_msbyte = tmp[1]; // Sign byte + lsbit
    temp_lsbyte = tmp[0]; // Temp data plus lsb
    if (temp_msbyte <= 0x80){temp_lsbyte = (temp_lsbyte/2);} // shift to tmp whole degree
    temp_msbyte = temp_msbyte & 0x80; // mask all but the sign bit
    if (temp_msbyte >= 0x80) {temp_lsbyte = (~temp_lsbyte)+1;} // twos complement
    if (temp_msbyte >= 0x80) {temp_lsbyte = (temp_lsbyte/2);}// shift to tmp whole degree
    if (temp_msbyte >= 0x80) {temp_lsbyte = ((-1)*temp_lsbyte);} // add sign bit

    if(temperature!=temp_lsbyte) {temperature=temp_lsbyte; zmtemp=1;}
    }

    sei(); //włączenie przerwań
    }

    Dodano po 4 [minuty]:

    aha, oto zmienna globalona w której przechowuje wartosć temperatury:

    volatile signed char temperature=0; //aktualna temperatura
    i zmienna globalna która mówi czy temperatura sie zmieniła:
    char zmtemp; //zmienna mówiące o zmianie temperatury

    jesli zmienna ta ma wartość jeden (co oznacza zmianę temperatury w stosunku do ostatniego pomiaru to w petli main :

    if(zmtemp==1) //sprawdzenie czy temperatura uległa zmianie od ostatniego pomiaru
    {
    printf("%d",temperature);
    zmtemp--;
    pisztekst("oC");
    }
  • #4 2536465
    elektryk
    Poziom 42  
    Posty: 11029
    Pomógł: 439
    Ocena: 241
    Skąd masz taką zakręconą procedure? DS1820 zwraca wynik w postaci liczby U2, wystarczy ją zapisać do zmiennej signed i już masz wszystko gotowe.
  • #5 2536645
    pgp
    Poziom 19  
    Posty: 412
    Pomógł: 6
    Ocena: 17
    No z noty katalogowej dallasa. Możesz mi z grubsza napisać ta procedurke ?
  • #6 2537001
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    pgp napisał:
    No z noty katalogowej dallasa. Możesz mi z grubsza napisać ta procedurke ?

    Może warto czasem użyć szukaj ?.

    Piotrek

    PS
    Wprawdzie dotyczy DS18B20 , ale możesz dostosować do swojego ;)
  • #7 2537237
    pgp
    Poziom 19  
    Posty: 412
    Pomógł: 6
    Ocena: 17
    Zmodyfikowałem trochę procedurę odczytu. Rezygnuję z temperatur ujemnych dla uproszczenia - zatem odczytuję tylko pierwszy bajt. no i zrobiłem sobie funkcję która wyrzuca ten bit na LCD. Okazuje sie ze raz na jakiś czas występują przekłamania pojedynczych bitów... wtedy temperatura wzrasta o 64, 32 , 16, 8 itd... stopni. Myślicie ze to wina że urządzenie jest na płytce uniwerslanej, a nóżki czujnika sa nieprzciete - takie długie jak oryginalne - to prototyp. Może gdybym skrócił nóżki, zrobił jakąś obudowe metalową (ekran) to nie byłoby tych przekłamań... Stworzyłem funkcję która odrzuca nagłe wzrosty/malenia temperatury o więcej niż 8 stopni. Jeśli natomiast stan taki występuje przez 4 pomiary z rzedu (a pomiary wykonuję co sekundę) to przyjmuję tą "dziwnie większą/mniejsza wartość" jako prawdziwą.... Póki co sprawuje się nieźle... No czasami są przekłamania o 4 stopnie... choc urządzenie ma służyc do sterownika ogrzewania wiec chyba zmniejsze próg z 8 do 4 stopni,bo wydaje mi się ze nie jest możliwe żeby w ciągu 1 sek. temp. zmieniła się o 4 stopnie... A oto funkcja :

    void Read_Temperature(unsigned char x)
    {
    char tmp,temp_lsbyte,licz;
    int k;
    cli(); //wyłączenie przerwań
    if(!ow_reset())// czy czujnik odpowiedział na reset?
    {

    write_byte(0xCC); //Skip ROM
    write_byte(0x44); // Start Conversion
    delay(52);
    ow_reset();
    write_byte(0xCC); // Skip ROM
    write_byte(0xBE); // Read Scratch Pad

    tmp=read_byte();
    temp_lsbyte = tmp; // Temp data plus lsb
    temp_lsbyte = (temp_lsbyte/2); // shift to tmp whole degree


    if(temperature!=temp_lsbyte) //sprawdzenie czy nastapiła zmiana od ostatniego pomiaru
    {
    if( ((temp_lsbyte-temperature)<x)||((temperature-temp_lsbyte)<x) ) {temperature=temp_lsbyte; zmtemp=1;licz++; }//jesli zmiana jest wieksza/mniejsza od x stopni - odrzucamy ją
    if(licz==4) {temperature=temp_lsbyte; licz=0; } //jeśli cztery razy pod rząd odczytamy temperaturę dziwnie wyzsza/nizsza
    }
    else {licz=0;}


    }

    sei(); //włączenie przerwań
    }
  • #8 2537311
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Nie napisałeś z jaką częstotliwością taktujesz uC , ale jeśli jest to >1MHz to...
    
    unsigned char read_bit(void)
    {
    unsigned char presence;
    sbi(DDRD,3); //DQ = 0; // pull DQ low to start timeslot
    //****może w tym miejscu dodać delay(1) ?????
    cbi(DDRD,3);//DQ = 1; // then return high
    delay(10); // delay 20 us from start of timeslot
    if(bit_is_clear(PIND,3)) presence=0;
    if(bit_is_set(PIND,3)) presence=1;
    return(presence); // return value of DQ line
    } 
    

    ... może dodaj zwłokę pomiędzy sbi i cbi , ponieważ przy zapoczątkowaniu timeslot-u , stan niski na DQ powinien trwać >1uS , a przy taktowaniu uC np. 8MHz raczej tak nie jest :(
    Spróbować warto ;)

    Piotrek

    PS
    Długość nóżek DS-a nie ma tu nic do rzeczy , ale sposób jego zasilania - jak najbardziej ma.
  • #9 2555973
    pgp
    Poziom 19  
    Posty: 412
    Pomógł: 6
    Ocena: 17
    Zrobiłem tak jak mówisz - dodałem tergo delay'a , ale to powoduje błąd - temperatura jest wtedy 127 st C....

Podsumowanie tematu

✨ Problem dotyczy błędnych odczytów temperatury z czujnika DS1820 przy nagłych zmianach temperatury, np. zbliżeniu bardzo zimnego obiektu z zamrażarki, co skutkuje nierealistycznymi wartościami sięgającymi 140°C. Dyskusja wskazuje, że przyczyną mogą być błędy w procedurze konwersji danych z czujnika, szczególnie przy odczytach temperatur ujemnych, oraz zakłócenia sygnału wynikające z prototypowej konstrukcji (długie nóżki czujnika, brak ekranowania). Proponowane rozwiązania obejmują uproszczenie procedury odczytu do obsługi tylko temperatur dodatnich, implementację filtrów eliminujących nagłe skoki temperatury powyżej określonego progu (np. 8 stopni), a także poprawę stabilności sygnału poprzez skrócenie nóżek i zastosowanie obudowy ekranowanej. Wskazano również na konieczność odpowiedniego taktowania mikrokontrolera i dodania opóźnień w procedurze odczytu bitów, aby zapewnić poprawne odczyty. Mimo modyfikacji, pojawiają się sporadyczne przekłamania, co sugeruje wpływ wilgoci lub warunków środowiskowych na pomiary.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA