go_away

Author Topic: Help with a2d converter on atmega16  (Read 2074 times)

0 Members and 1 Guest are viewing this topic.

Offline NJSTopic starter

  • Beginner
  • *
  • Posts: 4
  • Helpful? 0
Help with a2d converter on atmega16
« on: February 02, 2011, 02:34:44 PM »
The current evolution of my year old $50 robot is maze navigation.  I want to use sharp IR sensors on the front and side of the robot to make it do right hand sweeps through a maze.  The problem is that I cannot for the life of me get a reliable signal out of the a2d converter.  I'm trying to set up a threshold voltage input to make the sensor act like a switch (so the robot doesn't have to physically touch the walls).  Here is some test code that I am using with an LED to indicate if I've met the threshold or not.  I've even added a small amount of capacitance to the IR sensor to help with noise (found this doing a search).

Code: [Select]
while(1)
{
  Front_IR=a2dConvert8bit(1);
   if (Front_IR > 95) {
   PORT_ON(PORTD, 4);
   }
   if (Front_IR < 95) {
   PORT_OFF(PORTD, 4);
   } 
        }

I am using an atmega16, so the a2d ports are on the A channel (pull up resistors are off) as opposed to the C channel for the atmega8 from the $50 robot tutorial.  My issue is that no matter what value I put into the test code (95 was the last one I tried).  The LED is either on, off, or randomly flashing.  The random flashing instances seem to have no relation to how far and object is placed in front of the sensor, I can understand some noise in the signal, but there is no correlation at all.  I have a volt meter connected and the IR sensor is correctly delivering a 0-3V signal to the input port on the chip depending on object distance.  My meter is older, but I am not seeing any significant noise in the signal from the IR sensor itself.  If I change the a2d port in the code to say port A3 (with nothing connected to it) I get a similar random flashing of the LED.

So what am I doing wrong?  I've actually gotten an IR sensor to work before and I never ran into this problem.

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,944
  • Helpful? 98
Re: Help with a2d converter on atmega16
« Reply #1 on: February 02, 2011, 02:55:00 PM »
The Sharp IR distance sensors do pull a large current when they pulse their LED. How are you powering them?
This may be what is causing the trouble.

I have used a separate 5V regulator to power the Sharps and added a largish, 10uF, cap right on the connector pins on the Sharp module.

I don't use Atmega but I would put a delay in the while loop so that the ADC is not read too often.
Someone else should give you help with the code.

Offline NJSTopic starter

  • Beginner
  • *
  • Posts: 4
  • Helpful? 0
Re: Help with a2d converter on atmega16
« Reply #2 on: February 02, 2011, 03:34:57 PM »
My test set up is an old battery charger rated at 5vdc and 1amp, I have a 220 uF capacitor wire into the power output of the charger as well.  This feeds the chip and the IR sensor, my meter indicates very stable 5.021 vdc power being supplied to the chip and IR sensor.   I don't think power is an issue, but I will make sure there are separate battery packs on the robot once I get that far.  Thanks for pointing that out.

I've added a delay to the a2d conversion, but it hasn't really helped me glean any additional useful information.  Other then I think there must be some issue with scaling and or code for my a2d conversion.


Offline hopslink

  • Robot Overlord
  • ****
  • Posts: 202
  • Helpful? 14
Re: Help with a2d converter on atmega16
« Reply #3 on: February 02, 2011, 04:15:55 PM »
...Other then I think there must be some issue with scaling and or code for my a2d conversion.

It sounds like this could well be the case. Try replacing the sensor with a known stable source like a potentiometer or potential divider. If you are still seeing the same behaviour it points to a code issue, as a guess probably somthing hinky in the configuration of the ADC.

Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,944
  • Helpful? 98
Re: Help with a2d converter on atmega16
« Reply #4 on: February 02, 2011, 05:27:51 PM »
Check using a pot as NJS suggests is a good test to see if its the Sharp causing problems. Do unplug the Sharp so it doesn't get power.

Quote
my meter indicates very stable 5.021 vdc power being supplied to the chip and IR sensor

The Noise caused by the Sharp can not be seen on a meter. You must use an O-scope as it is 1usec voltage dip every 200usec.
A meter will average this fluctuation and the voltage will look steady but the ADC will see it.

Offline NJSTopic starter

  • Beginner
  • *
  • Posts: 4
  • Helpful? 0
