interrupt works just once during a program

Hello.

I'm doing a project with the Arduiono 101 and iv'e connected several sensors to it.
Each sensor needs it's own code to run in order to read the data and do some thing with it.

In order to select the code segment to run the correct code for the specific sensor, i'm using a joystick that has 2 axis and a push button.

While in the "main menu" and inside void loop,();, tilting the joystick to a certain direction calls a function outside void loop();. Inside the called function is a code that reads the sensor the user has selected.

In order to break the loop of the called function and go back to the "main menu" I have to use an interrupt by pressing the push button (must be interrupt, there are no other options).

Interrupts are enabled throughout the code.
The interrupt is called fine just for the first time, but i can't call the interrupt again and I don't know why. How can I fix this?

for example:

void setup() 
{
// stuff....
  pinMode(Interrupt_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(Interrupt_PIN), ISR, CHANGE); // in order to break loops after user selection
//....
}

void loop() 
{
  joystick_pos();
}

void ISR() // Interrupt Serivce Routine - call joystick function in order to switch sensor
{
  Serial.println("INTERRUPT!!!!!!!!!!!!!!!!!!!!!!!!!");
  digitalWrite(greenLED,HIGH);
  analogWrite(redpin, 255); 
  analogWrite(bluepin, 255);
  analogWrite(greenpin, 255);
  joystick_pos();
}

void joystick_pos()
{
  noInterrupts(); // no interrupts while user is selecting sensor
  digitalWrite(greenLED,LOW);
  analogWrite(redpin, 255);  // Turn on Purple color on full color LED
  analogWrite(bluepin, 255);
  analogWrite(greenpin, 0); 
  
  user_selection = NULL;
  while (user_selection == NULL)
  {
    int x_pos = analogRead(in_x); //read the signal of x and y and store them in variables. pos means position.
    int y_pos = analogRead(in_y);
//    Serial.print("X: ");
//    Serial.println(x_pos);
//    Serial.print("Y: ");
//    Serial.println(y_pos);
    
    if((x_pos <= (x_up+5))) // X is UP && ........
    {
      if(((y_center -5) <= y_pos) && ((y_pos) <= (y_center + 5))) // Y CENTER
      {
        Serial.println("12");
      }
      if((y_pos <= (y_right+5))) // Y is RIGHT
      {
        Serial.println("1 and a half");
      }
      if(((y_left -5) <= y_pos) && ((y_pos) <= (y_left + 5)))
      {
        Serial.println("10 and a half");
      }
    } // end of X UP
  
  
    if(((x_center -5) <= x_pos) && ((x_pos) <= (x_center + 5))) // X is CENTER && ........
    {
      if(((y_center -5) <= y_pos) && ((y_pos) <= (y_center + 5))) // Y CENTER
      {
        Serial.println("CENTER");
      }
      if((y_pos <= (y_right+5))) // Y is RIGHT
      {
        Serial.println("3");
        for (int i=0; i<=2; i++) // flash three times to show user selection is received
        {
          digitalWrite(greenLED, HIGH);
          delay(200);
          digitalWrite(greenLED, LOW);
        }    
        mic_touch_vibration(); // user selected mic touch vibration
      }
      if(((y_left -5) <= y_pos) && ((y_pos) <= (y_left + 5))) // Y is LEFT
      {
        Serial.println("9");
        digitalWrite(greenLED, HIGH);
        analogWrite(redpin, 0); 
        analogWrite(bluepin, 0);
        analogWrite(greenpin, 0);
        blynk_setup();
      }
    } // end of X CENTER

  
    if(((x_down -5) <= x_pos) && ((x_pos) <= (x_down + 5))) // X is DOWN && ........
    {
      if(((y_center -5) <= y_pos) && ((y_pos) <= (y_center + 5))) // Y CENTER
      {
        Serial.println("6");
        for (int i=0; i<=2; i++) // flash the color LED three times (WHITE color) to show user selection is received
        {
          analogWrite(redpin, 255);
          analogWrite(bluepin, 255);
          analogWrite(greenpin, 255);
          delay(200);
          analogWrite(redpin, 0);
          analogWrite(bluepin, 0);
          analogWrite(greenpin, 0);
          delay(200);
        }
        sharpIR(); // user selected SharpIR sensor
      }
      if((y_pos <= (y_right+5))) // Y is RIGHT
      {
        Serial.println("4 and a half");
      }
      if(((y_left -5) <= y_pos) && ((y_pos) <= (y_left + 5))) // Y is LEFT
      {
        Serial.println("7 and a half");
      }
    } // end of X DOWN
  }
}

//....... other function I have written........

// The called functions enable interrupt and read the sensor until interrupt occurs.
//for example:
void blynk_setup()
{
  interrupts();
  digitalWrite(greenLED,HIGH);//turn on the green LED and turn off everything else
  analogWrite(redpin, 0);  //
  analogWrite(bluepin, 0 ); //
  analogWrite(greenpin, 0);
  blynk_run();
}


void blynk_run()
{
  user_selection = 1;
  while(1)
  {
    blePeripheral.poll();
    Blynk.run();
  }
}

