Attiny 13a adc not responding

Go To Last Post
42 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was making a IR proximity sensor for my school project using attiny 13a. I wanted to make it small, so i choose attiny 13a. Also, i have already bought a small enclosure for it. I have attached the schematic. The code was actually written for arduino by Ricardo Ouvina@instructables but i converted it for the attiny 13a.

# i use Avr studio 4.19

The arduino code -

 

// Simple Proximity Sensor using Infrared
// Description: Measure the distance to an obstacle using infrared light emitted by IR LED and
//   read the value with a IR photodiode. The accuracy is not perfect, but works great
//   with minor projects.
// Author: Ricardo Ouvina
// Date: 01/10/2012
// Version: 1.0

int IRpin = A0;               // IR photodiode on analog pin A0
int IRemitter = 2;            // IR emitter LED on digital pin 2
int ambientIR;                // variable to store the IR coming from the ambient
int obstacleIR;               // variable to store the IR coming from the object
int value[10];                // variable to store the IR values
int distance;                 // variable that will tell if there is an obstacle or not

void setup(){
  Serial.begin(9600);         // initializing Serial monitor
  pinMode(IRemitter,OUTPUT);  // IR emitter LED on digital pin 2
  digitalWrite(IRemitter,LOW);// setup IR LED as off
  pinMode(11,OUTPUT);         // buzzer in digital pin 11
}

void loop(){
  distance = readIR(5);       // calling the function that will read the distance and passing the "accuracy" to it
  Serial.println(distance);   // writing the read value on Serial monitor
  // buzzer();                // uncomment to activate the buzzer function
}

int readIR(int times){
  for(int x=0;x<times;x++){     
    digitalWrite(IRemitter,LOW);           // turning the IR LEDs off to read the IR coming from the ambient
    delay(1);                                             // minimum delay necessary to read values
    ambientIR = analogRead(IRpin);  // storing IR coming from the ambient
    digitalWrite(IRemitter,HIGH);          // turning the IR LEDs on to read the IR coming from the obstacle
    delay(1);                                             // minimum delay necessary to read values
    obstacleIR = analogRead(IRpin);  // storing IR coming from the obstacle
    value[x] = ambientIR-obstacleIR;   // calculating changes in IR values and storing it for future average
  }
 
  for(int x=0;x<times;x++){        // calculating the average based on the "accuracy"
    distance+=value[x];
  }
  return(distance/times);            // return the final value
}


//-- Function to sound a buzzer for audible measurements --//
void buzzer(){
  if (distance>1){
    if(distance>100){ // continuous sound if the obstacle is too close
      digitalWrite(11,HIGH);
    }
    else{  // beeps faster when an obstacle approaches
      digitalWrite(11,HIGH);
      delay(150-distance);  // adjust this value for your convenience
      digitalWrite(11,LOW);
      delay(150-distance);  // adjust this value for your convenience
    }
  }
  else{  // off if there is no obstacle
    digitalWrite(11,LOW);
  }
}
//i neglected the buzzer since i didnt require it.

//When i made first testd it on arduino, without any object nearby, it showed around 900 and with object in front, it showed around 300. So, i changed my arduino code a l//ittle bit like this-

int IRpin=A0;
int IRemitter=2;
int ambientIR;
int obstacleIR;
int value[10];
int distance;
void setup() {
Serial.begin(9600);
pinMode(IRemitter,OUTPUT);
digitalWrite(IRemitter,LOW);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
}
void loop() {
distance=readIR(5);
Serial.println(distance);
if(distance<400)
{digitalWrite(11,HIGH);
digitalWrite(12,LOW);
}
else
{digitalWrite(11,LOW);
digitalWrite(12,LOW);
}
}
int readIR(int times){
  for(int x=0; x<times; x++)
  { 
    digitalWrite(IRemitter,LOW);
    delay(1);
    ambientIR=analogRead(IRpin);
    digitalWrite(IRemitter,HIGH);
    delay(1);
    obstacleIR+analogRead(IRpin);
    value[x]=ambientIR-obstacleIR;
  }
  for(int x=0; x<times; x++)
  {
    distance+=value[x];
  }
  return(distance/times);
}

  It worked nice on the arduino, but when i wrote it for attiny 13, it doesnt work, one pin stays high and one pin low forever.

