ADC waarden niet constant

Anoniem

Ik heb een projectje gestart om iets met een motorfader te doen. Op het moment loop ik tegen het probleem aan dat de waarden welke ik met de interne ADC van een PIC18F8722 niet echt constant zijn.

Ik lees op de loper van de fader een spanning tussen de 0 en 5v uit. Tussen de loper en ground heb ik een 100nF condensator gezet.

Het eerste probleem waar ik tegenaan loop is het bereik wat ik kan inlezen. Bij 4.6V heb ik de maximale digitale waarde al bereikt en ik krijg de digitale waarde nooit 0. Dit heeft waarschijnlijk te maken met de zeners die intern bij de ADC van de PIC zitten. Ik heb gemerkt dat ik dit kan oplossen door de Vref spanningen anders in te stellen. Door Vref- iets boven 0V en Vref+ iets onder 5V te leggen wordt het bereik van de digitale waarde van 0 tot maximaal. Nu komt het: Ik wil eigelijk geen gebruik maken 'aparte' Vref spanningen. Het is uiteindelijk de bedoeling dat het gaat draaien op een PIC welke geen mogelijkheid heeft om de Vref apart in te stellen. Ik ben totaal niet geweldig met analoge elektronica, vandaar de vraag of hier iemand een oplossing voor heeft :).

Het volgende punt is de waarde zelf. Van de 10 bits gebruik ik er maar 8. De analoge waarde schommelt niet veel (rond de 10mV) maar blijkbaar toch te veel om een constante digitale waarde op te leveren. Ik heb geprobeerd om met een circulaire buffer samples op te slaan en daar het gemiddelde van te nemen zonder de hoogste en laagste waarde mee te rekenen. Met 10 samples in de buffer rammelt de berekende waarde nog steeds met 1 op en neer. Berekening over 100 samples werkt, de digitale waarde rammelt niet. Echter bij het bewegen van de fader veranderd de digitale waarde niet met de zelfde snelheid mee omdat eerst de buffer compleet moet worden herschreven.

Het doel is dat de fader een constante waarde tussen 0 en 255 opleverd, zonder dat deze op en neer rammelt wanneer de fader stil staat. Heeft hier een goede oplossing voor (digitaal of analoog)?

- Meet je dezelfde spanningswisseling met een scope oid? Dan ligt het aan je hardware (en eventueel software).
- Gebruik je delays? Je moet wachten totdat je ADC klaar is met converten. Post je code eens.

Ik heb dit bij een AVR al ondervonden. Deze heeft een AVCC welke ik was vergeten aan te sluiten . Misschien heeft een PIC ook zoiets ?
Grtz

Anoniem

Op 24 februari 2009 21:25:02 schreef JuuL:
- Meet je dezelfde spanningswisseling met een scope oid? Dan ligt het aan je hardware (en eventueel software).
- Gebruik je delays? Je moet wachten totdat je ADC klaar is met converten. Post je code eens.

Code posten is op het moment lastig aangezien ik in Oostenrijk zit en de code op mn pc thuis staat ;). Ik kon het niet laten rusten vandaar dat ik het nu al post :P.

Anyway met het inlezen van de ADC wacht ik totdat deze klaar is:

code:


ADCON0.GO=1;
while(ADCON0.GO);
//Rest van de code

Het zou dus best kunnen dat het aan de hardware-kant al fout gaat. Ik realiseer me ook net dat 10mV speling opzich al best veel is: 5V / 255 = 19mV. Hoe kan ik dit evt. stabieler krijgen? Of evt digitaal oplossen?

Op 24 februari 2009 21:41:07 schreef The Dutchman:
Ik heb dit bij een AVR al ondervonden. Deze heeft een AVCC welke ik was vergeten aan te sluiten . Misschien heeft een PIC ook zoiets ?
Grtz

Dat is in feitte de Vref. Deze kan via een aparte input (AVdd + AVSS) of via de Vref+ en Vref-. In mn print heb ik destijds de AVdd + AVss aan de voedingsspanning en ground gehangen (5V geschakelde voeding). Op de Vref+ en Vref- heb ik nu via een spanningsdeler wat andere waarden gezet (komt ook van dezelfde 5V voeding). Dit vanwege het 1'e probleem wat ik in de startpost heb beschreven.

