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

[AVR][C] - jak skalibrować sobie odczyt z ADC

mirekk36 17 Paź 2009 17:08 4047 4
  • #1 7140167
    mirekk36
    Poziom 42  
    Witam,

    Zabrałem się w końcu za moduł ADC w prockach AVR przy wykorzystaniu C.

    Okazało się, że nie jest to takie skomlikowane ale...

    mam dziwne problemy (hmmm chyba muszę sobie jakoś skalibrować) z odczytem czy może prawidłowym wskazywaniem wartości mierzonego napięcia.

    Prób dokonuję na procku ATtiny26. Poniżej schemat.
    [AVR][C] - jak skalibrować sobie odczyt z ADC

    do procka mam podpięty jeszcze wyświetlacz LCD a w zasadzie PLED - pobiera b.mało prądu i nie korzysta z podświetlenia - więc nie powinien wprowadzać jakichś specjalnych zakłóceń. Całość zmontowana jest na razie na płytce stykowej a zasilanie leci sobie z USBASP i jak mierzę je dwoma multimerami to wynosi ono +4,92V

    Programowo korzystam z wewnętrznego źródła odniesienia 2,56V

    jak widać napięcie podaję mierzę przez dzielnik R1/R2 - rezystory tak dobrałem prawie idealnie jeśli chodzi o wartości. Tylko ten 10K ma tak na prawdę 10,01K

    I teraz mój problem - polega na tym, że za nic w świecie nie wychodzą mi po obliczeniach napięcia dokładnie tak samo jak na dwóch różnych zewnętrznych miernikach, które tak samo wskazują +4,92V. U mnie wychodzi +4,52V

    (problem z tzw "skaczącym" napięciem rozwiązałem sobie poprzez np 100 pomiarów w pętli i obliczanie zwykłej średniej z tych 100 pomiarów. Więc wyświetlane napięcie jest w zasadzie stabilne - ale średnio o kilka mV niższe niż te które widać gdy mierzę miernikiem na dzielniku. Oczywiście dochodzi tu jeszcze jakaś nieliniowość bo gdy napięcie ustawię sobie na wejściu +1,02V i widzę je na LCD - to mierniki pokazują +1,17V

    Generalnie docelowo chciałem sobie zrobić w miarę dokładny Woltomierz w zakresie 0 - 32V - stąd taki dzielnik

    no ale to odczytywane napięcie jest zwykle niższe. Używam preskalera 128 - a jak dam najmniejszy = 2 - to odczytywane i przeliczane napięcie jest jeszcze ciut niższe :(

    a programowo próbuję robić to mniej więcej tak:

    		
    #define idmax 100
                               w=0;
                               // w pętli robione jest 100 pomiarów
    		for(i=0;i<idmax;i++)
    		{
    			a = a2dConvert10bit(2);
    			w += a;
    			_delay_ms(3);
    		}
     
                              // tu obliczana jest średnia (w/idmax)
                              // wynik mnożony jest przez 0,0025 - tylko razy 10tys
                              // i jeszcze wynik mnożony jest przez współczynnik dzielnika rezystorowego
    		h = (w/idmax)*25*13;
    
    		v1 = (h/10000UL);         // tu mam wynik przed przecinkiem
    		v2 = (h/1000UL)%10UL; // tu mam pierwszą liczbę po przecinku
    		v3 = (h/10UL)%10UL;    // tu mam drugą liczbę po przecinku
                  // te dziwne obliczenia powyżej są po to żeby nie korzystać z liczb typu float
    
    


    może ktoś ma jakieś spostrzeżenia gdzie robię błąd albo co powinienem jeszcze zrobić? poprawić itp ?

    za wszystkie sugestie z góry dziękuję

    Dodano po 3 [minuty]:

    dodam tylko, że próbowałem sobie dodawać jakąś stałą wartość do zmiennej w od razu po wykonaniu pętli - tak aby "sztucznie" otrzymać wartość +4,92V (czyli taką jak pokazują mierniki sprzętowe) - ale jak zmniejszam napięcie np do 1V - to oczywiście nieliniowość jakaś tam powoduje że i tak to się rozjeżdża :(
  • Pomocny post
    #2 7140308
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Ja myślę, że problemem może być kiepska rezystancja wewnętrzna twojego mierzonego źródła napięcia (bo masz je przez rezystor 120k), choć tą powinien poprawiać kondensator. Spróbuj dodać przed ADC, a za dzielnikiem wtórnik napięciowy na wzmacniaczu operacyjnym. Zasadniczo podczas próbkowania napięcia do przetwornika wpływa całkiem spory impuls prądu i nie da się tego zauważyć miernikiem raczej...

    Zwiększ czas próbkowania, to powinno pomóc, ale tylko trochę <: (jeśli tu jest problem)

    4\/3!!
  • Pomocny post
    #3 7140369
    Konto nie istnieje
    Poziom 1  
  • #4 7140544
    mirekk36
    Poziom 42  
    Bardzo dziękuję za sugestie - myślę, że skoro dobrałem bardzo idealne rezystory to w takim razie tak jak pisał atom1477 na pewno pozostawała kwestia poziomu wewn. napięcia odniesienia - być może jest niższe niż 2,56 lub nieco wyższe - też to widziałem w PDF'ie - tylko jak to sobie skalibrować bo widziałem że niektórzy to jakoś robią i radzą sobie bez WO i tym podobnych rzeczy

    UDAŁO się w końcu - i doszedłem już jak sobie to skalibrować IDEALNIE ;) . Okazało się, że tak jak pisałem wcześniej dodawanie jakiejś stałej wartości przy jakimś powiedzmy średnim poziomie napięcia i tak powoduje później spore odchylenia przy większych i mniejszych napięciach.

    Jednak wystarczyło zrobić tak:

    #define idmax 100 
                               w=0; 
                               // w pętli robione jest 100 pomiarów 
          for(i=0;i<idmax;i++) 
          { 
             a = a2dConvert10bit(2); 
             w += a; 
             _delay_ms(3); 
          } 
      
                              // tu obliczana jest średnia (w/idmax) 
                              // wynik mnożony jest przez 0,0025 - tylko razy 10tys 
                              // i jeszcze wynik mnożony jest przez współczynnik dzielnika rezystorowego 
              // ale właśnie tym współczynnikiem trza sobie skalibrować - tyle że trzeba by
              // użyć np wartości np: 13,95 - czyli liczby zmiennoprzecinkowej
              // dlatego mnożę ten współczynnik jeszcze przez 100
          h = (w/idmax)*25*1395; 
    
         // a później dzielę przez większą liczbę 
    
          v1 = (h/1000000UL);         // tu mam wynik przed przecinkiem 
          v2 = (h/100000UL)%10UL; // tu mam pierwszą liczbę po przecinku 
          v3 = (h/1000UL)%10UL;    // tu mam drugą liczbę po przecinku 
                  // te dziwne obliczenia powyżej są po to żeby nie korzystać z liczb typu float 


    w komentarzach opisałem co zrobiłem - pozwoliło to IDEALNIE skalibrować procka (oczywiście zdaję sobie sprawę jeszcze z tego, że może to się nadal rozjeżdżać przy jakichś sporych zmianach temperatury otoczenia)

    teraz jednak wartości napięcia mojego woltomierza na ATtiny26 - z tak prostym układem wejściowym (zwykły dzielnik) - idealnie zgadzają się w całym zakresie pomiarowym z wartościami mierzonymi przez dwa różne zewnętrzne multimery . (czasem tylko na drugim miejscu po przecinku występuje różnica ale max 1 - a o tyle to potrafią się także różnić wyniki na obydwu multimerach) więc jest super!!! ;)

    Dodano po 4 [minuty]:

    oooo ale jednak okazało się, że temperaturą to głowy mogę sobie w ogóle nie zawracać - zrobiłem ciekawy eksperymencik.

    Oziębiłem do -22stC procka za pomocą sprężonego powietrza - tzn nakapałem na nigo ten płyn aż się zmrozil i cały oszronił na maxa ;) a wcześniej gdy testowałem tak DS-y to temperatura dochodziła w takim przypadku do -22st

    później podgrzałem go suszarą do włosów

    i w trakcie tych "stress-testów" cały czas mierzył napięcie - i wiecie co?

    napięcie prawie w ogóle się nie zmieniało - tylko w skrajnych warunkach czasem potrafiło się na chwileczkę zmienić czyli opaść lub się zwiększyć ale o kilkanaście mV - więc - mierniczek napięcia na ATtiny wyszedł extra!
  • #5 7140582
    Konto nie istnieje
    Poziom 1  
REKLAMA