Search This Blog

Tuesday, 27 May 2014

Arduino: User Error -- AIN0 *IS NOT* A0

I am revisiting my code for the OSLRF01  Open Source Laser Range Finder, as the thought occurred to me that I should be using the ATmega built-in Analog Comparator to determine the rise time of the return pulse.  

I will outline the new code in an upcoming post, however.....


This post is about my failure to clearly RTFM:

In this case, it would be the  Atmel 8bit Microcontroller Datasheet specifically Section 22 on the Analog Comparator (Page 246) and Table 13-9 on page 88:

So let me state a simple fact that I ignored:

AVR digital pins AIN0 (D6), and AIN1 (D7) are NOT the same as AVR Analog pins A0 and A1.


Nick Gammon has this simple diagram on his site for using the AVR Analog Comparator, that I've looked at a dozen times:


It Clearly shows AIN0 and AIN1 associated with Digital pin D6 and D7 respectively.    Yet I continued to try using A0 as my reference voltage, and A1 as the incoming analog signal.   

 I mean *Why on god's green earth would I compare analog signals on digital pins, right?*

It was only by chance that I was reading a similarly puzzled users question on the Arduino Forum: 


Quote
It is possible to select any of the ADC7..0 pins to replace the negative input to the Analog Com-
parator. .....
 If ACME is cleared or ADEN is set, AIN1 is applied to the negative input to the Analog
Comparator.
A0 and A1  are not the same as AIN0 and AIN1.
Quote
PC1 (ADC1/PCINT9) pin  and PC0 (ADC0/PCINT8)
PCINT23 /AIN1 - pin D7  and PCINT22/OC0A/AIN0 - pin D6)
There is "working" example:
Code:
//Configure Analog Comparator, Video Input Capture
  ADCSRB &= ~(1<<ACME);
  ACSR   &= ~(1<<ACD) ;           // Analog Comparator disable off
  ACSR   |=  (1<<ACIC);

  ACSR   |=  (1<<ACIS1);          // comparator detection edge
  ACSR   |=  (1<<ACIS0);          //** 10 - falling, 11- rising:  ACSR &= ~(1<<ACIS0)
  DIDR1  |=  (1<< AIN0D);         // disable digital input buffer AIN0/1
  DIDR1  |=  (1<< AIN1D);
Digital pins 6 and 7 as comparator inputs.
BTW, should you clear a flag after printing?

<Insert the sound of a hard forehead smack here>








References:
http://www.arduino.cc/en/Reference/PortManipulation
http://www.billporter.info/2010/08/18/ready-set-oscillate-the-fastest-way-to-change-arduino-pins/
https://github.com/projectgus/digitalIOPerformance
digitalWriteFast, digitalReadFast, pinModeFast etc  <--- needs to be updated for Arduino 1.0+
https://code.google.com/p/digitalwritefast/downloads/list  <--- needs to be updated for Arduino 1.0+
http://www.lightware.co.za/shop/en/laser-sensors/24-oslrf-01.html
http://arduino.cc/en/Hacking/Atmega168Hardware
https://github.com/TMuel1123/Arduino/blob/master/FastPins/FastPins.h <--  this one looks promising but needs the pins mapped...
http://tmuel1123.blogspot.ca/2014/01/fastpinsh-or-way-to-realize-really-fast.html
http://forum.arduino.cc/index.php/topic,94534.0.html
http://www.avr-tutorials.com/comparator/utilizing-avr-analog-comparator-aco
http://www.avr-tutorials.com/sites/default/files/ATMega8515%20Analog%20Comparator_1.pdf