[Bericht gewijzigd door Anoniem op dinsdag 24 februari 2009 22:18:12 (28%)

Henry S.

Moderator

Dat moet zonder referenties en andere maatregelen prima lukken.

-Voeding van de uC wel 5V? Dit is standaard je referentie.
-Ingang van de ADC niet te hoog afgesloten? 10k max maar blijf liever rond de 2k7 mbv een buffer opamp.
-Hou je rekening met links of rechts uitlijnen van de ADC?
-ADC krijgt tijd om te herstellen?
-ADC timing correct?
-Voeding van fader stabiel?

Dit mag een digit varieeren, meer niet.

Deze post is niet door ChatGPT gegenereerd. De 2019 CO labvoeding.
Anoniem

Voeding uC is 5V. Fader is 10K, loper hangt rechtstreeks aan de ADC ingang. Voeding van de fader is de zelfde 5V. Hier zou ik misschien iets mee moeten proberen, aangezien dit een geschakelde voeding is.

Wat bedoel je met 'links of rechts uitlijnen'?

ADC krijgt voldoende tijd om te herstellen lijkt me. Na het inlezen wordt de waarde naar een LCD weggeschreven met wat int to string conversie's ertussen.

[Bericht gewijzigd door Henry S. op dinsdag 24 februari 2009 22:41:31 (39%)

Henry S.

Moderator

Op 24 februari 2009 22:33:57 schreef M14:
Voeding van de fader is de zelfde 5V. Hier zou ik misschien iets mee moeten proberen, aangezien dit een geschakelde voeding is.

Zorg voor een schone voeding, en ik zet nu helemaal een vraagteken bij 5V.

Wat bedoel je met 'links of rechts uitlijnen'?

Zie datasheet, left/right allignment

BTW: Netter of niet quoten, anders beantwoorden.

Deze post is niet door ChatGPT gegenereerd. De 2019 CO labvoeding.
Arco

Special Member

Fader is 10K

Datasheet adviseert max. 2K5...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Als je een conversie doet, is dan ook echt alleen het ADC bezig. Of gebeuren er tegelijkertijd ook nog vanallerlei andere zaken.
Je kunt de processor in slaap mode zetten tijdens een adc-conversie. Iets van idle-adc oid. Kijk maar eens in de datasheets bij sleepmodes. Zeker een aanrader.

Ik heb er iig al eens profijt van gehad.

En verder is een idd een schone voeding belangrijk. Heb je de aanwijzingen uit de datasheet opgevolgd? GOED ontkoppeld, smoorspoeltje tussen VCC en AVCC, het is niet voor niets dat de ADC een eigen voedingspin cq eigen voeding heeft.

edit: ik zie dat je een geschakelde voeding gebruikt. Heb je een scoop zodat je de rimpel van je voeding kunt meten? In de datasheet staat vast wel ergens wat de max rimpel op je voeding mag zijn. Ik denk dat de combinatie van factoren de storing opleverd. Geen schone voeding, ontkoppeling.

|:( :( Ik zie nu dat het om een PIC-ding gaat, dacht dat het om een AVR ging. stom, stom totaal overheen gelezen. Neemt natuurlijk niet weg dat de voeding erg belangrijk is. Het beste kun je nu eerst die schakelende voeding het raam uitknikkeren en een linieare voeding nemen.

Maak me niet gek, ik ben al gek.
Arco

Special Member

Pic of Avr; een geschakelde voeding is niet geschikt als referentiespanning voor een AD converter. Zoals reeds gezegd, een RF spoeltje ertussen (varkensneusje o.i.d.) en een condensator.
Dat is trouwens zelfs met een lineaire voeding aan te raden...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Henry S.

Moderator

http://www.winpicprog.co.uk/pic_tutorial_analogue_board.htm

Alleen wordt hier omslachtig gedaan omdat de verkeerde opamp gebruikt wordt. CA3130 enkelzijdig voeden en weg met de 7660.

Deze post is niet door ChatGPT gegenereerd. De 2019 CO labvoeding.
Anoniem

Op 24 februari 2009 22:43:26 schreef Henry S.:

Zie datasheet, left/right allignment

Deze is '0'. Door alleen ADRESH uit te lezen heb ik als het goed is de 8 meest relevante bits.

Op 24 februari 2009 22:54:16 schreef Arco:
[...]
Datasheet adviseert max. 2K5...

Lezen blijkt weer eens een vak apart te zijn :), had het nog niet in de datasheet gezien. Henry had het over een buffer-opamp, hoe moet of kan dit er concreet uit zien.

Op 24 februari 2009 22:56:30 schreef WilToyo:
Het beste kun je nu eerst die schakelende voeding het raam uitknikkeren en een linieare voeding nemen.

Ik begrijp dat een stabiele voeding belangrijk is alleen wil ik eigelijk niet van die geschakelde voeding afstappen. Is op het moment ook vrij moeilijk omdat dat ding nu eenmaal op de print zit.

Zijn er andere manieren om die voedingsspanning stabieler te krijgen, bijv. door spoelen / condensators te gebruiken?

-----------------------
Hmz, helft is al beantwoord tijdens het typen van deze post :). In ieder geval allen bedankt, ik ga weer eens prutsen zodra ik thuis ben.

Op 24 februari 2009 23:22:49 schreef M14:Ik begrijp dat een stabiele voeding belangrijk is alleen wil ik eigelijk niet van die geschakelde voeding afstappen. Is op het moment ook vrij moeilijk omdat dat ding nu eenmaal op de print zit.

Zijn er andere manieren om die voedingsspanning stabieler te krijgen, bijv. door spoelen / condensators te gebruiken?

Kan, maar of je het helemaal schoon gaat krijgen? Blijven natuurlijk wel lapmiddelen. Goed ontkoppelen is de boodschap. Begin maar vast met een spoeltje (varkensneusje zoals Arco zei) van tussen de 10uH en 100uH. Liefst 100uH. Verder een C-tje tussen de referentie en GND van 100nF en tussen AVCC en GND.

Maak me niet gek, ik ben al gek.

Wat ook helpt, naast alle HW tips:

- software gemiddelde berekening (maakt het geheel wel trager, maar met een 'moving average' heb je alleen een opstart periode).
- Uitschieters weggooien. Je hebt een pool met gemeten waarden. Gooi de uitschieters weg en bepaal dan eventueel het gemiddelde.
- Soms (hangt af van type uC, lees datasheet), moet je nog een bepaalde tijd wachten na het selecteren van een ingang, voordat GO kan wordt gezet. (tijd heeft de Track and Hold nodig om te stabiliseren). Volgens mij gaat dit bij de nieuwere PIC's automatisch (??).

Je meetwaarde zal een stuk rustiger zijn.

(Ikzelf heb eigenlijk nooit meer dan jitter om één bit. In gebruik altijd 'gewoon' de +5V voeding als referentie voor de ADC.)

- Wel altijd de bandbreedte van je ingang zo laag mogelijkhouden. Ga je iets meter met een reactie tijd van een paar seconden, plaats dan een filter voor de ingang met de RC tijd van 10Hz ofzo. Doet ook wonderen.

- Als je ingangssignaal wat hoogfrequentere ruisbevat, dan helpt een 100nF condensator direct bij de PIC ook goed.

FullPower

De grootste moeilijkheden liggen daar waar we ze niet zoeken. [Goethe]
Anoniem

Nu ik weer terug ben heb ik weer het een en ander uitgeprobeerd en ben tot de conclusie gekomen dat een geschakelde voeding voor ADC-metingen geen succes is ;). Ik heb een lineaire 5V op zowel de potmeter als Vref- en Vref+ aangesloten, wat direct een veel beter resultaat gaf.

Ik zit momenteel nog met 1 probleem. De minimale waarde die ik meet is 7 en maximale waarde is 252 op een schaal van 0 tot en met 255. Vref- = 0V en Vref+ = 5V, zelfde voeding als op de fader. De uitgelezen waarden kloppen ook, de spanning op de loper bereikt nooit precies de minimale en maximale waarde. Het is uiteindelijk wel de bedoeling dat de uitgelezen waarde tussen 0 en 255 varieert.

Ik heb dit nu alsvolgt opgelost:

code:


ADC_uit = (ADC_uit - 7) * 1.041;
if(ADC_uit<0)ADC_uit=0;
else if(ADC_uit>255) ADC_uit=255;

ADC_uit is een signed int en bevat het gemiddelde van 10 samples. Van deze waarde haal ik de minimaal gemeten waarde af en vermenigvuldig ik het met 1.041. De if-statements zorgen dat de berekende waarde niet boven 255 of onder 0 komen mocht de ingelezen waarde toch onder 7 of boven 252 zitten.

Opzich werkt het, alleen vraag ik me af of hier betere oplossingen voor bestaan (analoog of digitaal). Is dit misschien op te lossen met een opampschakeling zoals Heenry eerder in dit topic postte? Deze heb ik overigens nog niet gemaakt, de electronica-zaak hier in de buurt heeft op maandag vrij :+.

Henry S.

Moderator

Dit is met die schakeling op te lossen, ?Uref is te trimmen, net als de versterking.

Je zal wel gemerkt hebben dat floats meteen een hele hap geheugen innemen.

Deze post is niet door ChatGPT gegenereerd. De 2019 CO labvoeding.

Op deze manier heb je altijd een zekere afwijking door je berekening. Wat je beter kunt doen is het volgende:
De minimale waarde 7 en alles wat eronder zit gewoon weggooien.

code:


if(ADC_uit <= 7)
ADC_uit = 0;

Werkt beter, code is kleiner, eenvoudiger.

Maak me niet gek, ik ben al gek.
Henry S.

Moderator

Met een nette uC voeding en interne ref heb je ook geen gedonder, netjes 0-1023 in mijn geval.

Maar de buffer is meestal wel nodig ivm met de aard van de ADC.

Deze post is niet door ChatGPT gegenereerd. De 2019 CO labvoeding.

Het kan natuurlijk ook aan de potmeter/fader liggen dat die niet helemaal 0Ω wordt.

Maak me niet gek, ik ben al gek.
Henry S.

Moderator

Is goed mogelijk, dan idd de laagste waarden weggooien.

Deze post is niet door ChatGPT gegenereerd. De 2019 CO labvoeding.
Anoniem

Dan ga ik ergens deze week die opamp schakeling eens proberen :). Gebruik van floats neemt idd meer geheugen in gebruik. Nu opzich nog geen probleem, maar het moet uiteindelijk op een goedkopere uC met minder geheugen gaan draaien (word waarschijnlijk een PIC16F690).

