[En-Nut-Discussion] Analog input

The Laing Family laing at bigpond.net.au
Sat Jan 17 04:40:46 CET 2004


A couple of clarifications/questions:

a) The DivFactor parameter in my function doesn't seem to have any effect at
all, although I believe I'm calculating the mask correctly. But then again,
I've never understood why Lars was using a division factor of 128? Back to
reading the datasheet...!

b) Over the linear range of the input, the relationship I get between the
value read (in decimal) and the input voltage (in volts) is:

		Value = Voltage * 380

c) I thought the upper limit of the measurable voltage (when the value
returned is 0x03FF) would be the same as the reference voltage (2.56 volts),
but this doesn't seem to be precisely the case, although it's very close.
For instance, I've got a reading of 1010 (0x03F2) for a voltage of 2.69
volts. Is this just some inaccuracy in my voltage measurement?

Regards,

Simon

PS. One other crucial point to remember when working with the analog inputs
is the note on the Ethernut site: "PORT F connector GND not connected to R3.
This is caused by a major problem with the Cad Software we are using. Either
use a short wire from the mounting hole or use a ground connection on your
board."

> -----Original Message-----
> From: en-nut-discussion-bounces at egnite.de
> [mailto:en-nut-discussion-bounces at egnite.de]On Behalf Of The Laing
> Family
> Sent: Saturday, 17 January 2004 1:51 PM
> To: Ethernut User Chat (English)
> Subject: RE: [En-Nut-Discussion] Analog input
>
>
> Hmmm, I think this may be a bit trickier than it first appears -
> at least I
> have been struggling with the same issue. However, I think I have pretty
> well worked it out, though I would be very grateful for someone to correct
> any mistakes I have made. A few notes:
>
> 1) Port F is not marked in any way on my Ehthernut 2.0 board, and its
> location is not explained in the hardware manual. However, it is the only
> 20-way IDC connector on the board and is located on the edge of the board
> next to the programming port socket.
>
> 2) The allocation of the pins is shown in the circuit diagrams at the back
> of the hardware manual, and the AVCC5 pins are nearest the R3 resistor.
>
> 3) The documentation in the Atmega128 datasheet is pretty exhaustive and
> very useful.
>
> As for software, I have slightly modified Lars Andersson's code
> to use only
> 1 function (I don't know why he bothered with a separate initalisation
> function?), and include my code below. Using this, I get a
> reasonably linear
> reading of the voltage on the input up to about 3V, then it seems
> to flatten
> out.
>
> I hope this is useful to someone....
>
> Regards,
>
> Simon (Laing)
>
> /*
>  * FUNCTION:    ADConvert
>  *
>  * DESCRIPTION: Read one of the analog channels using a simple,
> non-interrupt driven ADC driver
>  *
>  *				This involves manipulating the ADC
> registers, which are specified as
> follows
>  *				for the Atmega128 (see page 243-246
> of the Atmega128 Manual)
>  *
>  *					Register	Bit
> Name	Value	Meaning
>  *				 	ADMUX		 7
> REFS1 	  1		Use internal 2.56V REF with external
> capacitor at AREF pin
>  *				 	ADMUX		 6
> REFS0	  1		Use internal 2.56V REF with external capacitor
> at AREF pin
>  *				 	ADMUX		 5
> ADLAR 	  0		Left Adjust Result (0 = Right-adjusted)
>  *				 	ADMUX		4-0
> MUX4..0	  n		Input Channel and Gain Selection
>  *
>  *				 	ADCSRA		 7
> ADEN 	  1		AD converter on
>  *					ADCSRA		 6
> ADSC	  0 	Start Conversion
>  *				 	ADCSRA		 5
> ADFR 	  0		Free-running Select (0 = OFF)
>  *				 	ADCSRA		 4
> ADIF	  0		ADC Interrupt Flag (Set when conversion
> completes)
>  *				 	ADCSRA		 3
> ADIE	  0		ADC Interrupt Enable (Interrupts enabled when
> set)
>  *				 	ADCSRA	 	2-0
> ADPS2..0  7		Pre-scaler Select bits (Gives division
> factors from 2 to 128)
>  *
>  * PARAMETERS:	Channel:		Analog channel to
> read (0 - 7)
>  *				DivFactor:		Division
> factor - any power of 2 up to 128.
>  *
>  * RETURN CODE: 10-bit analog value
>  *
>  * SOURCE: 		Derived from Lars Andersson on
> http://news.gmane.org/gmane.comp.hardware.microcontrollers.ethernut
>  */
> int ADConvert(short Channel, short DivFactor)
> {
> 	int ADresult;
> /* Result to be returned
> 		*/
> 	int DivMask = 0;
> /* Bit mask for the requested division factor			*/
> 	int	i;
> 		/* Loop counter for computing log value
> 		*/
>
> 	/*
> 	 * Set the multiplexer register
> 	 */
> 	ADMUX = 0xC0 | (Channel & 0x07);		/* Use
> internal ref voltage and set
> channel */
>
> 	/*
> 	 * Compute the bit mask for the division factor
> 	 */
> 	for (i = 0; i < 8; i++)
> 	{
> 		/*
> 		 * Need to take the log of the requested division
> factor. Do this by
> 		 * working out which is the most significant bit
> 		 */
> 		if (DivFactor & 0x01)
> 			DivMask = i;
> 		DivFactor >>= 1;
> 	}
>
> 	/*
> 	 * Set up the Control and Status register. Enable ADC,
> clear ADIF (by
> setting it!),
> 	 * and set the division factor
> 	 */
> 	ADCSRA = (0x90 | DivMask);
>
> 	/*
> 	 * Delay a little to settle the MUX
> 	 */
> 	NutDelay(40);
>
> 	/*
> 	 * Start the ADC and wait for it to complete the conversion
> 	 */
> 	sbi(ADCSRA, ADSC);               		/* Start ADC	*/
> 	loop_until_bit_is_set(ADCSRA, ADIF); 	/* Wait for ADIF,
> will happen soon */
>
> 	/*
> 	 * Read the input value
> 	 */
> 	ADresult = ADCL;			    		/*
> Read LSB first   */
> 	ADresult |= ((int)ADCH) << 8;			/* then MSB
>         */
>
> 	/*
> 	 * Clear the ADCSRA, including the AD Interrupt Flag (by
> setting it!)
> 	 */
> 	ADCSRA = 0x10;
>
> 	return(ADresult);
> }
>
>
>
> > -----Original Message-----
> > From: en-nut-discussion-bounces at egnite.de
> > [mailto:en-nut-discussion-bounces at egnite.de]On Behalf Of Simon Biniek
> > Sent: Saturday, 17 January 2004 1:29 AM
> > To: Ethernut User Chat (English)
> > Subject: Re: [En-Nut-Discussion] Analog input
> >
> >
> > > Do some have a example how i can use the analog
> > > input on ethernut using the internal analog input og
> > > port F?
> >
> > It's the third time you've asked that and you've got
> > an awnser and example code here in the group.
> > First off all read the Datasheet of the AtMega128.
> >
> > > I have a ordninary temperature resistor. I want to
> > > sample the value of the resistor.
> > > On port F it is pins fra 1..8. How do i connect the
> > > resistor?
> >
> > Analog Inputs can't directly mesare resistors. They
> > only can measure voltages. You have to build a voltage
> > divider or a robinson bridge.
> >
> > regards
> >
> > Simon
> >
> >
> > __________________________________
> > Do you Yahoo!?
> > Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes
> > http://hotjobs.sweepstakes.yahoo.com/signingbonus
> > _______________________________________________
> > En-Nut-Discussion mailing list
> > En-Nut-Discussion at egnite.de
> > http://www.egnite.de/mailman/listinfo.cgi/en-nut-discussion
>
> _______________________________________________
> En-Nut-Discussion mailing list
> En-Nut-Discussion at egnite.de
> http://www.egnite.de/mailman/listinfo.cgi/en-nut-discussion




More information about the En-Nut-Discussion mailing list