Society of Robots - Robot Forum

Software => Software => Topic started by: ethought on March 07, 2010, 08:55:32 AM

Title: Simple C question - Combine 2 Bytes from AVR
Post by: ethought on March 07, 2010, 08:55:32 AM
Hi all -

A simple question I think.

Trying to get values for an analog sensor.

Using a Sharp IR analogue range sensor with an Atmega8.

At the moment I am only checking the ADCH value. But there are 2 bits returned ADCL and ADCH.

The question is how do I combine these into an integer?

Code: [Select]
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>

int set_PORTD_bit(int position, int value);

int main (void)
{
   DDRD = 0x03; // Set LED1 as output

   //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

   // No MUX values needed to be changed to use ADC0

   ADCSRA |= (1 << ADFR);  // Set ADC to Free-Running Mode
   ADCSRA |= (1 << ADEN);  // Enable ADC
   ADCSRA |= (1 << ADSC);  // Start A2D Conversions


   for(;;)  // Loop Forever
   {

// bits are ADCL and ADCH

      if(ADCH < 140)

      {
set_PORTD_bit(0,0);
set_PORTD_bit(1,0);
      }
      else
      {
                set_PORTD_bit(0,1);
                _delay_ms(50);
                set_PORTD_bit(0,0);
                _delay_ms(50);

                /// LED 2
                set_PORTD_bit(1,1);
                _delay_ms(50);
                set_PORTD_bit(1,0);
                _delay_ms(50);
      }
    }
}

int set_PORTD_bit(int position, int value)
{
  // Sets or clears the bit in position 'position'
  // either high or low (1 or 0) to match 'value'.
  // Leaves all other bits in PORTB unchanged.

  if (value == 0)
  {
    PORTD &= ~(1 << position);      // Set bit position low
  }
  else
  {
    PORTD |= (1 << position);       // Set high, leave others alone
  }

  return 1;
}

Thanks
Title: Re: Simple C question - Combine 2 Bytes from AVR
Post by: Razor Concepts on March 07, 2010, 09:42:12 AM
There are many ways to do this, it is easiest when you just think about each bit.

I was thinking you OR the ADCH into the lower 8 bits of a 16 bit integer (uint_16), shift those up 8, then OR the ADCL into the lower 8 bits again and you should have an integer.

Additionally you can take a peek at where the a2dConvert10bit() command is, there is a simple way that Admin converts them into an integer but I forgot how he did it.
Title: Re: Simple C question - Combine 2 Bytes from AVR
Post by: Hasan999 on March 07, 2010, 10:21:14 AM
Not 100% sure, but try including the Sensor.c file first:

Code: [Select]
#include "sensors.c"

That contains the configuration for Sharp IR Range sensor..

To detect the range, use:

Code: [Select]
int range = sharp_IR_interpret_GP2D12(a2dConvert8bit(7));

where, 'range' will give the distance in cm, and '7' is the analogue port that has the sensor plugged in.

Title: Re: Simple C question - Combine 2 Bytes from AVR
Post by: ethought on March 07, 2010, 11:00:15 AM
Tried with this:

Code: [Select]
voltage_int = ADCL;
voltage_int  += (ADCH << 8);

Seems to be much more accurate now but still not really reliable... (I have no serial connection so cannot see the actual integers being generated).

I will also try the sensors.c include. Thanks
Title: Re: Simple C question - Combine 2 Bytes from AVR
Post by: Razor Concepts on March 07, 2010, 11:36:19 AM
Did you put a capacitor (10uF generally works well) across the sharp's power and ground?
Title: Re: Simple C question - Combine 2 Bytes from AVR
Post by: ethought on March 08, 2010, 03:55:25 AM
No, I have not tried with a capacitor. I will try that. Thanks for the tip!
Title: Re: Simple C question - Combine 2 Bytes from AVR
Post by: Webbot on March 08, 2010, 07:46:07 PM
Also that black plastic looking case is actually a conductor. Try to make sure it is connected to ground as well.