PLEASE BIG HELP ATTiny13 ADC

10 posts / 0 new
Author
Message

I'm newbie to this ADC concept anyway i think i pretty much get it running from values 0 and 5vc (discrete input) but that's not my idea.
I need to turn on an output when i reach more than 2.5V please help me with this.

I just need a guide how to calculate the value i got from the ADC, i'm lost completely.

Here is the code:

```#include
#include
int ReadADC(char);
int val=0;
int main (void)
{
DDRB |= (1 << 1);
DDRB &= ~(1 << 4);

ADMUX |= (1 << REFS0);
ADMUX |= (1 << MUX0) | (0 << MUX0);

ADCSRA |= 0b10000000;
while (1)
{
val = ReadADC(2); <<-- Here how i calculate [val] i need to compare it when is bigger than 2.5v

}

return 1;
}

int ReadADC(char n)
{
ADMUX = n;			//n is a channer between 0 and 7
ADMUX |= 0b01000000;	//0x40 = 0b01000000 = AVcc = voltage reference
ADCSRA |= 0b01000100;	//0x44;= 0b01000100	bit6= start ADC conversion, bit2= div factor = ck/16

while((ADCSRA & 0x40) !=0){}; //wait for conv complete

return ADC;
}
```

Please help me i really needs this to get going on a project. I know you guys have this expertise.

Last Edited: Sat. Dec 12, 2015 - 12:53 PM
Total votes: 0
`   ADMUX |= (1 << REFS0);`

This selects the internal voltage reference which only goes up to 1.1v. You will need to use vcc as a reference.

Once you have done that, then you just need to test if the returned value is greater than 1024 * vcc / 2.5.

Regards,
Steve A.

The Board helps those that help themselves.

Total votes: 0

Thanks a lot for a quick response, but i'm a newbie on this. VCC needs to be setup some how??

I change my code due to your suggestion like this.

```// ATtiny13
// ADC Module
#include
#define F_CPU 8000000UL
#include

int ReadADC();
int val=0;
int main (void)
{
DDRB |= (1 << 1);
DDRB &= ~(1 << 4);
PORTB &= ~(1 << 4);

ADMUX |= (0 << REFS0); // VCC as Reference
ADMUX |= (1 << MUX1) | (0 << MUX0); // ADC2 PB.4
ADCSRA |= (1 << ADEN); // Enable ADC

while (1)
{
val = ReadADC();

if (val > 2048)
{
PORTB &= ~(1 << 1);
}
else
{
PORTB |= (1 << 1);
}
}

return 1;
}

int ReadADC()
{

ADMUX |= (0 << REFS0); // VCC as Reference
ADMUX |= (1 << MUX1) | (0 << MUX0); // ADC2 PB.4
ADCSRA |= (1 << ADSC); // Start Converstion

while((ADCSRA & 0x40) !=0){}; //wait for conv complete

return ADC;
}
```

I really appreciate the big help.

Total votes: 0
`ADMUX |= (0 << REFS0);`

should be

`ADMUX &= ~(1 << REFS0);`

This seems not right

``` while (1)
{
val = ReadADC();
if (val > 2048)
{
PORTB &= ~(1 << 1);
}
else
{
PORTB |= (1 << 1);
}
} ```

I think that should be like this

```while (1)
{
val = ReadADC();
if( val > 511)	// <-- mind this
{
PORTB &= ~(1 << 1);
}
else
{
PORTB |= (1 << 1);
}
}```

or simply the code can be like this

```while (1)
{
if(ReadADC() > 511)
PORTB &= ~(1 << 1);
else
PORTB |= (1 << 1);
}```

Please keep in mind that ADC value never exceeds 1023 since the ADC's resolution is 10bit (0..1023)
Roughly,
0 means 0 volt, 1023 means 5 volt and if you need 2.5 volt then 1023/2 = 511.
Big enough? :D

KISS - Keep It Simple Stupid!

Total votes: 0

Yep thanks a lot man. my ADC is working fine. I think i want to revisit the concept because there's a lot stuff that is a little fuzzy for me.

Any good reference you can tell me to make my ADC expertise stronger?

Total votes: 0
`      if (val > 2048) `

Sorry, that was my fault. I meant to say 1024 * 2.5/ vcc. That would make 512 (or 511) the correct answer.

Regards,
Steve A.

The Board helps those that help themselves.

Total votes: 0

Thanks any way, it is working fine now.
I will post the code for someone who need it in the future.

```// ATtiny13
// ADC Module
#include
#define F_CPU 8000000UL
#include

int ReadADC();
int val=0;
int main (void)
{
DDRB |= (1 << 1);
DDRB &= ~(1 << 4);
PORTB &= ~(1 << 4);

ADMUX |= (0 << REFS0); // VCC as Reference
ADMUX |= (1 << MUX1) | (0 << MUX0); // ADC2 PB.4
ADCSRA |= (1 << ADEN); // Enable ADC

while (1)
{
val = ReadADC();

if (val > 625)
{
PORTB &= ~(1 << 1);
}
else
{
PORTB |= (1 << 1);
}
}

return 1;
}

int ReadADC()
{

ADMUX |= (0 << REFS0); // VCC as Reference
ADMUX = 2;// ADC2 PB.4
ADCSRA |= (1 << ADSC); // Start Converstion

while((ADCSRA & 0x40) !=0){}; //wait for conv complete

return ADC;
}
```
Total votes: 0

#define F_CPU 80000000UL

Quite an old post it is.
As much as i know, attiny 13 runs at 9.6 mhz. Since the CKDIV8 fuse is set by default. It should run at 1.2 mhz. But he F_CPU as 8 mhz. Wont the delays work erratically ? I mean we are telling the compiler that the tiny 13 is running at 8 mhz but it isnt.

Total votes: 0

Quite an old post indeed, so why resurrect it with a remark on something that has nothing at all to do with the problem?

Rudro17 wrote:
Wont the delays work erratically ?

What delays? There aren't any.

As much as I know, the #define you're remarking on does not affect the code at all.

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]

Total votes: 0

Locked because there is no material benefit to anyone in exhuming this thread.

Ross McKenzie ValuSoft Melbourne Australia