Jump to content
ELFORUM - Forumul Electronistilor
Sign in to follow this  
nickrvl

ADC Attiny24, discutii.

Recommended Posts

De cind fac voltmetre cu Mc-uri Atmega (PIC nu am incercat), Atmega8, Attiny13, Attiny24,26, am observat decalaje intre afisarea valorilor comparativ cu un multimetru (de fapt mai multe ca sa ma verific), aceste decalaje nu am reusit sa le rectific decit din soft.

In aceasta discutie vorbesc strict doar de Attiny24 deoarece am avut un pic de timp si am luat din nou la purecat "problema", folosesc o placa de test la care am legat LCD-ul, divizorul rezistiv si in ultima instanta un generator de tensiune constanta (4V din alimentarea Mc-uli, 5V) cu un TL431, acesta din urma l-am anexat pentru a proba si cu referinta externa a ADC-ului astfel am o referinta extrem de stabila de 4V dar cum am spus aceasta diferenta persista.

In definitiv este vorba de o difernta de 0,2V la 23,9V (doar atit am incercat), adica ii dau sa masoare 23,9V, din semireglabili il compar/egalizez cu un multimetru iar cind scad aproape de minim, la 0.5V, voltmetru meu indica 0,3V, decalajul se produce progresiv, incepe de pe la 15V cu un decalaj de 0,1V iar pe la 7V deja are 0,2V, asta inseamna aproximativ 0.8V pe intreaga scala (0-100V), nu am verificat decit pina la 23,9V.

Atasez mici insemnari facute in timpul incercarilor.

De tinut cont ADC.pdf

 

---Poate stie cineva precis de ce apare acest decalaj.

 

Schema folosita nu este relevanta, de mentionat ca am folosit intrarea ADC 3.

 

Softul nu e mare lucru, este scris in Bascom, il atasez si pe acesta:

$regfile = "ATtiny24.dat"Config Lcd = 16 * 2Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Portb.0 , Rs = Portb.1Cursor OffClsConfig Adc = Single , Prescaler = Auto , Reference = Aref   'Avcc   'Internal  '_1.1Start AdcDim Aratavolt As String * 3Dim X As WordDim V As WordDoV = Getadc(3)Aratavolt = Str(v)If V > 99 ThenAratavolt = Format(aratavolt , "00.0")Locate 2 , 1Lcd Aratavolt ; "V  "ElseAratavolt = Format(aratavolt , "0.0")Locate 2 , 1Lcd Aratavolt ; "V  "End IfLocate 1 , 1Lcd "ADC = " ; Getadc(3) ; "  "Wait 1Loop

Share this post


Link to post
Share on other sites

ADC-ul are rezolutie 10bit deci 1024 de valori , 0 pentru 0V si 1023 pentru Vin 4V maxim cat e referinta , deci ca sa fie chiar exact exista o formula de baza pe care orice program o foloseste ADC = (Vin/VAREF) x 1024 . De fapt formula asta apare clar in pdf-ul atasat de tine dar n-ai tinut cont in program . Daca ar fi avut ADC-ul 1000 de valori era valabil asa simplu cum ai facut tu ... de aici neliniaritatea

Share this post


Link to post
Share on other sites

ADC-ul are rezolutie 10bit deci 1024 de valori , 0 pentru 0V si 1023 pentru Vin 4V maxim cat e referinta , deci ca sa fie chiar exact exista o formula de baza pe care orice program o foloseste ADC = (Vin/VAREF) x 1024 . De fapt formula asta apare clar in pdf-ul atasat de tine dar n-ai tinut cont in program . Daca ar fi avut ADC-ul 1000 de valori era valabil asa simplu cum ai facut tu ... de aici neliniaritatea

Momentan tot nu inteleg cum anume trebuie implementata formula, eu am folosit-o doar pentru stabilirea Vin la pini fata de 100V (maxim de masurat) pentru a calcula divizorul rezistiv, este evident ca trebuie folosita dar nu-mi vine acum....Este posibil ca variabilele mele sa nu fie capabile sa calculeze cifra dupa punctul zecimal? pentru ca totusi ar trebuii sa pot aplica formula dar nu rezulta ce si cit trebuie.

Share this post


Link to post
Share on other sites

Momentan tot nu inteleg cum anume trebuie implementata formula, eu am folosit-o doar pentru stabilirea Vin la pini fata de 100V (maxim de masurat) pentru a calcula divizorul rezistiv, este evident ca trebuie folosita dar nu-mi vine acum....Este posibil ca variabilele mele sa nu fie capabile sa calculeze cifra dupa punctul zecimal? pentru ca totusi ar trebuii sa pot aplica formula dar nu rezulta ce si cit trebuie.

Ar trebui sa implementezi asta in BASCOM:
Dim volt as singleV=Getadc(3)volt=1.1*1024 ; rezultatul va fi in volti   1.1 tensiunea de referinta selectata de tinevolt=volt/V
si mai departe iti formatezi modul de afisare.Ca sa folosesti divizorul de tensiune pe care il doresti vei tine cont de tensiunea maxima de intrare adecvata tensiunii de referinta folosite (in cazul tau 1.1V) si de un curent ales prin divizor (de exemplu 100uA) si iti calculezi rezistentele astfel incat la 100V la intrare sa ai 1.1V la pinul uC.

Share this post


Link to post
Share on other sites

Formula ta e aşa:

 

U= ADC*Vref*K/1023

Împărţit la 1023. Nu 1024, nu 1000. ADC-ul nu măsoară decît între 0 şi 1023, adică 0x0000...0x03FF.

 

