[TUT] [C] Newbie's Guide to the AVR ADC

Go To Last Post
326 posts / 0 new

Pages

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

My guess is that there is some sort of interrupt/triggering happening but I can't quite get it.

Well microcontoller will be doing Analog to Digital conversion behind the scene. and will update converted digital data in ADCH and ADCL.

Quote:

Without the
ADCSRA |= (1 << ADATE);

line it was behaving even more strangely (the behavior was dependent on the speed with which I move the potentiometer - if I move fast LED1 turns on, if I move slow LED2 turns on, both at around 2.5V).

If u read data sheet u will come to know that ADATE bit in ADCSRA is for the auto triggering. so controller will do ADC conversation repeatedly based on the triggering source.

So if u dont set the ADATE bit controller will do Analog to Digital conversion only once and your led will be on based on voltage value of the pot. at that time.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I recently read through this tutorial and found a part that might lead to confusion.

In the tutorial it insists that two 330 ohm resistors must be used with the pot to avoid damage. I believe that this is incorrect (in most cases). the potentiometer will always be a fixed resistance between Vcc and Ground. therefore you do not need to worry about a low resistance path between Vcc and ground, for example in the tutorial it gives a 10k pot, if you only had the pot, you would always have 10k between Vcc and Ground regardless. Now one might be concerned about shorting the ADC input to Vcc or ground( this is what the Tutorial cites as the reason for the 330 ohm resistors), this is a possible condition. But, it is not a problem. Any standard ADC, like a voltmeter, will have a high input impedance, if this was not the case the ADC itself would sink appreciable current and change the voltage at the node you are measuring. In the ideal case the ADC would have infinite input impedance and would have no loading effect on the node of interest. It therefore is OK to directly connect the ADC to Vcc or Ground. The one problem that could arise is if the nominal value of the pot is low enough to allow too much current outside the specs of the power supply or the pot itself.

Josh

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the section "Voltage Reference Selection" of my atmega32's datasheet it is said that if AVCC is used as the voltage reference, an external capacitor should connected at AREF pin. How important is this? And what should the value of this capacitor be?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can someone tell me what the minimum samping rate is for the built-in ADC in ATMega32?

Plus, My mega32 doesn't have a ADFR bit, how do I initiate a free running conversion? Right now, Only single conversions are working for me.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

My mega32 doesn't have a ADFR bit, how do I initiate a free running conversion?

Read the section Starting a conversion in the data sheet, especially the pieces on "Auto triggering". And you could always try to actually use the search function in Acrobat Reader to search for "free running"...

Quote:

Can someone tell me what the minimum samping rate is for the built-in ADC in ATMega32?

Mimimum? :shock: In my world "rate" is something per units of time (ie. a symonym to "frequency"), so the mimimum samples per time you can get is "none at all per eternity" (approximately :wink:). I suspect that you are asking about maximum sampling rate. This would depend on the clock rate of the ADC.

Questions seems kind of odd, and clues to answers are easily locatable. Is this part of a school assigment perhaps?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I mean can I sample the data, at say anything from 1kHz to whatever the maximum samplng rate is?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, again you ought to turn to the data sheet
Page 202:

Quote:
By default, the successive approximation circuitry requires an input clock frequency
between 50 kHz and 200 kHz to get maximum resolution. If a lower resolution than 10
bits is needed, the input clock frequency to the ADC can be higher than 200 kHz to get a
higher sample rate.

From page 205 we can get that a conversion takes 13 cycles. Now we just need to apply some math to finish with a sampling frequency of (approximately) 3.85 KHz to 15.3 KHz. Gor lower sampling rates simply pause between samples. For higher rates you will have to sacrifice ADC accuracy.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hai all i'm doing a project which will control the temperature of Cooler. I'm using two adc channels

I have tried it by changing the channel and giving start conversion. i'm not using ADC interrupt.

now i want to use ADC interrupt two get datas of both channels. this is because for maintaining time interval.

Please help me by giving some guidelines how to proceed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does anyone know why this code does not work? I update the free running mode's code and I'm using an ATMega48.

int LEDS(int z)
{
	if(ADCH < 1)
	{
		(LED 1 on);
	}
	if(ADCH < 63)
	{
		(LED 2 on);
	}
	if(ADCH < 124)
	{
		(LED 3 on);
	}
	if(ADCH < 248)
	{
		(LED 4 on);
	}
}


