Im working with a sparkfun encoder, which also has red and green LEDs. Ive got my rotary encoder stuff working perfectly, the problem is when I call analogWrite to power the LED, I start missing Interrupts and my encoder goes screwy. Originally I had my LEDs plugged in to pins 5 and 6, but I figured the PWM timer on PORTD must be causing the encoder issues. I switched the two LEDs to pins 9 and 10 to get them on a different port, but analogWrite is still screwing with the way my pin interrupts. Is there anyway to use the arduinos PWM outputs with out the timers effecting the pin interrupts?
Are you using delay() ?
no
Try posting your code, it might be obvious what is wrong with it.
So like I said the encoder works 100% as it should, until i use an analogWrite in voidMain, when I use the PWM pins 5,6 which are also in potrD along with the encoder things tend to get really messed up. Now that I have switched the PWM to pins 9 and 10 in portB every so many clicks the encoder counts up twice instead of once. I do not have this problem using any other commands in void main besides analogWrite
void setup() {
Serial.begin(9600);
DDRD &= ~(1 << 3);
DDRD &= ~(1 << 4);
DDRB |= (1 << 9);
DDRB |= (1 << 10);
attachInterrupt(1, ISR_A, CHANGE);
}
void loop(){
analogWrite(9, 200);
analogWrite(10, 150);
}
void ISR_A(){
delay(10);
if (digitalRead(3) == digitalRead(4))
{
encoder0Pos++;
}
else
{
encoder0Pos--;
}
Serial.println (encoder0Pos, DEC);
}
the only thing I can even think of is to set up the PWM using standard AVR registers and port manipulation instead of analog write. Ive been having a hard time figuring out the timers though.
I thought you said that you were not using delay(). There it is in your ISR where it will not work anyway because interrupts are disabled automatically and delay() depends on them. You have not posted all of your code so I can't see whether encoder0Pos is declared volatile, which it should be as you are changing its value in the ISR.
Using serial from within a ISR is another NO NO.
Mark
Any attempt to use delay() or Serial IO in an ISR will hang the entire system.
There is no reason for PWM to affect interrupts at all.
Its possible you could have hardware issues with the LED outputs inducing
pulses on the interrupt inputs - this would have been my first thought
until I saw the code.
Im sorry im not acually using the delay, I threw that in there to see if it would help which it didnt, But the issue happens with or without the delay in the ISR, it made no difference.
volatile unsigned int encoder0Pos=0;
void setup() {
Serial.begin(9600);
DDRD &= ~(1 << 3);
DDRD &= ~(1 << 4);
DDRB |= (1 << 9);
DDRB |= (1 << 10);
attachInterrupt(1, ISR_A, CHANGE);
}
void loop(){
analogWrite(9, 200);
analogWrite(10, 150);
}
void ISR_A(){
if (digitalRead(3) == digitalRead(4))
{
encoder0Pos++;
}
else
{
encoder0Pos--;
}
Serial.println (encoder0Pos, DEC);
}
Now I know you guys said the serial call can screw up the ISR, but like I said the ISR works perfect with any code Ive tested in void_main, except analog write. The glitches (which are mostly extra encoder counts) got better (but didnt end) when I moved the PEMed, LEDS from pins 5/6 to pins 9/10 which would explain capacities coupling issues. What can I do to fix that?
I left the code the same but physically unplugged the LEDs and everything went smooth again. Theres decoupling caps on the interupt pins Im not sure what else to do, decouple the LEDs?
You have a power problem. Use small LED's or bigger current limiting resistors. Or change your power arrangements.
Mark
well my current limiting resistors are set up to let the LEDs in the encoder draw 30mA which is there max current, and 10mA below the atMegas328's current limit. Im guessing between the higher current pulses and the 6 inch wires to the breadboad Im getting current spikes coupled in to the encoder inputs. I just added .1uf caps right next to the LEDs and everything was smoothed out. ![]()
Its really hard to figure out if problems are hardware or software related. The weird thing is the encoder originally bounced really bad so added a 100hz RC filter to it to take care of the bouncing, I would have thought this would block out any captive noise?