Code executed twice (most of the time) from an interrupt

This is I hope a meaningful extract showing code to wait for any communication from a 433MHz transmitter to run some functions. The result is that it will usually run the functions twice, rarely only once. I had hoped that setting a flag between the RCSwitch.available and .resetAvailable calls would do this, but that doesn't work.

Is there a way to ensure only one interrupt is responded to (assuming that the transmitter button is staying down long enough to trigger several)?

Or does anyone know of a simpler library item for listening to the receiver?

#include <RCSwitch.h>
RCSwitch Radio = RCSwitch();

bool demand = false;

void setup() {

  Radio.enableReceive(0);  //Radio on interrupt 0 => that is pin 2
  homeflip();
  
}

void loop() {
  demand = false;   //Clear demand
  if (Radio.available()) {
    demand = true;
    Radio.resetAvailable();
  }
    while (demand) {  //Wait for radio demand signal
      flip();
      homeflip();
     demand = false;  
  }
 }

Please post all the code.

Not with no idea what flip() and homeflip() consist in.

Post a sketch that is complete and say what happens twice.

The examples in the library might be good to look at. Theoretically you shouldn't need to even know that interrupts are involved, that is not where you need to figure out what is going wrong, I don't think.

a7

@jremington @alto777
homeflip() and flip() run twice. Earlier I had them triggered by a switch and then they ran only once as I would expect.

// define pins
#define Ldir 3   //Lift motor Nema17
#define Lstep 4
#define Fdir 5   //Flip motor 28BYJ-48
#define Fstep 6
#define Empty 7  //Output pin to Empty LED
#define Test 8   //Test buttons
#define Limil 9  //Lift limit switch
#define Lid 10   //Lid open switch
#define Limif 11  //Flip limit switch
#define Flipen 12 //Flip driver enable
#define Vsense A3  //Vertical photodetector

#include <RCSwitch.h>
RCSwitch Radio = RCSwitch();

const int flipst = 188;   //No of cw steps to flip
const int check = 600; //No of lift steps before contents check
const int top = 1420;   //No of lift steps with no contents
const int fud = 2000;  //Time for HIGH and LOW:  28BYJ
const int lup = 100;   //Time HIGH: Nema
const int ldn = 1000;  //Time LOW: Nema - adjust for speed

int fail = 0;  //Counter for failed lifts
int steps = 0;  //Counter for steps
bool nokibble = false;
bool demand = false;

void setup() {
  pinMode(Ldir, OUTPUT);
  pinMode(Lstep, OUTPUT);
  pinMode(Fdir, OUTPUT);
  pinMode(Fstep, OUTPUT);
  pinMode(Empty, OUTPUT);
  pinMode(Test, INPUT_PULLUP);  //Signal LOW when pressed
  pinMode(Limil, INPUT_PULLUP); //Signal LOW when pressed
  pinMode(Lid, INPUT);   //Signal LOW when lid opened
  pinMode(Limif, INPUT);
  pinMode(Flipen, OUTPUT);

  Radio.enableReceive(0);  //Radio on interrupt 0 => that is pin 2
  homeflip();
  // homelift();
  // lift();  //Initial setup when switched on
}

void loop() {
  demand = false;   //Clear demand
  if (Radio.available()) {
    demand = true;
    Radio.resetAvailable();
  }
    while (demand) {  //Wait for radio demand signal
      flip();
      homeflip();
    // homelift();
    // lift();
    demand = false;  
  }
  
  // Lid is open
  // digitalWrite(Empty, LOW);  //Turn Empty light off
  // homelift();  //Move lift down
  // parkflip();  //Move flip out of the way
  // fail = 0;
  // while (digitalRead(Lid) == LOW) {
    //Wait for lid to shut
}


void homelift(){
  digitalWrite(Ldir, HIGH); //Lift downwards
  while (digitalRead(Limil) == HIGH){  //Lift above limit switch
    step(lup, ldn, Lstep);    //Move lift down to ref position
  }

}

void lift(){

  steps = top;  //No of steps for lift to top **TEST
  digitalWrite(Ldir, LOW);  //Lift upwards
  while (steps > 0){
    step(lup, ldn, Lstep);
    steps--;
  }
  // if (analogRead(Vsense) < 250) {

  // }

}

void homeflip(){

  digitalWrite(Flipen, LOW);  //Enable motor
  digitalWrite(Fdir, LOW);  //Anticlockwise  
    while (digitalRead(Limif) == LOW){  //Until limit switch closes
      step(fud, fud, Fstep);  //for BJ28, move to ref position
    }
  digitalWrite(Flipen, HIGH);  //Disable motor
}
void flip(){

  steps = flipst;
  digitalWrite(Flipen, LOW);  //Enable motor
  digitalWrite(Fdir, HIGH);  //Clockwise
  while (steps > 0){
    step(fud, fud, Fstep);  //Flip
    steps--;
  }
  digitalWrite(Flipen, HIGH);  //Disable motor
}



void step(int up, int down, uint8_t pin){
  digitalWrite(pin, HIGH); 
  delayMicroseconds(up);
  digitalWrite(pin, LOW); 
  delayMicroseconds(down); 
}

Are you aware that RCSwitch remotes typically send multiple copies of a given signal?

@jremington No I was not. Does this mean that the switch is happy to take ON ON ON ON to mean ON, for example? I had hoped to avoid getting and interpreting the data sent as it is irrelevent - I just need to know that a remote button has been pressed.

Since your functions take a while, use the library reset availability function after you do them.

You'll still have to get your finger off the button, but you will have plenty of time to do.

a7

Yes. Repetition is the only error checking feature implemented in the protocol. A suitably chosen delay can work to ignore extra copies of the signal.

Keep in mind that radio communication is inherently unreliable.

Is that not what I have done? I call .available, set the demand flag, then call .resetAvailable.

No.

void loop() {
  demand = false;   //Clear demand
    
  if (Radio.available()) {
      demand = true;
// not here right away...    Radio.resetAvailable();
  }

  while (demand) {  //Wait for radio demand signal
    flip();
    homeflip();

// here, so you ignore any that arrived right away or around the one that set you flag
// for all the time that flip/homeFlip took. Seconds:

    Radio.resetAvailable();
    demand = false;
  }
}

Walk your finger through it. You have to reset/cancle the official availability state.

If flip() and homeFlip() do not, as they appear to do, take many milliseconds, try throwing a delay in there long enough for... you to get your finger off the button and the transmitter to finich anything it had in progress.

If the blocking of flip() and homeFlip() or the extra delay I suggest become a problem, there are ways to code it so the net effect is the same but you can have your code juggling chainsaws in the meantime. Or calculating a few more digits of π, whatever.

In general, don't tell anyone you've handled something until you have. Handled it.

a7

Thank you @alto777 , you have solved my problem.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.