int main (void)
{
	ADCSRA |= (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0);
		
	ADMUX |= (1 << REFS0); 
	ADMUX |= (1 << ADLAR);
		
	
		
	ADCSRB |= (0 << ADTS2) | (0 << ADTS1) | (0 << ADTS0);
	ADCSRA |= (1 << ADEN); 
	ADCSRA |= (1 << ADSC); 
		
	while(1) 
	{ 
		LEDS(0);
	} 
} 

Life Is Like A Bucket Of Chicken.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OMGHWGA...

Quote:

Does anyone know why this code does not work?

No-one wants to read your code, think hard, maybe even dig out a mega48 and try to run the code, using some input they guess and hope is similar to yours.

Take a break, sit down and have a cup of coffe, and think about what someone who should help you needs to know. I'm hoping that you at least come up with theese:

1) A description of the circuit.
2) A description of what kind of signal you are sending in to the ADC.
3) A description of what you see that makes you decide that it is not working.
4) A description of what you have done up to now in form of thinking and tests.

One thing that might, or might not, have to do with your problem is that you read the ADC four times to determine which LEDs to turn on. If you want the four leds to be controlled by the same ADC reading you need to read the ADC once to a temporary variable and then use that for your four tests.

Or could it be that when the ADC value is low you see all LEDs on when you just want LED 1 on? If so then you need to arrange your if's in a cascading way (if- else if - else if ... ).

If I sit another half-hour thinking and guessing I might come up with ten more tips. One of those might be the one you needed, but then you have wasted my time coming up with the other nine because you didn't take your time to think about your audience. Go make coffe...

EDIT: Another tip on the side is to start a new thread for a new question (instead of bloating a thread that is about Deans tutorial). For a new question use the "New Topic" button rather than the "New Reply". If you think out a subject for your new thread that is both accurate and tempting more people will probably be interested.

EDIT: And I need to go to bed, as I am obviously too tired. This tutorial is written by Ken, none other. Sorry Ken, but as Dean more or less owns this corner of 'freaks it was an easy mistake to make. Assumption is the mother of many Foul-ups...

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

(instead of bloating a thread that is about Deans tutorial)

Credit where credit is due, this actually isn't one of mine. A fellow member went to the trouble of writing it, and only copied my writing style to remain consistent. Did a damn good job of it too - confused the hell out of me for a few minutes when I saw it, as I couldn't remember writing it...

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The input circuit is the same setup as the tutorial. And for the output, I turn the variable resistor, and one LED turns on, then another turns on, then another turns on, then another turns on. That is what I'm trying to do.

Life Is Like A Bucket Of Chicken.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Taco_Bell wrote:
The input circuit is the same setup as the tutorial. And for the output, I turn the variable resistor, and one LED turns on, then another turns on, then another turns on, then another turns on. That is what I'm trying to do.

So, what are you using as the trip points to turn on the LEDs at different ADC values? Are you using specific bits being turned on, or are you using byte or 10 bit integer values?

That is, for bit specific trip points, dose say, B1 turns one one LED, B3 turns on another LED, B5 another, B7 turns on yet another LED, etc.?

Or, are you using value based comparisons such as, the integer value 100 (0x64) turns on an LED, 155 (0x9B) turns on a different LED, and 200 (0xC8) yet another LED?

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

63, 126, 189, 252 are my trigger points and I'm running it 8 bit style.

Life Is Like A Bucket Of Chicken.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I doubt please. It is my first time dealing with ADC so... be pacient...