yuv_cohen:
Hello.

I'm doing a project with the Arduiono 101 and iv'e connected several sensors to it.
Each sensor needs it's own code to run in order to read the data and do some thing with it.

In order to select the code segment to run the correct code for the specific sensor, i'm using a joystick that has 2 axis and a push button.

While in the "main menu" and inside void loop,();, tilting the joystick to a certain direction calls a function outside void loop();. Inside the called function is a code that reads the sensor the user has selected.

In order to break the loop of the called function and go back to the "main menu" I have to use an interrupt (must be interrupt, there are no other options).

for example:

void loop();
{
joystick_pos();
}

I don't know what we're supposed to make of that

AWOL:
I don't know what we're supposed to make of that

I mistakenly posted it before i finished writing, sorry.
The post is now edited.

yuv_cohen:
I mistakenly posted it before i finished writing, sorry.
The post is now edited.

My earlier comment still stands.

Please remember to use code tags when posting code

interrupt()
{
  joystick_pos;
}

Does your code really look like that?

yuv_cohen:
In order to break the loop of the called function and go back to the "main menu" I have to use an interrupt by pressing the push button (must be interrupt, there are no other options).

It should not be necessary to use an interrupt if the program is designed better.

Have a look at Several Things at a Time and Planning and Implementing a Program

Note how each function runs very briefly and returns to loop() so the next one can be called. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R

Robin2:
It should not be necessary to use an interrupt if the program is designed better.

Have a look at Several Things at a Time and Planning and Implementing a Program

Note how each function runs very briefly and returns to loop() so the next one can be called. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R

I know that with proper coding it could be done differently and without interrupts, the thing is i am not allowed to re-write the code.
This is part of an assignment for a university project, and I must use an interrupt in order to enable the user to select a different sensor.

When i wrote there is no other option I meant it.

Well, without seeing the code you've written, you're just wasting time here.

The code is way too long for me to post it here, but it does exactly what the example shows. I've edited it to make it more detailed with some of the actual code.

What could cause an interrupt to work just once?

but it does exactly what the example shows

{
  joystick_pos;
}

So, your code doesn't do anything useful.

AWOL:

{

joystick_pos;
}


So, your code doesn't do anything useful.

AWOL:

{

joystick_pos;
}


So, your code doesn't do anything useful.

This code reads sensors to help disabled people communicate and activate things.
As iv'e said, the code is too long for me to post it in it's entirety.
I need help for just one thing. I do not need coding lessons. The writing of this code was mostly out of my hand.
So if you don't have an answer, please, stop trolling/schooling me because I really don't have the energy for it.

I'm just trying to point out that a function reference on its own does nothing useful.

But you're not interested, so, OK, I'm out.

yuv_cohen:
The code is way too long for me to post it here, but it does exactly what the example shows. I've edited it to make it more detailed with some of the actual code.

What could cause an interrupt to work just once?

Are you saying a University student waited until he wrote the entire program before he tried testing it?

Paul

Paul_KD7HB:
Are you saying a University student waited until he wrote the entire program before he tried testing it?

Paul

A university student is still writing it.

I just read back through the thread, and found you'd edited the original post.

Don't do that.

And don't do Serial I/O in interrupt context.

I'm amazed that these messages still aren't getting through.

yuv_cohen:
A university student is still writing it.

Some re-education required.

I kind of fixed it.

the problem was I was calling a function outside of the ISR before it was finished.
I fixed it by using a flag in the ISR, letting it finish, and having the rest of the program check if there were flags from an interrupt.

But now I have a new problem:

I call an interrupt

the interrupt sets volatile int flag = 1 and goes back to function a().

function a checks for flags, flag = 1, calls joystick_pos() function (to take user selection)

user selects a function

the function is called once, and then breaks and goes back to joystick_pos()

after the second time i press it it works fine.

example for the fix and a function being called:

volatile int flag = 0;

void setup() 
{
  pinMode(Interrupt_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(Interrupt_PIN), ISR, CHANGE); // in order to break loops after user selection
}

void ISR() // Interrupt Serivce Routine - call joystick function in order to switch sensor
{
  //Serial.println("INTERRUPT!!!!!!!!!!!!!!!!!!!!!!!!!");
  digitalWrite(greenLED,HIGH);
  analogWrite(redpin, 255); 
  analogWrite(bluepin, 255);
  analogWrite(greenpin, 255);
  flag = 1;
  //joystick_pos();
}