WilToyo, potmeter word ook niet helemaal 0Ω of 10kΩ.

code:


if(ADC_uit <= 7)
ADC_uit = 0;

Dit gaat overigens nooit werken. Dan mis je namelijk de waarden 1 t/m 7 in je bereik ;).

Afwijking is opzich ook niet erg, de fader moet uiteindelijk een waarde tussen 0 en 255 opleveren. Door het op mijn manier te berekenen lukt dat en blijft het volgens mij nog aardig lineair. Het nadeel is alleen het gebruikt van de float. Maargoed, moet eens testen met een opamp er tussen.

Dit gaat overigens nooit werken. Dan mis je namelijk de waarden 1 t/m 7 in je bereik .

Alsof je die gaat missen, die mis je toch al...

Maak me niet gek, ik ben al gek.
Anoniem

Ik lees waardes tussen 7 en 252 in. Wanneer ik

code:


if(ADC_uit <= 7)
ADC_uit = 0;

uitvoer, dan krijg je de volgende reeks wanneer je de fader omhoog schuift:
0,8,9,10,11,..,250,251,252. Schiet niet echt op wanneer de waarde tussen 0 en 255 moet kunnen varieren. Het wordt ooit de bedoeling dat dit als kleine lichttafel gaat werken, vandaar dat het tussen 0 en 255 moet kunnen varieren.

Henry S.

Moderator

Resolutie verhogen, mis je die paar onderste waarden niet.

Deze post is niet door ChatGPT gegenereerd. De 2019 CO labvoeding.
klein is fijn

Moderator

Op 3 maart 2009 00:36:52 schreef WilToyo:
Het kan natuurlijk ook aan de potmeter/fader liggen dat die niet helemaal 0Ω wordt.

Mijn idee, kijk eerst eens of het probleem niet hardwarematig is. Ik heb ook wel eens een halve avond in de software zitten zoeken terwijl er iets fout zat in de hardware.
Gewoon de potmeter even overbruggen met een draadje en Vref hard aan AVcc hangen, of intern op AVcc zetten.