sui77 / rc-switch

Arduino lib to operate 433/315Mhz devices like power outlet sockets.
1.89k stars 651 forks source link

A modest proposal - expose the interrupt so a user can write a callback function. #495

Open TheDougMiester opened 9 months ago

TheDougMiester commented 9 months ago

First let me say I love your work - this library saved the day for me. That said, I'd like to propose a very minor improvement. I'm not the sort of guy who just complains about something without offering a solution, so I've attached one. Here's the deal:

I recently had program which had a ton of "delay" calls in it. Sad, but necessary for reasons I don't think are worth going into. The result was "loop()" wasn't very timely in catching and processing calls to "if (mySwitch.available())". So, I needed to get access to RCSwitch's handleInterrupt call. It works pretty well, so I'd like to propose it as a new feature to an already excellent library. I'll attach the files, but here's the gist of it:

  1. In RCSwitch, just below the other enableReceive() declarations, add one more (line 86): void enableReceive(int interrupt, void (*ptrToFunction)(void));

  2. In RCSwitch.h at around line 158, make the following changes (lines 162 and 163 are new, the rest is already there):

    if not defined( RCSwitchDisableReceiving )

    static void handleInterrupt(); static bool receiveProtocol(const int p, unsigned int changeCount); int nReceiverInterrupt; static bool functionPtrExists; //NEW LINE static void (*externalFunctionPtr)(void); //NEW LINE

    endif

  3. In RCSwitch.cpp, change the declaration of RCSwitch:RCSwitch() to read as follows: RCSwitch::RCSwitch() { this->nTransmitterPin = -1; this->setRepeatTransmit(10); this->setProtocol(1);

    if not defined( RCSwitchDisableReceiving )

    this->nReceiverInterrupt = -1; this->setReceiveTolerance(60); RCSwitch::nReceivedValue = 0; this->externalFunctionPtr = NULL; //NEW this->functionPtrExists = false; //NEW

    endif

    }

  4. Then in RCSwitch.cpp, add the code for the new enableReceive defined in the header file: void RCSwitch::enableReceive(int interrupt, void (*ptrToFunction)(void)){ externalFunctionPtr = ptrToFunction; functionPtrExists = true; this->enableReceive(interrupt); //call to existing enableReceive }

  5. Finally, add the following 3 lines to the bottom of RECEIVE_ATTR RCSwitch::handleInterrupt() : if(functionPtrExists == true) { externalFunctionPtr(); }

Once you have done all this, in your main file for your arduino code, you would declare your function: void foo() { //do stuff }

this would get called in your code by: myRcSwitch.enable(0, &foo);

I've attached the proposed changes. Feel free to use them or not. Again, thanks for the great library RCSwitch-with-proposed-interrupt-mods-(and-test-code).zip