#define F_CPU 1200000UL
#include<avr/io.h>
#include<util/delay.h>
void adc_setup()    // adc setup function
{
    ADMUX|=(1<<MUX0);
    ADMUX|=(1<<REFS0);
    ADCSRA|=(1<<ADPS1)|(1<<ADPS0)|(1<<ADEN);
}
int adc_read()    // adc read function
{
    ADCSRA|=(1<<ADSC);
    while(ADCSRA&(1<<ADSC));
    return ADC;
}
int read_ir()    //Read IR by successive approximation
{    
    int value[5];
    int distance=0,i=0,j=0,aIR=0,oIR=0;
    
    for (i=0; i<5; i++)
    {    
        PORTB&=~(1<<PB0);    //IR Pin off to read IR from ambient
        _delay_ms(1);        // MInimum delay to read IR
        aIR=adc_read();        // aIR = ambient IR
        
        PORTB|=(1<<PB0);    // IR pin on
        _delay_ms(1);
        oIR=adc_read();        //object IR
        value[i]=aIR-oIR;
    }
        
    for (j=0; j<5; j++)
    {
        distance+=value[j];
    }    
    return(distance/5);
    
}
int main()
{
    DDRB|=(1<<PB3);        //pin(2), blue led
    DDRB|=(1<<PB0);        // pin(5), IR LED Pin 
    DDRB|=(1<<PB4);        // pin(4), green led
    adc_setup();
    int y=0;
    
    while(1)
    {
        y=read_ir();
        
        // if(y>0)
        {
        if(y>80)
        {
            PORTB|=(1<<PB3);
            PORTB&=~(1<<PB4);
            _delay_ms(5000);
            PORTB&=~(1<<PB3);
        }
        else 
        {
            PORTB|=(1<<PB4);
            _delay_ms(3000);
            PORTB&=~(1<<PB4);
            
        }
        }
    }
return 0;
}

i had once changed the condition to if(y<400) but the result was still same. If i uncomment the if(y>0) condition, then nothing happen, none of the led connected to the pins light up.

The delays used are according to its use in my project. I think something is wrong with the REFS0 bit. Someone please suggest the possible errors. :)

Last Edited: Fri. Sep 11, 2015 - 04:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TL;DR

 

(consider cutting that down to isolate what you believe the problem to be)

 

I'd also suggest that to debug this you also need some external method to be able to read the "y" value you are getting.

 

BTW why bother with the value[] array anyway. Why not just add the 5 readings into a "total" and then return "total / 5" as the average?

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

Im not a newbie to arduino because i got it when i was 15. Im 17 now. But still a newbie to using c for programming avr. I know c++. Is the F_CPU correctly defined ?

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

How can i see the value of y ? I cannot use a lcd because attiny 13a hasnt got so many pins.

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

Is y storing any negative value because for y>0 the pins are not becoming high.

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

Are you using a 12MHz crystal? Or the usual 16 MHz crystal used in an Arduino?

Ross McKenzie ValuSoft Melbourne Australia

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

I am running the tiny13 with its internal oscillator only. As much as i know, the internal oscillator frequwncy is 9.6 Mhz and it is already pre programmed with CKDIV8 fuse which means, i should write F_CPU as 1.2 Mhz. Is my calculation correct ?

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

Im new to this website. What does ADD TAGS help us to do ?

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

"> – 64 Bytes Internal SRAM

Hmmm--I guess you >>might<< be OK on SRAM with the code shown.  No globals and about 30 bytes of locals.

 

Many here seem to share your love of the Tiny13.  Myself, I like the elbow room and flexibility the Tiny25 family gives me.  For a one-off or if making a few, saving some pennies on each is not usually a critical factor.

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Would certainly appreciate using tiny 25 from the next time, but already hav 5 tiny 13's lying in the house. May be evrybody makes the same mistake ;)

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