Question one: I have the ATMega128 on a stk300 board and that board comes with a blue pot. Does this pot is for testing ADC? I cant understand its aim from the STK300 manual :-(

Question 2: I have a 10k pot. Please confirm me this:
I plug the wiper in the port F pin 0 (adc0). The vcc pin of the pot is plugged in the avcc pin or in the vcc pin of the port F? and the same about the ground. Do I have to make grounds in common (port f gnd and Agnd)?
Sorry I am not a expert in english language and I didnt undertood this on the tutorial...

Thank you very much
Alex

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The vcc pin of the pot is plugged in the avcc pin or in the vcc pin of the port F?

I understand that english is not your first language, but there is a real problem understanding your sentence above.

Anyway, here is a description of how to connect a potentiometer so you can read it's position with the AR ADC:

A potentiometer has three connections. One on each end of the resitive track, and one on the "wiper" that can move along this resistive track. You connect one of the endpoints to VCC and the other endpoint to GND. Thw wiper goes to the AVR ADC pin.

Connecting a potentiometer this way effectively makes it into a voltage divider. The voltage on the slider will be proportional to its position between the two endpoints.

http://en.wikipedia.org/wiki/Pot...
http://en.wikipedia.org/wiki/Vol...

If the pot on the STK300 you are talking about is the one close to the four headers forming a square, then this is used to adjust the analogue reference voltage (I believe it is marked AREF, but the piccture of the STK300 I found is not of good quality).

From a 1999 version of the STK300 User Manual:

Quote:
To use the [...] (on-board) Voltage Reference, the pot marked AREF is used to set the voltage
level.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Does the vcc pin of the pot is plugged in the avcc pin od of borad or it is to be plugged into the vcc pin of the port F (the ADC port)?"

I already simulated it in a test board with 2 330 resitors and a led on the wiper and it works and I know the pins of the pot. My doubt is:

How do I feed the pot? 1. Should I use the Vcc and GNd of the ADC port or 2. pot must be feed using the AVCC and AGnd?
Case 2: do I have to connect both gnds (port f gnd and Agnd) in order to make gorund common?

And what about a photoresistor that just has 2 ends? How it is connected to the portF?

Thanks, please be patient... :-)

Alex

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

<--- Im a newbie take it easy on me!

What about when you want to get a reading from your vcc ? for example I would like the avr to detect when its own voltage source is getting low. Great tutorial though!!

Support my site for funding my AVR projects!! heh

Credit Card Information

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi. Been reading the tutorials for a couple months learning WinAVR. Just signed up so this is my first post here.

Clawson pointed out to me that both the ADCH & ADCL registers must be read for ATTiny261's ADC to be refreshed as he illustrated in the post below mine here. So as frustrating it was to me to get all this to work and find code that can migrate from MCU to MCU, if it helps, here is working ISR driven ADC code for this MCU. No sense in letting this post go to waste:

#include "avr\io.h"
#include "avr\interrupt.h"

int main(void)
{

	// PORTB set for output
	DDRB = 0b11111111;
	
	// PORTA set high nibble as output
	DDRA |= 0b11110000;

	// No need to set A/D channel; reading ADC0 by default


	// Set prescaler to clk/8 to get 125kHz ADC clk
	// (Running 8MHZ w/ divide by 8 bit enabled = 1 MHZ)
	// 1MHZ / div by 8 ADC prescaler = 125kHz ADC clk
	ADCSRA |= (1 << ADPS1) | (1 << ADPS0);
	
	// Set ADC Vref to 2.56V
	// (with ext decoupling cap)
	ADMUX |= (1 << REFS1) | (1 << REFS0);
	ADCSRB |= (1 << REFS2);
	
	// Set ADC to free run mode
	ADCSRB &= ~(1 << ADTS2) | ~(1 << ADTS1) | ~(1 << ADTS0);
	
	// Enables ADC for use
	ADCSRA |= (1 << ADEN);
	
	// Enable ADC Interrupt
	ADCSRA |= (1 << ADIE);

	// Enable Global Interrupts
	sei();
	
	// Starts ADC conversion
	ADCSRA |= (1 << ADSC);

	// ADC Auto Trigger Enable
	ADCSRA |= (1 << ADATE);

	// Loop forever. ISR will interrupt when called.
	while (1)
	{
	}
}


ISR(ADC_vect) 
{ 
	// output ADC's value to PORTB,
	PORTB = ADCL;
// don't care about first 2 MSBs but they still must be loaded into some variable (ie read from the ADCH register) for the ADC to be updated.
temp = ADCH;
} 
Last Edited: Mon. Jun 2, 2008 - 07:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can't help wondering if this from the 261 datasheet is relevant here:

Quote:
When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently, if
the result is left adjusted and no more than 8-bit precision is required, it is sufficient to read
ADCH. Otherwise, ADCL must be read first, then ADCH.

Maybe try dummy reading ADCH and see what happens. Or simply:

PORTB = ADCW & 0xFF

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ +rokof+ below:

Single Conversion mode can offer a quieter signal aquisition conversion due to the fact that the programmer can disable unused MCU services prior to a conversion cycle.

Free run mode may be simpler to program for those learning the MCU. I can understand the possibility that after one masters the ADC module, single conversion mode may be one of choice.

Last Edited: Wed. Jul 2, 2008 - 03:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

