Go Down

Topic: Analog Sensor with attachInterrupt() (Read 2247 times) previous topic - next topic

atatistcheff

Hi,

I recently bought an analog IR line sensor from Sparkfun http://www.sparkfun.com/products/9453.  I didn't really have a plan for it but now I'd like to try making a wheel encoder for a robot.  I printed out an alternating black/white encoder pattern and attached it to one of the robot wheels.  The sensor picks up the difference in colors which is good.  However, to use this to actually count every pulse I need to use the attachInterrup() function.  Problem is, that only works on the interrupt pins which are digital. 

So I have an analog sensor returning values on the analog pins of ~40 for black and >200 for white.  What I need is to convert that signal to HIGH or LOW for digital pin 2.  Sounds like I need some external components to force these signals all the way HIGH or LOW so the digital state will change.  Of course the other alternative is to buy a digital output IR sensor but I'm hoping I can get something working with the parts I have. 

Any thoughts would be appreciated!

RuggedCircuits

Values of 40 and 200 map to voltages of 0.2V and 1V respectively (assuming a 5V reference) so you're right that they won't work for a digital signal.

Perhaps you can use the analog comparator peripheral, or an external analog comparator. On an Uno, for example, pins D6 and D7 can also be connected to the analog comparator. You can read about it in Section 22 of the ATmega328P datasheet.

You would need an external voltage divider to set a threshold of about 0.6V (halfway between 0.2V and 1V) on one of the analog comparator pins then connect your IR sensor on the other pin.

I don't think there are any Arduino library functions for working with the built-in comparator so you'll have to do it at the register level.

--
The Gadget Shield: accelerometer, RGB LED, IR transmit/receive, speaker, microphone, light sensor, potentiometer, pushbuttons

atatistcheff

Thanks for the quick reply. 

I did throw a meter on the sensor output and sure enough it varies between about .2v and 1.5v.  Using the built in comparator looks intriguing but I've only been using the Arduino for a couple of months and I think accessing the register values is a bit beyond me at this point.  I'll probably just pick up a digital output IR sensor next time I order parts. 

atatistcheff

Ok I spoke too soon.  I found a post in the old forum where someone wanted to do almost the same thing.  He was kind enough to post the register code when he got it working and it works for me too.

All I did was put a .6v reference on pin 6 then feed my analog input into pin 7.  The code below works to increment my encoder value when the wheel spins.  Totally cool!
[font=Courier]
volatile unsigned int encoderPos = 0;

void setup() {               
ACSR =
  (0<<ACD) |   // Analog Comparator: Enabled
  (0<<ACBG) |   // Analog Comparator Bandgap Select: AIN0 is applied to the positive input
  (0<<ACO) |   // Analog Comparator Output: Off
  (1<<ACI) |   // Analog Comparator Interrupt Flag: Clear Pending Interrupt
  (1<<ACIE) |   // Analog Comparator Interrupt: Enabled
  (0<<ACIC) |   // Analog Comparator Input Capture: Disabled
  (1<<ACIS1) | (1<ACIS0);   // Analog Comparator Interrupt Mode: Comparator Interrupt on Rising Output Edge 
 
  Serial.begin(57600);
}

void loop() {

  Serial.print("encoderPos=");
  Serial.println(encoderPos);

  delay(300); 
 
}
 
ISR(ANALOG_COMP_vect)
{
  // This is the interrupt handler
  encoderPos++;
  if (encoderPos > 32000) encoderPos=1;
}


[/font]

Arnonh

good example for use of the analog comparator
I Think you should add this code snippet to the playground

Go Up