Was this the right place to post the problem here ? Should i have posted it in projects ? Im new to the website :(

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

If A0 maps to ADC0, you can't use it as it is the /Reset pin on a tiny13!

Choose a different adc pin and see if it works!

 

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

Welcome to AVR Freaks!

 

Unfortunately, your post is very hard to follow, since your code looks exactly the same as your post comments, and has lost much of its indentation and formatting.  Please edit your post and avail yourself of the code editor.  It's on the right of the toolbar and looks like this:

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

It worked nice on the arduino, but when i wrote it for attiny 13, it doesnt work, one pin stays high and one pin low forever.

So, which pin is high and which is low?

 

Describe all your connections, including to the ADC input pin.

 

I always try to do a "sanity check".  In this case, I'd change the main loop code to e.g. blink the two LEDs in opposition, with maybe _delay_ms(1000) between.  That would say that the AVR is still continuing to run and the "about one second" would say that the AVR is really running at the speed you think it is.  (Example of the sanity:  if the AVR is really running at 1/8 the speed you think it is then the 5000ms delay would really be 40 seconds and you may not have waited that long.)

 

Whenever practical in my apps, if the design has a "power OK" or similar status LED, I like to keep it flashing at 1Hz at least during dev.  Then when new stuff is added and appears to be "not working" one can see whether things are still moving along in main loop and timer interrupt and such.

 

If the sanity check fails, then comment out the read IR routine and see if it works then.  I still think there is a possibility of stack overflow.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Was this the right place to post the problem here ? Should i have posted it in projects ?

Yes and No.

 

Moderator.

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

Here is the schematic i used. I see the analog pin is differently connected here. I followed the same pattern but why is it different than using LDR or pots?

I used adc1 i.e PB2 as the analog input in tiny 13. The pin PB3 always stays on.

Attachment(s): 

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

Here is the schematic i used.

Obviously, it is not the schematic of the app under discussion.

 

Did you do the "sanity tests" to ensure the LEDs are connected as you expect them to be?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Sorry i couldnt do it yet. But will do it in the next few hours and report as soon as possible.
Is there also a way to know the value of 'y' after 'y=read_ir()' ?

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

In answer to which question?

 

Is there also a way to know the value of 'y' after 'y=read_ir()' ?

Earlier I suggested:

 Many here seem to share your love of the Tiny13.  Myself, I like the elbow room and flexibility the Tiny25 family gives me. 

 Would certainly appreciate using tiny 25 from the next time, but already hav 5 tiny 13's lying in the house. May be evrybody makes the same mistake

So you chose to use one of the few AVR8 models without a debugging interface...   (but starting out you probably don't have a JTAGICE or equivalent anyway)

 

You could "log" write a few values or averages to EEPROM, then read them back with your ISP.

 

But first start with the sanity checks.  Are all LEDs really firing as you need them to?  What is the voltage on the ADC input pin?  Did you wait for a full minute for the LEDs to change?  If not, what do you get if you cut the 500ms and 3000ms down by a factor of 100?

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

No, the leds are not firing. I waited for a minute for the led to change but it didnt. It means the if (y>80) part is not getting executed and the else part is getting executed since the pin PB3 stays high and the LED connected to it only glows. I think the value of y is coming out to be negative or zero after average.

Last Edited: Sat. Sep 12, 2015 - 07:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Because any negative or zero value will not satisfy the condition (y>80) and the code wil go to the else part. when i uncomment the outer if(y>0), then none of the leds work. The led which was glowing before also doesnt glow. It surely means its not reading ADC

Last Edited: Sat. Sep 12, 2015 - 06:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Im not that experienced yet and i never wrote anything to eeprom before. Is there a tutorial for this ? Because i want to try it out then.

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

No, the leds are not firing. I waited for a minute for the led to change but it didnt. It means ...

No, we do not know that it means something yet -- until you show the schematic and confirm hardware operation with a "sanity test" program.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Will a hand drawn schematic be alright to submit ?

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

Yes if it is clear and not several megabytes in size... a .jpg or .png image is usually OK.

Ross McKenzie ValuSoft Melbourne Australia

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

I don't care if you just list all the pins and connections--as long as you have taken care to verify it is really connected in that fashion.

 

To me the important part is one of the sanity checks as alluded to above.

// assume active-low LEDs
#define PIN_GREEN PB4
#define PIN_BLUE PB2

#define BLUE_ON() (PORTB &= ~(1<<BLUE_PIN))
#define BLUE_OFF() (PORTB |= (1<<BLUE_PIN))

#define GREEN_ON() (PORTB &= ~(1<<GREEN_PIN))
#define GREEN_OFF() (PORTB |= (1<<GREEN_PIN))
...
while (1)
    {
        // "count" with the LEDs -- green is the "low bit"
        _delay_ms(500);
        GREEN_OFF();
        BLUE_OFF();
        
        _delay_ms(500);
        GREEN_ON();
        BLUE_OFF();
        
        _delay_ms(500);
        GREEN_OFF();
        BLUE_ON();
        
        _delay_ms(500);
        GREEN_ON();
        BLUE_ON();
        
    }

Once that succeeds, you know that the connections are good and the LEDs are good and you are really running your program and so forth.  A sanity check.

 

Then you start adding your app pieces one at a time and retest.  Preferably, IMO/IME, you keep one of the LEDs blinking at 1Hz...

 

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Sorry for the delay in work. Busy with a little bit of exam shedule, anyways, i fried my LM 7805 linear regulator. Can the tiny 13 run on 3.3v because i have plenty of zener diodes.

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

Sorry for the delayed response, i used the following code to test the that the avr is running at 1Mhz. A sanity check.

#define F_CPU 1200000UL

#include<avr/io.h>
#include<util/delay.h>

int main()
{
DDRB &= ~(1<<PB3);
DDRB &= ~(1<<PB4);

void BLUE_ON() 		//Function to turn on blue led
{
	PORTB&= ~(1<<PB3);
}
void BLUE_OFF() 	//Function to turn off blue led
{
	PORTB|= (1<<PB3);
}

void GREEN_ON() 	//Function to turn on green led
{
	PORTB&= ~(1<<PB4);
}
void GREEN_OFF() 	//Function to turn off green led
{
	PORTB|= (1<<PB4);
}

while (1)
    {
        // "count" with the LEDs -- green is the "low bit"
        _delay_ms(500);
        GREEN_OFF();
        BLUE_OFF();
        
        _delay_ms(500);
        GREEN_ON();
        BLUE_OFF();
        
        _delay_ms(500);
        GREEN_OFF();
        BLUE_ON();
        
        _delay_ms(500);
        GREEN_ON();
        BLUE_ON();
        
    }
return 0;
}

 

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

And the results of the sanity check?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Its not letting me upload a .mp4 file. I had taken the video of it working.

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

Anyways, #define F_CPU 1200000 yielded me blinking the green led at 1 sec. But the other led seemed slower, thats why wanted to show the results to you sir.
Since tiny 13 is preprogrammed with 9.6 mhz and also ckdiv8, i should write 1200000 for f_cpu.

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

Sir, just another question. If i give F_CPU, some other values other than F_cpu, will the avr not work?

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

SIr, pls suggest a way to send you the video.
500ms should give a delay of 1/2 a sec, but as much as i think, its a bit slower.

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

There's no real need to send a video of flashing leds!
Measure the flash rate - how many flashes per minute?
F_CPU can be any value you like, but it is used to calculate the delays. I would suggest your tiny13 is not running at 12MHz but somewhat slower. You can calculate the error based on how many flashes per minute you get vs what you expected.
If the default speed of the tiny13 9.6MHz?

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

Goodness Rudro... do you think that you could collect your thoughts and questions and put them in one post instead of "machine-gunning" us with 5 in 30 minutes...

 

Ross McKenzie ValuSoft Melbourne Australia

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

Kartman wrote:
I would suggest your tiny13 is not running at 12MHz but somewhat slower.
Uh... 1.2 MHz:

Rudro17 wrote:
Anyways, #define F_CPU 1200000 yielded me blinking the green led at 1 sec.

 

Quote:
If the default speed of the tiny13 9.6MHz?
That's the speed of the oscillator.  With CKDIV8, which is programmed by default, you get 1.2 MHz.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

...yielded me blinking the green led at 1 sec. But the other led seemed slower,...

? ???  What does that mean, slower?

 

You said yourself that GREEN is the low bit of your binary counter.  How often does the second bit change when you count

 

00

01

10

11

00

01

10

11

00

... ?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Sorry for the unclear previous reply. I figured that the green led blinks 8 times in 7 seconds, which is approximately is 1.1 blink every second. But the blue led blinked 4 times in 7 seconds. I still couldnt figure out, how to calculate delay from F_CPU. I defined F_CPU as 1200000, which means 1200000 clock cycles evry second, it therefore means (1/1200000) seconds per clock cycle. But how do i calculate that how much delay would _delay_ms(500) give me in case of F_CPU 1200000? It wouldnt be 500ms, it should be a little less than that.

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

What >>are<< you going on about?!?

 

Of course your code -- it was >>you<< that said that green is the low bit -- will have a period for the green LED that is 1/2 of that for the blue LED.  I even gave the counting sequence that demonstrated that.

 

And a 500ms delay SHOULD BE 500MS -- >>if<< you have stated F_CPU to reflect reality.

 

But now we see that the LEDs are connected as expected.  So now it is time to add some simple A/D with indication.  (As I mentioned, I'd keep one LED blinking.) The other to indicate ADC counts above/below a threshold using a pot.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

I think F_CPU doesnt affect the adc clock. We are using a prescalar to divide the internal clock, F_CPU is used for calculating the delays, as you said.

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

I think F_CPU doesnt affect the adc clock.

F_CPU is the frequency of the main clock.

Timers, Adc and all other parts use this clock.

The only exception is Watch dog timer which has its own oscillator.

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

A friend of mine recently made this and i worked for him. He used the same code, he used mega 8. So, i wired up my circuit wrongly. But i really didn't know so much about the delay and F_CPU and especially the sanity check method was very helpful.
Thanks to all who helped me.