Sida 2 av 3

Re: AD omvandlare

Postat: 27 juli 2011, 21:36:15
av gripner
en liten kod fråga, jag tror jag kommer använda mig av extern AREF som sätts till 2.5V då jag tar för givet att 0V = min värdet ADCn kan spotta ut och 2.5V blir max värdet om jag kör på extern ref.

Adc kanalerna jag vill läsa av är F0 F1 F2 F3

Efter en hel del läsande av exempel koder och lite i databladet så har jag kommit fram till detta

Vid initiering och dummy läsning av ADC första gången för att den inte ska vara skum när man verkligen vill ha värdet
ADMUX|=(0<<REFS1)|(0<<REFS0); //sätter ref V till extern källa.

Sedan när man läser från adc på "riktigt" använder jag
ADMUX=(ADMUX&0xF0)|channel;

channel är en uint_8 variabel med värdet 0,1,2,3 beroende på vilken kanal jag läser

uCn jag använder är at90USB1286

Det fungerar när jag testar, jag läser av 4 kanaler och kan se datan. inte helt säker på att det är rätt dock....
Vad säger ni som vet?

Re: AD omvandlare

Postat: 27 juli 2011, 21:49:14
av jesse
Hur skapar du referensspänningen?
Stämmer de inlästa värdena med de spänningar du har in på de fyra kanalerna i förhållande till Vref?

Värde = 256 * (Vin / Vref) // 8-bitars läsning.

Jag har inte kollat databladet än, men funkar det och data stämmer så är det antagligen riktigt.

Re: AD omvandlare

Postat: 27 juli 2011, 22:02:24
av sodjan
En sak bara. Vid *byte* av ADC kanal så ska man ofta vänta en kort tid för
att ADC ingången ska hinna stabilisera sig. Om nivåerna skiljer mycket och
man inte väntar specificerad tid, så kan man få väldigt felaktiga värden.
Det är normalt en ganska kort tid, några us eller så.

Re: AD omvandlare

Postat: 27 juli 2011, 22:05:05
av jesse
Det har jag redan skrivit i mitt andra inlägg... men det skadar ju inte att det påpekas igen. Det är lätt att missa en detalj i allt informationsflöde.

Kod: Markera allt

ställ in kanal (nr)
vänta (man ska vänta lite så att kanalen hinner stabiliseras innan konvertering startar)
starta konvertering

Re: AD omvandlare

Postat: 27 juli 2011, 22:13:05
av gripner
jag kör med _delay_ms(100); efter varje läsning av adc:n
körde 30ms från början men ville vara säker.

Ref spänning skapas med en simpel späningsdelare, 2 motstånd i serie mellan + och - , mätt så det är 2.5V där oxå för säkerheys skull.

Det är en 10bitars adc. tror jag fick 1024 som största tall, fast hex

Kod: Markera allt

			adc_start_conversion(0);
			_delay_ms(100);
			buf[0] = HEX((adcdata >> 8) & 15);
			buf[1] = HEX((adcdata >> 4) & 15);
			buf[2] = HEX(adcdata & 15);
			buf[3] = '';
			usb_serial_write((unsigned char *)buf, 4);


Re: AD omvandlare

Postat: 27 juli 2011, 22:27:11
av sodjan
> Det har jag redan skrivit i mitt andra inlägg...

Där ser man... :-)
Ja, det är väl, om jag minns rätt, ett par gånger tidigare som
någon har haft just det "probemet" så det gör knappast någon
skada att nämnas igen. Det viktiga är att man följer tiderna enligt
databladet, inte bara "väntar lite" så där hur som helst... :-)

> kommer använda mig av atmel USB1286

Är det en AT90USB1286 ? I så fall, säg gärna det.

Om vi antar att det är den, så ser det ut som att ADC'n själv lägger till
tid för att stabilisera nivån innan S/H kretsen låser spänningen och
konverteringen börjar. Läs ADC kapitlet i detalj...

> jag kör med _delay_ms(100); efter varje läsning av adc:n...

Sannolikt helt onödigt, med tanke på vad databladet säger.

Re: AD omvandlare

Postat: 27 juli 2011, 22:36:27
av gripner
Skrev at90usb1286 föregående post då folk kanske skulle vilja kolla datablad.

käns som det mesta verkar vara rätt och fungera.

Dock tycker jag inte om kanalväljandet. jag skickar ju 0-3 , frågan är om det verkligen är rätt, käns för simpelt!

Re: AD omvandlare

Postat: 27 juli 2011, 22:53:55
av sodjan
Varför är det för simpelt ?

Re: AD omvandlare

