Hi Everyone,
First post here, and I'd like to start by saying thanks to Felix for his excellent work in the open source community!!
I'm trying to figure out how to modify the RFM69 library code to change the interrupt pin from int0 to int1 for compatibility with another library. I changed the definition in RFM69.h from:
#define RF69_IRQ_PIN 2
to:
#define RF69_IRQ_PIN 3
After doing this it still functioned normally with RFM69 interrupt line connected to pin 2, but when I connected it to pin 3 it stopped working. I then changed the definition to a random number and it stopped working with interrupt connected to pin 2... so appears that definition can be either 2 or 3 and it will work with interrupt line connected to pin 2 but doesn't work with interrupt line connected to pin 3.
Any suggestions?
Thanks!
Erik, thanks for the kind feedback!
The pin definition is usef to match the interrupt number. Unfortunately on AVRs the pin number associated with the interrupt is different than the interrupt number itself. So that header file directive is only used to remember what pin the actual interrupt is on, for pinMode() purposes.
You will need to change the hardcoded interrupt # in the .cpp file, look for this line and change first param from 0 to 1 :
attachInterrupt(1, RFM69::isr0, RISING);
And keep the pin set to 3:
#define RF69_IRQ_PIN 3
Thanks Felix!
Is there also a way the library could be updated to support pin change interrupts as well? I have a project where INT0 and INT1 are already in use and really wanted to use Felix's awesome library for an RFM69C I'll be using.
My project is already using the helpful PinChangeInt library (http://playground.arduino.cc/Main/PinChangeInt) and it is working fine, but I have not been able to integrate it with RFM69.
I modified the RFM69 library to expose the interruptHandler method and removed the attachInterrupt call from the initialize method. I then made a test project and tried using the pin change library to handle an interrupt on A0 but no success. I even tried setting the pin change registers without the library to setup an interrupt on A0 but still no luck. I can use the normal "attachInterrupt" call in my test project to call my own handler which then calls the RFM69's interruptHandler method, but that's the only configuration that works.
void setup() {
// This approach works after removing this call from the RFM69 initialize and making its interruptHandler method public.
attachInterrupt(0, &testHandler, RISING);
// Not working
// PCintPort::attachInterrupt(A0, &testHandler, RISING);
}
void testHandler() {radio.interruptHandler();}
// Also not working (this is a manual setup of A0 for pin change interrupts...though I don't have logic for only changing on RISING edges which may be causing the problem. I'll probably try this next.
void setup() {
pinMode(A0, INPUT);
PCICR |= (1 << PCIE1);
PCMSK1 |= (1 << PCINT8);
interrupts();
}
ISR(PCINT1_vect) {radio.interruptHandler();}
The RFM radios use a hardware interrupt, of which there are only 2 on the Atmega328.
I haven't tried to use it with a regular digital pin so I do not know if it will work.
Thanks and I can now confirm it works great with the pin change interrupts. The issue was a digitalRead within the sendFrame method which looked for _interruptPin to go high.
while (digitalRead(_interruptPin) == 0); //wait for DIO0 to turn HIGH signalling transmission finish
So one more tweak was need, simply exposing _interruptPin so it could be changed. After this last change the library can now use any pin for the DIO0 pin.
In setup to use pin A0:
radio._interruptPin = A0;
PCintPort::attachInterrupt(A0, &testHandler, RISING);
And the handler simply calls the RFM69's handler:
void testHandler() {radio.interruptHandler();}
I'll probably work on adding the PinChangeInt library directly to my copy of RFM69.cpp and update the initialize method to accept an optional pin to use for the interrupt pin, so one could do:
radio.initialize(FREQUENCY, NODEID, NETWORKID, A0)
Thanks again for the help and this great library!
Seems that with changes in the lib more has to be done in RFM69.h now (line 39ff):
#define RF69_IRQ_PIN 2
#define RF69_IRQ_NUM 0
Now RF69_IRQ_NUM is there also.
Is it sufficient to change this to 3 and 1 in case I want use D3 instead of D2?
Quote from: Clemens on February 18, 2015, 05:58:07 PM
Is it sufficient to change this to 3 and 1 in case I want use D3 instead of D2?
Yes
Btw. RFM69 is also working with the lib on the Arduino Yun, pin and interrupt allocation is a bit switch to the common boards, so doublecheck this for mismatch something is not working.
You find the interrupt-pin alignment under
http://arduino.cc/en/Main/arduinoBoardYun -> External Interrupts
http://jeelabs.net/boards/7/topics/5984?r=5987#message-5987
Wiring at http://openenergymonitor.blogspot.de/2012/06/arduino-leonardo-atmega32u4-and-rfm12b.html
In the end it's working e.g. with
#define RF69_IRQ_PIN 3
#define RF69_IRQ_NUM 0