how do you set up ADC for single mode?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
how do you set up ADC for single mode?

Follow the first post but don't set ADFR (free run mode). Now a conversion is triggered each time you set the ADSC bit and is complete when you see that ADSC bit trasition from 1 to 0. (don't be tempted to use ADIF as the signal for completion or, if you do, make sure to clear the bit each time - but using ADSC as the flag is much easier as it's self-clearing)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

what are the advantages of free running ADC over single mode?
I want to check the temperature of a tank in intervals of say 2 sec.What would be best? Set the ADC in free run mode and check ADCH every 2 seconds or set it in single mode and every 2 sec make a conversion then check ADCH?

Is free running more cpu consuming or the other way around? Maybe I'll implement a floating point controller algorithm in the future so i want to know

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I have some questions about voltage divider. How can pot output 0.15 to 4.85 volts? On one side pot will output

((330+10)/(330+330+10))*5V
340*5/670 = 1700/670 = 2.537 V

On the other side:

((330)/(330+10+330))*5V
330*5/670 = 1650/670 = 2.462 V

http://en.wikipedia.org/wiki/Vol...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wonderful tutorial, very helpful. I learned enough to build a simple voltage / battery monitor for another circuit!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, Thanks for the great tutorial. I'm completely new to all this. A month ago I had no idea what an AVR even was, and now I'm barely beginning to understand. Ports and registers and bits are still all kinda like mysterious black boxes to me, but hopefully I'll figure it out.

Anyway, my question, and I know it's probably really stupid, is what if you want to use the ADC to control the frequency of a flashing LED rather than just whether the LED is on or off based on a threshhold voltage? Can you write a line of code like

LEDfrequency = (ADCH/10);

and then use LEDfrequency as a variable in a flashing subroutine?

If there's a tutorial already written on this, I'm sorry. You could just point me in that direction if you don't want to re-explain it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Can you write a line of code like

LEDfrequency = (ADCH/10);

and then use LEDfrequency as a variable in a flashing subroutine?


Sure, why not? You can use the information you got from the ADC in any way that you want.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

I am a newbie in AVR programming. Currently I am building a project with ATMEGA8 ADC. In this project, I am using 2 ADC inputs (ADC0 and ADC1), XTAL 3.6864 MHz (prescaller : 101). The problem is:

When I activate only 1 channel (ADC0), it works nicely. However, when I tried to switch to the other channel (ADC1), my program just read the same value like the first one. I change the channel by setting and clearing MUX0 bit to select ADC0 and ADC1.

Could anyone help me with this? Here is the simple program based on program list Dean's Tutorial (1st page), with modification to read 2 ADC Channels:

#include
#include
#include "lcd.h"

int adc0 = 0;
int adc1 = 0;
int adcport = 0;

int main (void)
{
int num;
char buffer[7];

lcd_init(LCD_DISP_ON);
lcd_command(LCD_DISP_ON);
lcd_clrscr();

ADCSRA |= (1 << ADPS2) | (1 << ADPS0);
ADMUX |= (1 << REFS0);
ADMUX |= (1 << ADLAR);

ADMUX |= (1 << MUX0);

ADCSRA |= (1 << ADFR);
ADCSRA |= (1 << ADEN);
ADCSRA |= (1 << ADIE);
sei();
ADCSRA |= (1 << ADSC);

for(;;)
{
lcd_gotoxy(0,0); // Display ADC0
lcd_puts("ADC0: ");
num = adc0;
itoa(num , buffer, 10);
lcd_puts(buffer);
lcd_puts(" ");

lcd_gotoxy(0,1); // Display ADC1
lcd_puts("ADC1: ");
num = adc1;
itoa(num , buffer, 10);
lcd_puts(buffer);
lcd_puts(" ");
}
}

ISR(ADC_vect)
{
if (adcport==0)
{
if (ADCH==0)
adc0 = ADCL;
else adc0 = ADCH * 256;
adcport = 1;
ADMUX |= (1<<MUX0); // Switch to ADC1
}
if (adcport==1)
{
if (ADCH==0)
adc1 = ADCL;
else adc1 = ADCH * 256;
adcport = 0;
ADMUX &= ~(1<<MUX0); // Switch to ADC0
}
}

Thanks a lot !!!

Best,
wibi

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

FAQ#1 - trying making your main/ISR shared variables volatile.