void joystick_pos()
{
  flag = 0;
  Serial.print("flag is: ");
  Serial.print(flag);
  noInterrupts(); // no interrupts while user is selecting sensor
  digitalWrite(greenLED,LOW);
  analogWrite(redpin, 255);  // Turn on Purple color on full color LED
  analogWrite(bluepin, 255);
  analogWrite(greenpin, 0); 
  
  user_selection = NULL;
  while (user_selection == NULL)
  {
    int x_pos = analogRead(in_x); //read the signal of x and y and store them in variables. pos means position.
    int y_pos = analogRead(in_y);
//    Serial.print("X: ");
//    Serial.println(x_pos);
//    Serial.print("Y: ");
//    Serial.println(y_pos);
    
    if((x_pos <= (x_up+5))) // X is UP && ........
    {
      if(((y_center -5) <= y_pos) && ((y_pos) <= (y_center + 5))) // Y CENTER
      {
        Serial.println("12");
      }
      if((y_pos <= (y_right+5))) // Y is RIGHT
      {
        Serial.println("1 and a half");
      }
      if(((y_left -5) <= y_pos) && ((y_pos) <= (y_left + 5)))
      {
        Serial.println("10 and a half");
      }
    } // end of X UP
  
  
    if(((x_center -5) <= x_pos) && ((x_pos) <= (x_center + 5))) // X is CENTER && ........
    {
      if(((y_center -5) <= y_pos) && ((y_pos) <= (y_center + 5))) // Y CENTER
      {
        Serial.println("CENTER");
      }
      if((y_pos <= (y_right+5))) // Y is RIGHT
      {
        Serial.println("3");
        for (int i=0; i<=2; i++) // flash three times to show user selection is received
        {
          digitalWrite(greenLED, HIGH);
          delay(200);
          digitalWrite(greenLED, LOW);
        }    
        mic_touch_vibration(); // user selected mic touch vibration
      }
      if(((y_left -5) <= y_pos) && ((y_pos) <= (y_left + 5))) // Y is LEFT
      {
        Serial.println("9");
        digitalWrite(greenLED, HIGH);
        analogWrite(redpin, 0); 
        analogWrite(bluepin, 0);
        analogWrite(greenpin, 0);
        blynk_setup();
      }
    } // end of X CENTER

  
    if(((x_down -5) <= x_pos) && ((x_pos) <= (x_down + 5))) // X is DOWN && ........
    {
      if(((y_center -5) <= y_pos) && ((y_pos) <= (y_center + 5))) // Y CENTER
      {
        Serial.println("6");
        for (int i=0; i<=2; i++) // flash the color LED three times (WHITE color) to show user selection is received
        {
          analogWrite(redpin, 255);
          analogWrite(bluepin, 255);
          analogWrite(greenpin, 255);
          delay(200);
          analogWrite(redpin, 0);
          analogWrite(bluepin, 0);
          analogWrite(greenpin, 0);
          delay(200);
        }
        sharpIR(); // user selected SharpIR sensor
      }
      if((y_pos <= (y_right+5))) // Y is RIGHT
      {
        Serial.println("4 and a half");
      }
      if(((y_left -5) <= y_pos) && ((y_pos) <= (y_left + 5))) // Y is LEFT
      {
        Serial.println("7 and a half");
      }
    } // end of X DOWN
  }
}
  

void mic_touch_vibration() 
{
  flag = 0;
  interrupts();
  user_selection = 1;
  while(1) // loop until user selects to switch sensor
  {
    if((digitalRead(mic) == HIGH) && (digitalRead(touch) == LOW) && (digitalRead(vibration) == HIGH)) // 
    {
      Serial.println("No Input Detected"); //if no input - blue is on
      analogWrite(redpin, 0);
      analogWrite(bluepin, 255);
      analogWrite(greenpin, 0);
    }
    else //flash blue & green three times
    {
      Serial.println("Input Detected"); 
      for (int i=0; i<=2; i++)
      {
        analogWrite(redpin, 0);
        analogWrite(bluepin, 255);
        analogWrite(greenpin, 0);
        delay(200);
        analogWrite(redpin, 0);
        analogWrite(bluepin, 0);
        analogWrite(greenpin, 255);
        delay(200);
      }
    }
    if (flag == 1)
    {
      joystick_pos();
    }
  }
}

void blynk_setup()
{
  user_selection = 1;
  interrupts();
  digitalWrite(greenLED,HIGH);//turn on the green LED and turn off everything else
  analogWrite(redpin, 0);  //
  analogWrite(bluepin, 0 ); //
  analogWrite(greenpin, 0);
  blynk_run();
}



void blynk_run()
{
  flag = 0;
  while(1)
  {
    blePeripheral.poll();
    Blynk.run();
    if (flag == 1)
    {
      joystick_pos();
    }
  }
}

The serial print looks like this:

...
CENTER
CENTER
3 // ***** <- user made a selection, function a() is called
No Input Detected //runs and reads a sensor once
CENTER
CENTER
...
CENTER
CENTER // until i make another selection
3
No Input Detected // and then it stays in the called function
No Input Detected

Post complete code, or get banned for wasting forum time.

Simple choice.

Your choice.

He’d have to get the university student’s permission to post the code.

I don't mind posting the code but it's too long for me to post it.

here is a link to it

As for your remarks "Some re-education required" and "Are you saying a University student waited until he wrote the entire program before he tried testing it?" - Why are you so condescending? Yeah, i'm new to writing arduino codes. Yeah, I wrote a program that I need to make changes in. How funny.

Ignoring published advice is not funny either.

If you can't post it, attach it.

Again, published advice.

"Are you saying a University student waited until he wrote the entire program before he tried testing it?"

This is not condescending, this is common sense