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

[AT90S2313] [C] [WinAVR] Precyzja, rozdzielczośc w DS1820

J_D 31 Sty 2009 20:34 1577 8
REKLAMA
  • #1 6083220
    J_D
    Poziom 10  
    Witam,
    przeglądnąłem prawie wszystkie posty dotyczące DS11820 (oj było ich trochę). Większośc przykładów jest bisana pod BASCOMa a je potrzebuje informacji i przykładowych kodów w C aby podglądnąc i rozwiązac moje problemy.
    O co chodzi.
    1. Temperatura wyświetlana na 4 z 8 wyświetlaczach 7-seg. LED.
    2. Licze CRC i upraszczam sobe wyswietlajac wynik z dokładnościa 0.5C po przecinku.
    3. Obsługa wyświetlaczy znajduje się w przerwaniu od TMER0. Działa bez zarzutu, więc jej nie skopiowałem do posta.

    
    	while(1)
    	{	CRC = 0;
    		DS_Present=reset_1w();
    		if (DS_Present != 0)
    		{
    			temp_sign = 8;
    			temp_h = 8;
    			temp_l = 8;
    			temp_units = 8;
    		}
    		else 
    		{
    			send_1w(0xCC);
    			send_1w(0x44);
    			_delay_ms(750);
    			reset_1w();
    			send_1w(0xCC);
    			send_1w(0xBE); 
    			
    			for (i=0; i<9; i++)
    			{
    				ds_map [i] = get_1w();
    				licz_CRC (ds_map [i], &CRC);
    			}
    			
    			reset_1w();
    
    			if (CRC==0)
    			{
    				T_LSB = ds_map[0]; //temp
    				T_MSB = ds_map[1];
    
    			// wyswietlanie dziesiatek stopnia
    				if ((T_LSB & 0x01) == 0) temp_units = 0;
    				else temp_units = 5;
    
    			// 	Liczenie temperatury
    				if(T_MSB==0)	// plus
    				{
    					temp_sign = 0;
    					T_LSB = T_LSB/2;
    					DisplayValue (T_LSB);
    				}
    		
    				else
    				{
    					temp_sign = 10;
    					T_LSB = (256-T_LSB)/2;
    					temp_h = T_LSB/10;
    					k = temp_h*10;
    					temp_l=T_LSB - k;
    				}
    			}
    		}
    


    Wyswitlanie temp na wyswietlaczach:

    void DisplayValue (unsigned char Value)
    {
    // temp_sign - Display 0 - znak temp.
    // temp_h - Display 1 - dziesiątki temp.
    // temp_l - Display 2 - jednostki temp.
    // temp_units - Display 3 - dziesietne częsci temp.
    
    unsigned char i, j;
    
    	if (Value >= 125)
    	{
    		Value = 125;
    		temp_sign = 1;
    		temp_h = 2,
    		temp_l = 5;
    	}	
    
    	if (Value >= 100 && Value < 125)
    	{
    		temp_sign = abs (Value/100);
    		i = Value - (temp_sign*100);
    		temp_h = i/10;
    		j = temp_h*10;
    		temp_l = i - j;
    	}
    
    	if (Value<100 && Value>9)
    	{
    		//temp_sign = 0;
    		temp_h = abs (Value/10);
    		temp_l = Value - (temp_h*10);
    	}
    
    	if (10 > Value)
    	{
    		temp_l = Value;
    		temp_h = 0;
    		//temp_sign = 0;
    	}
    }


    Generalnie wszystko działa ale chciałbym ulepszenia, które nie daje mi spac.

    A teraz problemy i prosba o pomoc w ich rozwiązaniu:
    1. Jak zwiekszyc precyzję wyświetlania dziesiętnych stopni? Cel 0.1 a nie 0.5

    Co tak naprawde daje w resultacie:
    TEMPERATURE=TEMP_READ-0,25+ (COUNT_PER_C-COUNT_REMAIN)/COUNT_PER_C? Jak będzie wyglądała wartoś TEMPERATURE? Bedzie to np. 225 (22.5)?

    Wg moich obliczen zawsze będzie to dokładnośc do 0.5st.

    2. Mógłby któś zerknąc na funkcję DisplayValue () bo coś podejrzewam ze pow. 100 st nie spelnia ona swojego zadania.

    3. Przejscie na DS18B20 nie wchodzi w rachube bo chce sie pozbyc starych czujnikow :)

    Pozdrawiam
    J_D
  • REKLAMA
  • #2 6083759
    markosik20
    Poziom 33  
    J_D napisał:

    Wg moich obliczen zawsze będzie to dokładnośc do 0.5st.


    Zgadza się bo ten model nie ma większej rozdzielczości :wink:.
  • #3 6083875
    MarcinKawka
    Poziom 12  
    Na oko wygląda OK, ale niezbyt optymalne.
    Jak już opakowałeś tym ifem to abs (Value/100); zawsze zwróci ci +1

    Poprawiona wersja:
    
    if (Value >= 100 && Value < 125) 
       { 
          temp_sign = 1; 
          i = Value - 100; 
          temp_h = i / 10;
          temp_l = i % 10; 
       }
    
  • REKLAMA
  • #4 6083884
    J_D
    Poziom 10  
    Dziekuję markosik20 za odpowiedz.
    Cytat:
    Zgadza się bo ten model nie ma większej rozdzielczości

    Dziwi mnie zatem jak ludzie w swoich postach uzyskuja 0.1 na DS1820 (nie B).

    Jeszcze jeden maly problem. Przy odczycie temp. pow. 60st C (nad swieczka powinno byc troche goraco) czasem dostaje wartosc o wiele nizsza od aktualnej temp (nagle 30) a czasem wartosc jest zupelnie z kosmosu (ujemna). Teraz nie wiem czy zle dziala mi funkcja wyswietlania, czy przekrecaja sie wartosci temp. (stad zmiana znaku).
    Timingi sprawdzalem raczej jest wszystko ok. Jezeli czujnika nie grzeje nad swieczka to wyglada ze dziala całkiem przyzwoicie (-10 - temp. pokojowa).
    Podlączenie lini przez 4k7 do +, linie DQ i GND podlaczone do DSa (+5V dodatkowo na DSie nie gra roli - problem ten sam).

    Czekam niecierpliwie na pomoc.
    Pozdrawiam
    J_D

    Dodano po 24 [minuty]:

    Cytat:
    abs (Value/100); zawsze zwróci ci +1

    Powywalałem abs, ograniczenie do 125st wrzuciłem przed wywołaniem tej funkcji
    				if(T_MSB==0)	// plus
    				{
    					temp_sign = 0;
    					T_LSB = T_LSB/2;
    					if (T_LSB > 125) T_LSB = 125;
    					DisplayValue (T_LSB);
    				}
    


    i teraz wyglada to tak:

    void DisplayValue (unsigned char Value)
    {
    unsigned char i, j;
    
    if (Value >= 100)
       {
          temp_sign = Value/100;
          i = Value - (temp_sign*100);
          temp_h = i/10;
          j = temp_h*10;
          temp_l = i - j; 
       }
    
    	if (Value<100 && Value>9)
    	{
    		temp_sign = 0;
    		temp_h = Value/10;
    		temp_l = Value - (temp_h*10);
    	}
    
    	if (10 > Value)
    	{
    		temp_l = Value;
    		temp_h = 0;
    		//temp_sign = 0;
    	}
    }


    Niestety, nie rozwiązuje to dziwnych wskazan i wahan temp 98, 90, 89, 102, 110... :(

    Ps. Jaka jest temperatura nad świeczką (2cm od płomienia)? Moze poprostu jest czujnikowi zbyt gorąco ?
  • REKLAMA
  • #5 6084120
    MarasK
    Poziom 18  
    spróbuj powoli nagrzewać - np wsadzając opakowane szczelnie do wrzącej wody lub zwiększyć pojemność termiczną. Zawsze możesz zastosować załącz/wyłącz świeczki tzn dawkowanie opalania :)
  • #6 6084213
    J_D
    Poziom 10  
    Kurcze nie wiedzialem ze tak ciezko ogrzac czujnik.
    Probowałem rózne zposoby (na razie bez uzycia wody) drastyczne - bezposrednio w ogien, pod lutownice, mniej drastyczne- stopniowe podpalanie. Bez zmian,
    69.5, 68, c25.5 (znaczek c mowi mi ze temp <0) - tu mnie zgięło.
    Bardzo ciezko dochodze do 100st bo ciagle czujnik jest niestabilny. Sprawdzalem z roznymi czujnikami. Ten sam efekt. :(
    Moze to kod jest zly?
  • #7 6085203
    MarasK
    Poziom 18  
    	return  ((scratchpad[1] << 4) | (scratchpad[0] >> 4));	//obliczanie dla DS18B20
    	return ((scratchpad[0]>>1)&0b01111111); // obliczanie dla DS1820 (nie B!!)
    

    Ja tak zmieniam temperaturę - oczywiście scratchpad to tablica 9 bajtów odczytanych z czujnika.
  • REKLAMA
  • #8 6085841
    J_D
    Poziom 10  
    Witam,
    najprawdopodobniej trafilem na jakąś dziwną serię DSów.
    Pisze na nich jak byk DS1820 i nr. seryjny. Biorę inny tez DS1820 (pozniejsze sample) i kiszka. Temp = 125.5 (0xFF/2).
    Bardzo dziwne...Zerknie ktos na algorytm, moze znowu wina czasow, ale nie sadze.
    Pozdrawiam
  • #9 6088603
    J_D
    Poziom 10  
    Zmieniłem rezystor pull-up na 3kOhm, dodatkowo jak w nocie podlaczylem VDD DSs do GND i problem z flukutacja sie rozwiazal :) Temperatura jest stabilna.
    Temat mozna zamknac. W innym poscie bede ciagnal watek precyzji i temp. ujemnych.

    Dziekuje za pomoc.
    J_D
REKLAMA