The comparator on Arduino uno loses interrupts from time to time. Why ???
The comparator is connected as follows: (+) to pin6 and (-) to A0 by using MUX. When the constant Voltage on pin6 is greater or lesser than the linearly and periodicaly rising and falling signal on A0, then on pin2 we can generate 1, or 0. So, I can observe on the oscilloscope when we have rising and when falling edge of the interruption. In my opinion, the program is correct. So what is the reason of these loses ? xxx.ino (2.3 KB)
My code:
const int redLED = 8;
const int greenLED = 9;
int i,j;
///////////////////////////////////////////////////////////////////////////////////
void setup()
{
pinMode(redLED,OUTPUT); pinMode(greenLED,OUTPUT);
pinMode(A0,INPUT);
pinMode(6,INPUT);
pinMode(7,INPUT); // this pin is not in use here.
pinMode(2,INPUT);
// comparator on digital pin D6 (AIN0)
ACSR |= (1<<ACI);//B00010000; // Clear flag comparator interrupt (ACI bit to 1)
ACSR |= (1<<ACIE); // dodalem interupt enable, bez tego nie zadziala.
ACSR &= B11011111; // Set ACBG, to be equal "0"
ADCSRA &= ~(1 << ADEN); // Disable the ADC module because
ADCSRB |= (1 << ACME); // Enable the MUX selector for negative input of comparator
ADMUX = 0; // Select A0 as comparator negative input
ACSR |= B00000011; // Set interrupt on rising edge*/
ACSR &= ~(1<<ACIC); // input capture disabled
sei();
}
///////////////////////////////////////////////////////////////////////////////////
void loop()
{
}
//////////////////////////////////////////////////////////////////////////////////
ISR (ANALOG_COMP_vect) // Interrumption vector for the Analog comparator
{
if(ACSR & B00000010) //If we are into falling edge
{
if(!(ACSR & B00100000))//If ACO is 0 (we have that ! for inverse)
{ //A change from HIGH to LOW was detected
//Do what you want to do here..
digitalWrite(redLED, HIGH); digitalWrite(greenLED, LOW);
digitalWrite(2,LOW);
ACSR &= ~(1<<ACIE);
ACSR |= (1<<ACIS1) | (1<<ACIS0);// Remember top set back the interrupt on rising edge for next ISR
ACSR |= (1<<ACIE);
}
}
if(ACSR & B00000011) // if we are into rising edge
{
if((ACSR & B00100000)) //If ACO is 1
{ //A change from LOW to HIGH was detected
//Do what you want to do here...
digitalWrite(greenLED, HIGH); digitalWrite(redLED, LOW);
digitalWrite(2,HIGH);
ACSR &= ~(1<<ACIE);
ACSR |= (1<<ACIS1); ACSR &= ~(1<<ACIS0); // Remember set back interrupt on falling edge for next ISR
ACSR |= (1<<ACIE);
}
}
}
On the osciloscope I observe that some rising or falling changes of comparator output are not detected, though they should. I do not see reason of these detection lack.
Changes are periodical so it is easy to notice these lacks on the osciloscope.
Try this to see how it behaves. It ignores ACO and corrects a logic error
ISR (ANALOG_COMP_vect) // Interrumption vector for the Analog comparator
{
if(( ACSR & B00000011) == B00000010 ) //If we are into falling edge
{
// if(!(ACSR & B00100000))//If ACO is 0 (we have that ! for inverse)
{ //A change from HIGH to LOW was detected
//Do what you want to do here..
digitalWrite(redLED, HIGH); digitalWrite(greenLED, LOW);
digitalWrite(2,LOW);
ACSR &= ~(1<<ACIE);
ACSR |= (1<<ACIS1) | (1<<ACIS0);// Remember top set back the interrupt on rising edge for next ISR
ACSR |= (1<<ACIE);
}
}
else if(( ACSR & B00000011) == B00000011 ) // if we are into rising edge
{
// if((ACSR & B00100000)) //If ACO is 1
{ //A change from LOW to HIGH was detected
//Do what you want to do here...
digitalWrite(greenLED, HIGH); digitalWrite(redLED, LOW);
digitalWrite(2,HIGH);
ACSR &= ~(1<<ACIE);
ACSR |= (1<<ACIS1); ACSR &= ~(1<<ACIS0); // Remember set back interrupt on falling edge for next ISR
ACSR |= (1<<ACIE);
}
}
}
From here I assumed that it was partly working and simply that some changes were missed.
Now I am beginning to wonder if there is a something more fundamental and the ISR is not being called at all.
Do the red / green leds switch on even occasionally in response to your input ?
From where did you get the basic code sample you are working with ? Did you create it yourself from the data sheet or copy it from a web link ?
Code from ElectroNoobs (https://www.youtube.com/watch?v=0vRF8Ce9umE), adapted for my educational needs.
Yes LEDs work correctly. And you can even notice these lacks by observing carefully its blinking.