Is there a way to duplicate the function of a hardware interrupt, pins int0/int1(digital pins 2/3) on other pins on the 328.
I know PWM can be "simulated" on non PWM pins and analog pins can be digital pins, Is there a similar way to "convert" a digital pin in software to function as an interrupt pin.
The simple answer is yes, every analogue or digital pin can generate an interrupt.
They are not quite as convenient as INT0 & INT1.
Each pin has a dedicated interrupt service routine that is called when the corresponding pin changes.
There are only three "Pin Change" interrupts for all the input & output pins. Each pin change interrupt can be triggered by upto 8 pins.
The mapping is roughly:
PCI0 will be triggered by pins in Port B (Arduino pins 8 to 13)
PCI1 will be triggered by pins in Port C (Arduino pins Analog 0 to 5 & Reset)
PCI2 will be triggered by pins in Port D (Arduino pins 0 to 7)
If you look in Section 12. External Interrupts, it explains:
The External Interrupts are triggered by the INT0 and INT1 pins or any of the PCINT23...0 pins. ... The pin change interrupt PCI2 will trigger if any enabled PCINT23...16 pin toggles. The pin change interrupt PCI1 will trigger if any enabled PCINT14...8 pin toggles. The pin change interrupt PCI0 will trigger if any enabled PCINT7...0 pin toggles.
Section 11. Interrupts, explains the names of the interrupt routines.
So, when you arrive in the interrupt routine for e.g. PCI0, it can be triggered by upto 8 pins, and you'll have to write a little bit of code to figure out which. Of course, if only one pin is set up to generate an interrupt, then there is only one pin to look at.
My conundrum for my project is I have to measure four pulse sources, currently I have one on d2(int0) and one on d4(int1) I need two more. which is why I was looking for a "soft" interrupt.
I have to be careful in mucking about because I also have serial data back and forth (on d0,d1), pwm on 4 pins(d5,d6,d10,d11) and several addressables running on the I2C bus on pins a4 and a5.
EDIT: So upon further review, the clear answer is not with out mucking up a bunch of other stuff already using timers and interrupts.
Prolly goinng to move to some other hybrid answer from here.
Worked like a charm, Grumpy_mike, thanks, that was exactly what I was looking for.
One note I experienced in using your Pin Change Interrupt call
PCattachInterrupt(7, rpm_fun01, CHANGE);
Versus the original hardware interrupt call
attachInterrupt(0, rpm_fun, RISING);
Is that it doubled my resulting rpm from the following equation
if (rpmcount >= 20) {
//Update RPM every 20 counts, increase this for better RPM resolution,
//decrease for faster update
rpm = 30*1000/(millis() - timeold)*rpmcount;
timeold = millis();
rpmcount = 0;
Serial.println(rpm,DEC);
}
Output from Hardware Interrupt was 1200 rpm
Output from Pin Change Interrupt was 2400 rpm
I know this is because the CHANGE state measures both the switch from high to low and the switch back from low to high as a trigger each where the RISING call only triggers on the low to high switch.
I thought Id just mention it if anyone else doesn't catch it reading this in the future because the first version only supports CHANGE and not RISING and FALLING.
Thanks again for your help, I was this close <-> to switching to a much more complex I2C answer.