Re: Help with a2d converter on atmega16
« Reply #5 on: February 02, 2011, 10:01:35 PM »
I built a voltage divider and when I deliver 3-4.5 VDC to the a2d pin I still get the same full range of totally random LED flashing.  Voltage divider was powered with 3 AA with a capacitor to minimize voltage fluctuations, so I'm sure the a2d pin was getting a very clean signal. 

That leaves me with a coding issue, and I'm totally clueless as to what the issue is.  I tried this before and it was just plug and play, must be something simple.  If anyone has any ideas on what (if any) changes need to be made to swap the a2d code from an atmega8 to an atmega16 that might help.

Offline NJSTopic starter

  • Beginner
  • *
  • Posts: 4
  • Helpful? 0
Re: Help with a2d converter on atmega16
« Reply #6 on: February 04, 2011, 01:40:13 AM »
I ended up writing my own code, I'm not sure why the stock $50 robot stuff didn't work for me.  Here is what I came up with if anyone is curious, two a2d channels that flash LEDs.  Also, it was my first real crack at writing code so if anyone has optimization suggestions let me know!

Code: [Select]
//*********AVR LIBRARIES TO LOAD*********
#include <avr/io.h>     // include I/O definitions (port names, pin names, etc)
#include <avr/interrupt.h> // include interrupt support

//*********DEFINE PORT FUNCTIONS*********
#define PORT_ON( port_letter, number ) port_letter |= (1<<number)
#define PORT_OFF( port_letter, number ) port_letter &= ~(1<<number)
#define PORT_ALL_ON( port_letter, number ) port_letter |= (number)
#define PORT_ALL_OFF( port_letter, number ) port_letter &= ~(number)
#define FLIP_PORT( port_letter, number ) port_letter ^= (1<<number)
#define PORT_IS_ON( port_letter, number ) ( port_letter & (1<<number) )
#define PORT_IS_OFF( port_letter, number ) !( port_letter & (1<<number) )

#define BV(bit) (1<<(bit))
#define cbi(reg,bit) reg &= ~(BV(bit))
#define sbi(reg,bit) reg |= (BV(bit))

//*********SOME VARIABLES***************
int Front_IR=0; //front IR sensor
int Side_IR=0;  //side IR sensor

//*******THIS IS THE CORE PROGRAM********
int main (void)
{
//PORT CONFIGURATION
    DDRD = 0xFF;  //configure all D ports for output

//A2D CONFIGURATION
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Set ADC prescalar to 128 - 125KHz sample rate @ 16MHz
ADMUX |= (1 << REFS0); // Set ADC reference to AVCC
ADMUX |= (1 << ADLAR); // Left adjust ADC result to allow easy 8 bit reading
ADCSRA |= (1 << ADEN);  // Enable ADC
    cbi(ADCSR, ADFR);       // default to single sample convert mode
//ADCSRA |= (1 << ADFR);  // Set ADC to Free-Running Mode

   

    for(;;)  // Loop Forever
    {
//get Front_IR data from front sensor
cbi(ADMUX, MUX2);cbi(ADMUX, MUX1); cbi(ADMUX, MUX0); //set a2d ch 0
sbi(ADCSR, ADIF);  //clear hardware "conversion complete" flag
sbi(ADCSR, ADSC);  //start conversion
while( bit_is_set(ADCSR, ADSC) ); //wait for conversion to be done, patience grasshopper
Front_IR=ADCH;

//get Side_IR data from front sensor
cbi(ADMUX, MUX2);cbi(ADMUX, MUX1); sbi(ADMUX, MUX0); //set a2d ch 1
sbi(ADCSR, ADIF);  //clear hardware "conversion complete" flag
sbi(ADCSR, ADSC);  //start conversion
while( bit_is_set(ADCSR, ADSC) ); //wait for conversion to be done, patience grasshopper
Side_IR=ADCH;
   
    if(Front_IR > 112) //195 is ~3.8v on you voltage divider
    {
PORT_ON(PORTD, 4);
      }
      else
      {
PORT_OFF(PORTD, 4);
      }
    if(Side_IR > 195) //195 is ~3.8v on you voltage divider
    {
PORT_ON(PORTD, 5);
      }
      else
      {
PORT_OFF(PORTD, 5);
      }
 
    }  //end infinite if loop
}  //end main

 


Get Your Ad Here

data_list