Also for reasons of atomic access it is unwise to make them 16 bit (two register) wide 'int' if 'char' would be OK

If they must be 16 bit then protect access to them in main with "sregcopy=SREG; cli(); access the variable; SREG=sregcopy"

Also your code doesn't look right:

if (ADCH==0) 
adc0 = ADCL; 
else adc0 = ADCH * 256;

Appears to violate the datasheet requirement:

Quote:
When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently, if the result is left adjusted and no more than 8-bit precision is required, it is sufficient to read ADCH. Otherwise, ADCL must be read first, then ADCH.

Also this code only ever appears to set ADSC once and it does not appear to be configuring for free-running mode.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What are you intending this

if (ADCH==0)
   adc0 = ADCL;
else 
   adc0 = ADCH * 256; 

to do? No, no nitpicking, an honest question.

There is a strict procedure to follow if you read both ADCH and ADCL. Those registers are "double buffered" wich means that in order to always being able to read a value pair ot of them that belongs to the same register then you need to read them in this specific order: First ADCL and then ADCH. The mechanism involved works like this: When you read ADCL then the low byte of the current conversion value is read out of ADCL immediately, and the high byte of the same conversion value is moved to a temporary register. When you read ADCH that temporary registers value is returned. And as long as you dont read ADCH no new conversion values will be moved into the registers. This also implies that you should not read the same register twice. If you read ADCL two times, then the same value will be returned for the two reads. If you read ADCH twice (as you do with first the test if ADCH==0 and then adcn = ADCH * 256 you risk getting values from two different concersions if a conversion finishes between the test and the assignment. (Data sheet page 195.)

If you for some reason just want to combine ADCH and ADCL to a (a 16 bit) integer value then this simple scheme will work in avr-gcc (WinAVR):

adcn = ADC;   // Read the full 16 vit ADC value

Tip: Learn how to use the code tags when posting as this will preserve the indentation, and prevent semicolon-right parenthesis from being displayed as a wink-smiley.

EDIT: Ooops! Didn't notice the (new) fifth page of the thread with Cliffs response.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hey everyone, i have a serious problem or at least that's what i think it is..
i have just bought a new laptop and it does not have an RS232 female with it, it only has the VGA female... how can i connect the butterfly to bray's terminal?? please help:( thanks a lot

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need a USB-to-RS232 converter. Prepare to spend $20 to £30.

There are lots of them around. Here is one example: https://www.crystalfontz.com/car...

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What does this thread have to do with either RS-232 or the Butterfly?

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Plus, it is cross posted. I informed the poster in another thread that his post was considered uncool.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Very well done. It cleared up a few issues I was having. If your not running free run mode or using interrupts this code is handy.

while (ADIF ==0);
This flag is set when the conversion is ready.
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
while (ADIF ==0);

that statement says something like:

while (4 ==0);

which will never be true. I bet you meant something like:

while ((ADCSRA & (1<<ADIF)) ==0);

(but it's better to block on ADSC being one than ADIF being zero anyway)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When setting the prescaler in ADCSRA, we usually hard code the prescaler values like this:

ADCSRA |= (1 << ADPS2) | (1 << ADPS0);

Unfortunately, when we change our chip's clock speed, we have to remember to change the ADC prescaler as well. If we set the prescaler bits using an algorithm that takes into account the CPU clock speed, we can avoid this problem:

uint8_t prescale = 0;
for( uint8_t div = (F_CPU / 200000L) - 1;
        div > 0;
        div >>= 1, prescale++);
ADCSRA |= prescale;

In the compiled program, this will not result in any more code than the previous example. Since the value in prescale is a constant at compile time and the prescale variable is not used anywhere else, these get optimized out leaving the same code as the first example.

If you look at the AVR datasheets, you'll see that the ADPSx bits are just the Log2 value of the division factor which is all the above calculates. It will pick the smallest division factor that will set ADC clock as close to 200KHz without going over.

Cheers,

Tom

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for this splendid tutorial. After only reading the datasheet of my avr i had a whole load of questions all of which were answered by the text above.
Thanks for taking the time to write.

There is one little thing. The datasheet i raed concerned exactly my Atmega8. At one point it says:

"The ADC is enabled by setting the ADC Enable bit, ADEN in ADCSRA. Voltage
reference and input channel selections will not go into effect until ADEN is set."

Does that mean i will have to enable ADC only as a last step of setting the ADMUX and ADCSRA registers?

Meanwhile i can see that for your microcontorler there was no such demand. (in the code you'r enabling ADC only as the last step in the whole ADC registers setup.

Are there already such huge differences between different AVR's?

Kind regards

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's always good programming practice to leave the actual enabling of a device until the very last step after all other initialisation. Consider a timer for example. As soon as the CS bits are set it starts running. You'd probaby want to ensure that it had already been set into the right mode and configured to produce the right external pin behaviour BEFORE it starts counting.

As for the ADC nothing really happens (even after ADEN) until you set ADSC so you really just need to ensure that THIS is the last step of initialisation in fact and you could ADEN earlier in the sequence.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I see. Thanks for answering.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I used the code from "Part 1 – A Simple Free-Running ADC Example" - it works great. But how to change it from 8-bit precission into 10-bit precission ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

But how to change it from 8-bit precission into 10-bit precission ?

The ADC is running with 10-bit precision in the first part, but it is left justified so that you get the eight most significant parts in ADCH. To get all 10 bits you
i) Want the result right justified in ADCH+ADCL, and
ii) want to read the 16-bit value in ADCH+ADCL

Item i) is accomplished by not setting the ADLR bit.

