I want to count pulses generated from a PWM pin on my Photon, so I’m feeding the PWM out to a second GPIO, and attaching an interrupt to that second pin. When the interrupt is triggered, it updates a counter.
This seems to work, other than I’m getting twice as many interrupts as I’d expect when setting attachInterrupt to RISING or FALLING (or at least my service routine’s running twice as many times as I’d expect). So, for example, if I’m using 1000 Hz to set the PWM output, the interrupt seems to be triggered 2000 times per second for RISING or FALLING mode. Seems to be exactly 2000 times, so not a standard noise issue. If I switch interrupt mode to CHANGE, then… I still get 2000 interrupts per second, which is correct, but I’d expect 4000 if it were consistent with RISING and FALLING modes.
The PWM signal looks lovely on my oscilloscope, not noisy.
I’ve tried using two different GPIOs (5 and 1) for this pulse-counting scheme, same results.
Thanks in advance for any help!
Strange. You should post your code so that we can completely understand what you’re trying to do.
Also, I should mention that the timers that drive the PWM output already have counters attached to them so that interrupts can be thrown when the counter register matches a certain value. Might be worth looking into.
1 Like
Thanks. Relevant code, I think, below. Would appreciate a pointer to how I can capture the interrupts when the counter match a value if you know offhand, otherwise I’ll (re-)read the docs.
//Assign GPIO numbers
int mot_step = 2;
int mot_dir = 3;
int testOut1 = 4; //toggles at half the freq of mot_step - just a test, can be used for something else
int stepCountIn = 1; //triggers an irq whenever a step is made to keep a count of steps
...
//setup GPIO pins
pinMode(mot_dir, OUTPUT);
digitalWrite(mot_dir, dir_proximal);
pinMode(mot_step, OUTPUT);
digitalWrite(mot_step, HIGH);
pinMode(testOut1, OUTPUT);
digitalWrite(testOut1, HIGH);
pinMode(stepCountIn, INPUT);
attachInterrupt(stepCountIn, incrSteps, FALLING );
...
void incrSteps()
{
if (dir_proximal)
{
stepCount--;
}
else
{
stepCount++;
}
testOutState = !testOutState;
digitalWrite(testOut1, testOutState);
}
}
An important bit is missing tho'
How does your analogWrite()
call look?
I can't exactly replicate your issue.
This is the code I tested with and I do get the exepcted 1000 triggers per second at 1000Hz PWM frequency (even going up to 65535Hz it works as expected - despite a slight miscount due to millis()
inaccuracy)
const int pinPWM = D0;
const int pinINT = D1;
const int pinDBG = D2;
volatile uint32_t count;
void setup() {
pinMode(pinPWM, OUTPUT);
pinMode(pinDBG, OUTPUT);
pinMode(pinINT, INPUT);
attachInterrupt(pinINT, isr, RISING);
analogWrite(pinPWM, 100, 1000);
}
void loop() {
static uint32_t ms = millis();
if (millis() - ms < 1000) return;
uint32_t c = count;
count = 0;
ms = millis();
Serial.printlnf("pulses during last second %u", c);
}
void isr() {
count++;
pinSetFast(pinDBG);
delayMicroseconds(5);
pinResetFast(pinDBG);
}
What device OS version are you running again?
BTW, we prefer the pin labels over anonymous pin numbers.
1 Like
BTW, you have a stray }
in your ISR.
1 Like
Unfortunately, the stray } was a copy/paste goof on my part.
I ran your code as-is, and got interesting results, below. I suspect I’m doing something fundamentally dumb. Any thoughts are appreciated!
Ok… as it happens, I have a spare Photon. I substituted it into the same circuit, and it works properly. So, bad device? I’ll take another look at the circuit tomorrow, I had checked that output loading and so forth was OK before I wired it up but maybe I’m missing something.
That’s a surprise - but sure, a HW issue would explain that.
Maybe something for support.particle.io
1 Like
Ha! Found the problem, it is my circuit. The pwm output is feeding into a control pin for a device whose inputs are not well-specified on its datasheet, and I’m seeing a very fast but high-amplitude ringing that’s causing an unwanted irq to trigger on either edge.
Now I have to go play electrical engineer to fix, but I now know what to fix. Thanks a lot for helping me to poke in the right direction!