Postat: 27 juli 2011, 23:11:35
av labmaster
Make it simple, the functinality is the most important thing to focus on!!!!

Re: AD omvandlare

Postat: 28 juli 2011, 01:04:52
av gripner
Från databladet

Bits 4:0 – MUX4:0: Analog Channel Selection Bits
The value of these bits selects which combination of analog inputs are connected to the ADC.
These bits also select the gain for the differential channels. See Table 25-4 for details. If these
bits are changed during a conversion, the change will not go in effect until this conversion is
complete (ADIF in ADCSRA is set).

Kod: Markera allt


Table 25-4. Input Channel and Gain Selections
MUX4..0   Single Ended Input            Positive Differential Input                   Negative Differential Input        Gain
00000      ADC0
00001      ADC1
00010      ADC2
00011      ADC3              
00100      ADC4
00101      ADC5
00110      ADC6
00111      ADC7

Min kod

Kod: Markera allt

ADMUX|=(0<<REFS1)|(0<<REFS0); //sätter bit REFS1 och 0 till 1 i mux register = AREF avänds
ADMUX=(ADMUX&0xF0)|channel; //  sätter kanal till uint8_t variabel channel som kan vara 0,1,2 eller 3 
Käns som det bör göras anorlunda, dvs sätt MUX bitarna....
De exemplen jag sätt kod från använder adc pinne 0. den behövs ej sättas då alla mux bitarna (5st) är default 00000

Kanske man i mitt fall sätta channel till 0,1,10 eller 11?

Re: AD omvandlare

Postat: 28 juli 2011, 01:51:58
av jesse
I C-programmering är det ingen skillnad om man anger ett tal binärt, decimalt, oktalt eller hexadecimalt. Så om du skriver 0b11 eller 3 spelar ingen roll. Det finns ändå bara ettor och nollor i processorn, så 3 är inget annat än 0b11.

Läs gärna lite grundläggande om talrepresentation, variabler mm i C-programmering, så klarnar det ännu mer. (rekommenderas: Vägen till C - av Ulf Bilting, 2000)

Det var ju praktiskt att kanalerna var numrerade i ordning från 0 till 3 (eller om du vill - 0b00 till 0b11) för då blir det ju enklare att loopa igenom med en indexvariabel, t.ex.

Kod: Markera allt

for (channel=0 ; i<4; i++ ) {
    ADMUX=(ADMUX&0xF0)|channel;
    ... // konvertera
    analog_data[channel] = ADCL;
}
> pinne 0. den behövs ej sättas då alla mux bitarna (5st) är default 00000

Fast av rutin bör man sätta kanal 0 ändå. Antag att du t.ex. senast läste av kanal 3. Då måste du sätta kanal 0 igen, annars kommer du ju att läsa kanal 3 en gång till (Då ADC minns den senast valda kanalen )

Re: AD omvandlare

Postat: 28 juli 2011, 09:24:00
av sodjan
> adc pinne 0. den behövs ej sättas då alla mux bitarna (5st) är default 00000

Gör inte det till en dålig vana !
Det ser ut som att du har slarvat och inte tänkt på det
alls, och det vill du säkert inte.

Re: AD omvandlare

Postat: 28 juli 2011, 10:04:41
av gripner
Skrev att exemplen jag skummat igenom ofta ej sätter MUX bitarna då det är 0 default och de använder adc0.
Jag använder som jag skrivit 0,1,2 och 3 vid anrop av adc konversation.

Hoppas jag får möjlighet i eftermiddag att gå till jobbet och labba lite med kontrollmätningar.
Jobbigt dock med att usb till seriel drivrutinen för atmel uC inte funkar på min 64Bit OS installation :(

Programera, ut med usb kabeln och sätt i en annan 32bit dator (os) och testa, är något fel är det bara att byta igen zzz

Om någon mer har problem med USB -serial (CDC) på atmels produkter eller någon annan för den delen på 64Bit windows,
http://curiouslynerdy.com/2009/10/usb-c ... t-windows/

Har inte hunnit testa den ännu men ser lovande ut!

Re: AD omvandlare

Postat: 28 juli 2011, 15:14:29
av gripner
Guiden ovan fungerar fint på 64 bit w7

Re: AD omvandlare

Postat: 28 juli 2011, 23:31:46
av ie
Satt och svor en del för några dagar sen då jag fick opålitliga mätningar i en ATtiny85. Löste sig när jag så passusen om att ha rätt timing för ADC'n. Man måste välja lämplig prescaler beroende på klockfrekvensen. I 8MHz har jag för mig att 64 var ett lämpligt värde. Mätningarna blev då helt stabila. Inga delay behövs heller.