Accomplishing item ii) depends on your compiler. For avr-gcc (WinAVR) you can simply do:

int theValue = ADC;

If your compiler does not offer you this nifty access to 16-bit "L+H-registers" then this should work in any standards-compliant compiler:

int theValue = ADCH<<8 + ADCL;

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have the same configuration as in the first example, and I've verified that the voltage over the resistors vary between 0.16V and 4.85V.

The problem is that I'm only seeing 0-64 on ADCL and always 0 on ADCH. If I use the left alignment option, I only see 0-16 on ADCH. What happened to the 10-bit range?

I'm using an ATMEGA8, my reference voltage is set to Vcc and I'm sending the values through RS232 to my computer (which works fine).

please help!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,
i have a problem which i cannot overcome alone, so if somebody can help me i'll be thankful.

I'm using Mega128 with 1MHz clock source and debugger JTAGICE,but after conversion ADCL and ADCH are empty(and they shoudnt).
If someone can give some clue what is wrong.
Here is my code:

#include 

#define ADCCon	 (ADCSRA|=0x40)//Start ADC Conversion

void AdcInit(void)
{
	ADMUX |= (1 << REFS0);//AVCC with external capacitor at AREF pin
	ADCSRA|=0x80;//Enable ADC
	ADCSRA |=(1 << ADPS1) | (1 << ADPS0);//Select Division Factor =8
}
int main (void)
{	int buf;
	
	AdcInit(); 

	for(;;)
	{
		ADCCon;
		while(ADCSRA &(1<<ADSC)) {};
		buf = (ADCH<<8) + ADCL; 
	}

}

10x.
O ,and i add to watch variable "buf", but the value is "Location not valid".
It stays that way even when i set it to 0 (int buf=0; )

Beware the barrenness of a busy life.
Socrates .

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cahofmeyr wrote:
I have the same configuration as in the first example, and I've verified that the voltage over the resistors vary between 0.16V and 4.85V.

The problem is that I'm only seeing 0-64 on ADCL and always 0 on ADCH. If I use the left alignment option, I only see 0-16 on ADCH. What happened to the 10-bit range?

I'm using an ATMEGA8, my reference voltage is set to Vcc and I'm sending the values through RS232 to my computer (which works fine).

please help!

Can someone please help me?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you so much for this tutorial. I'm a newbie and this tutorial was GREAT!

It's so nice that people like you and abcminiuser doing these tutorials!

So thanks again! :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks for the tutorial! I got the ADC up and running in no time!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

as for 10-bit conversions, the code in this thread to add them is wrong (for my GCC).

value = ADCL + (ADCH<<8);

I fixed it with the above code, by swapping them : which the pre-processor will probably correctly read the L then the high byte (at least in my tiny brain it makes sense). I now get 10 bits, yay!

I read the datasheet at least 5 times, but the tutorial made it all come together. Thanks.

Conrad Braam - www.softcircuitry.blogspot.com - www.plcsimulator.org
Always start off poorly, that way when you finally figure it out, you can get a few surprise hits in.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Any reasonably new avr-gcc/avr-libc will happily accept the simple

value = ADC;

and generate the correct code sequence for reading ADCH and ADCL and combine them into one 16-bit value.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Pages

Topic locked