U e ce trebuie să afişezi pe LCD, în milivolţi. ADC e valoarea pe care o citeşti din registru, Vref e tensiunea de referinţă, exprimată în volţi, iar K reprezintă raportul divizorului de tensiune.

 

Ca tipuri de variabile:

U: float

ADC: unsigned char

Vref: float

K: float

Share this post


Link to post
Share on other sites

Zice altfel, dar zice incorect. Presupunînd o referinţă de 5V, cînd ADC-ul ia valoarea maximă, dacă faci calculul vei vedea că iese aşa:Vin = 1023*5000/1024 = 4995.E corect? Nu.

Share this post


Link to post
Share on other sites

Zice altfel, dar zice incorect. Presupunînd o referinţă de 5V, cînd ADC-ul ia valoarea maximă, dacă faci calculul vei vedea că iese aşa:

Vin = 1023*5000/1024 = 4995.

 

E corect? Nu.

Se pare ca este totusi corect, daca tinem cont de afirmatia producatorului respectiv:

"0x000 represents ground, and 0x3FF represents the selected reference voltage minus one LSB".

Ca cineva vrea sa forteze afisarea unei tensiuni de 5V pentru 5V aplicati, da, atunci formula care include 1023 i-ar satisface cerinta, insa valoarea fisata ar fi mai mare cu circa 5mV (0.00488V), deoarece convertorul ADC va produce un rezultat egal cu 2^n-1, deci doar 1023 valori.

Mai clar: 0V*1/1024=0V (minimul aplicat la intrarea convertorului) , 5*1023 (adica2^n-1)/1024=4.995V (maximul aplicat la intrarea convertorului) si uite asa de la 0 la 1023 sunt 1024 de valori, altfel ai "fura" un bit din rezultatul conversiei.

Am mari dubii ca atat MICROCHIP cat si ATMEL si, probabil, si alti productaori de microcontrollere care includ ADC ar putea fi atat de prost informati incat sa publice in toate foile lor de catalog aceeasi formula de calcul al rezultatului conversiei, sau, cel putin, aceeasi logica de calcul.

Share this post


Link to post
Share on other sites

Dupa masa o sa testez cele de mai sus, referinta momentan o am externa de 4V obtinuta din alimentarea mc-ului dar daca dupa aplicarea acestor calcule si daca ma multumeste o sa trec pe referinta de alimentare AVCC.

Share this post


Link to post
Share on other sites

Se pare ca este totusi corect, daca tinem cont de afirmatia producatorului respectiv:

"0x000 represents ground, and 0x3FF represents the selected reference voltage minus one LSB".

În cazul respectiv, da, numai că nickrvl vrea să vadă 5V pe afişaj cînd aplică 5V pe intrare:

Ca cineva vrea sa forteze afisarea unei tensiuni de 5V pentru 5V aplicati, da, atunci formula care include 1023 i-ar satisface cerinta, insa valoarea fisata ar fi mai mare cu circa 5mV (0.00488V), deoarece convertorul ADC va produce un rezultat egal cu 2^n-1, deci doar 1023 valori

Share this post


Link to post
Share on other sites

În cazul respectiv, da, numai că nickrvl vrea să vadă 5V pe afişaj cînd aplică 5V pe intrare:

 

Degeaba vrea el...

Atunci foloseste oversampling pe 11, 12 ... 16 biti folosindu-se de informatiile din atasament.

Si aici, exemplu practic: http://www.mcselec.com/index.php?option=com_content&task=view&id=325&Itemid=57

atmel oversampling adc.pdf

Share this post


Link to post
Share on other sites

Cred că ştiu de unde provine confuzia.

 

Vreau să măsor între 0-100V.

Am referinţă de 4V şi un ADC pe 10 biţi, adică valori între 0x0000 şi 0x03FF. Aici e problema, pentru că ultima valoare, 0x03FF, NU corespunde valorii de 4V, ci ADCmax = 4V*1023/1024 (referinţa minus un LSB).

 

Divizorul rezistiv trebuie să aibe raportul:

K = 100V/4V * 1024/1023

 

Valoarea e cel puţin tîmpită. Chiar dacă ai pune raportul ăsta, multimetrul tău va măsura cu paşi de 100V/1024=97,65625mV. Ca să obţii paşi de fix 100mV ţi-ar trebui o referinţă de 4,096V (un LM4040, de exemplu). Un LSB ar deveni fix 4mV, iar gama s-ar extinde pînă la 102,3V (sper să nu fi greşit pe undeva).

Share this post


Link to post
Share on other sites

Asa mai merge ratza, ma bucur ca ai inteles de unde vine confuzia. Dar stau si ma intreb: nickrvl, cum ai "varat" programelul ala in Bascom in attiny24 cand depaseste cam cu 7% capacitatea de memorie a lui? Te intreb pentru ca vei avea surprize (fara formatare are cam 89% din memoria Flash a lui attiny24). Sau il folosesti pentru testarea diferitelor parti din program?

Share this post


Link to post
Share on other sites

E interesant că valoarea de top corespunde referinţei minus un LSB. La toate ADC-urile şi DAC-urile cu care am lucrat pînă acum, valoarea de top corespundea fix cu referinţa. De acum înainte o să mă uit mai atent.

Share this post


Link to post
Share on other sites

Chiar si adc-urile externe pe 10 biti de la Microchip au aceeasi logica de formare a rezultatului (vezi MCP3008).

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.