[SOLVED] sketch stops after Interrupt is called.

sketch stops at after interrupt weldExitFlag() is called

#include <PinChangeInterrupt.h>
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
Servo myServo;

//Pins assigned

//Const Variables
const int buttonPin  = 9;  // Weld button

void setup()
{
  attachPCINT(digitalPinToPCINT(buttonPin), WeldExit, CHANGE);
}

void Display()
{
  lcd.clear();
  lcd.setCursor(5, 0);
  lcd.print("Spot Welder");
  lcd.setCursor(3, 1);
  lcd.print("Microcontroller");
  lcd.setCursor(0, 2);
  lcd.print("W1:");
  lcd.print(pre);
  //lcd.print(char(0xE4));
  lcd.print("ms");
  lcd.setCursor(9, 2);
  lcd.print("P:");
  lcd.print(pause);
  lcd.print("ms");
  lcd.setCursor(0, 3);
  lcd.print("W2:");
  lcd.print(WeldTime);
  lcd.print("ms ");

  myServo.detach();
}


void WeldExit()
{
  if (weldExitFlag == true)
  {
    contWeld = false;
    Display();
  }
}

void Weld()  //Actual weld
{
  int wait;
  if ((SrvPotMap1 && SrvPotMap2) == 0)        //disables servo when both servo pot values are zero and sets weld interval
  {
    wait = 700;
  }
  else
  {
    wait = 0;
  }
  delay(wait);
  lcd.backlight();
  myServo.attach(servoPin);
  digitalWrite(rdy, LOW);
  ServoStart();
  buttonState = digitalRead(buttonPin);
  zeroCrossingFlag = false; //set flag false and wait for next zero crossing
  while (!zeroCrossingFlag) {};
  delayMicroseconds(tgr_dly);
  digitalWrite(TRIAC, HIGH);
  delay(pre);               //preWeld time ms
  digitalWrite(TRIAC, LOW);
  delay(pause);
  zeroCrossingFlag = false; //set flag false and wait for next zero crossing
  while (!zeroCrossingFlag) {};
  delayMicroseconds(tgr_dly);
  digitalWrite(TRIAC, HIGH);
  delay(WeldTime);
  digitalWrite(TRIAC, LOW);
  ServoReturn();
  myServo.detach();
  digitalWrite(bzr, HIGH);
  delay(100);
  digitalWrite(bzr, LOW);
}

void continousWeld()
{
  
  int countWeldCycle;
  int bzrCount;
  lcd.backlight();
  lcd.setCursor(0, 1);
  lcd.print("W1:");
  lcd.print(pre);
  lcd.print("ms ");
  //lcd.print(char(0xE4));
  //lcd.print("s");
  lcd.setCursor(9, 1);
  lcd.print("W2:");
  lcd.print(rotaryEncoder());
  lcd.print("ms");
  while (bzrCount < 2)
  {
    digitalWrite(bzr, HIGH);
    delay(60);
    digitalWrite(bzr, LOW);
    delay(60);
    bzrCount++;
  }
  buttonState = digitalRead(buttonPin);
  while (buttonState == HIGH)
  {
    weldExitFlag = true;
    countWeldCycle++;
    lcd.setCursor(0, 3);
    lcd.print("Weld Cycle(s):");
    lcd.print(countWeldCycle);
    delay(100);
    buttonState = digitalRead(buttonPin);
    Weld();
    delay(500);
  }
  digitalWrite(bzr, HIGH);
  Display();
  lcd.backlight();
  delay(200);
  digitalWrite(bzr, LOW);
  delay(200);
  weldExitFlag = false;
}

void setFlag()
{
  zeroCrossingFlag = true; //interrupt sets flag true
}

void loop()
{
  switch (checkButton())
  {
    case shortPress:
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Mode: Manual Weld    ");
      lcd.setCursor(0, 2);
      lcd.print("W1:");
      lcd.print(pre);
      //lcd.print(char(0xE4));
      lcd.print("ms");
      lcd.setCursor(9, 2);
      lcd.print("P:");
      lcd.print(pause);
      lcd.print("ms");
      lcd.setCursor(0, 3);
      lcd.print("W2:");
      lcd.print(WeldTime);
      lcd.print("ms ");
      lcd.backlight();
      Weld();
      break;

    case longPress:
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Mode: Automatic Weld");
      continousWeld();
      break;

    case longerPress:
      configMenu();
      break;
  }
  zeroCrossingFlag = false;
  rotaryEncoder();

byte checkButton()
{
  byte event = noEvent;
  buttonState = digitalRead(buttonPin);

  //button pressed
  if (buttonState == LOW && previousButtonState == HIGH)
  {
    delay(20);   //blocking debounce routine
    buttonState = digitalRead(buttonPin);//read button again
    if (buttonState == LOW && previousButtonState == HIGH)
    {
      buttonPressStartTimeStamp = millis();
      startTimeout = true;
    }
  }

  //button released
  if (buttonState == HIGH && previousButtonState == LOW)
  {
    delay(20);//blocking debounce routine
    buttonState = digitalRead(buttonPin);//read button again
    if (buttonState == HIGH && previousButtonState == LOW)
    {
      buttonPressDuration = (millis() - buttonPressStartTimeStamp);
      startTimeout = false;//duration determined no timeout required
    }
  }

  if (buttonPressDuration > 0 && buttonPressDuration <= shortTime)
  {
    event = shortPress;
    buttonPressDuration = 0;
  }

  if (buttonPressDuration > longTime && buttonPressDuration <= longerTime)
  {
    event = longPress;
    buttonPressDuration = 0;
  }

  //button not released and still timing
  if (buttonState == LOW && startTimeout == true && (millis() - buttonPressStartTimeStamp) > longerTime)
  {
    event = longerPress;
    startTimeout = false;
  }

  buttonPressDuration = 0;
  previousButtonState = buttonState;
  return event;
}

the interrupt function interrupts as expected but does not enter the loops after doing so. It interrupts and displays, where as it should display the Display() function

]code]
void continousWeld()
{…


lcd.print(“W1:”);
lcd.print(pre);
lcd.print("ms ");
//lcd.print(char(0xE4));
//lcd.print(“s”);
lcd.setCursor(9, 1);
lcd.print(“W2:”);
lcd.print(rotaryEncoder());
lcd.print(“ms”);
while (bzrCount < 2)
} [/code]

it tries putting the continousWeld() function in the loop thinking it would exit into the loop but that did not work either.

I just scanned your code an I don't see a } to to end the loop() function. I would imagine it would need to be placed just before the byte checkButton().

The sketch is incomplete. There are over a dozen variables and functions undefined! The remaining code is very hard to understand because it lacks comments to explain intent.

It makes no sense to use an interrupt for a button and also poll that button. You should get rid of the interrupt and check the button more often.

It is almost never a good idea to do display output in an ISR.

The sketch is quite big hence just added only the part where the error was showing up. I was trying for a better work around since the call before the ISR has a few delay and polling the button does work but a bit slow because of the delay.

Post the complete program. Or, better still, write a short demo program that demonstrates the same problem.

...R

You probably shouldn't be trying to call display functions from inside the ISR. Just set your variable to false and get out and let loop catch the display next time around.

Delta_G:
You probably shouldn’t be trying to call display functions from inside the ISR. Just set your variable to false and get out and let loop catch the display next time around.

Yup ! i did just that and it works better.

#include <PinChangeInterrupt.h>
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
Servo myServo;

//Pins assigned

//Const Variables
const int buttonPin  = 9;  // Weld button

void setup()
{
  attachPCINT(digitalPinToPCINT(buttonPin), WeldExit, CHANGE);
}

void Display()
{
  lcd.clear();
  lcd.setCursor(5, 0);
  lcd.print("Spot Welder");
  lcd.setCursor(3, 1);
  lcd.print("Microcontroller");
  lcd.setCursor(0, 2);
  lcd.print("W1:");
  lcd.print(pre);
  //lcd.print(char(0xE4));
  lcd.print("ms");
  lcd.setCursor(9, 2);
  lcd.print("P:");
  lcd.print(pause);
  lcd.print("ms");
  lcd.setCursor(0, 3);
  lcd.print("W2:");
  lcd.print(WeldTime);
  lcd.print("ms ");

  myServo.detach();
}


void WeldExit()
{
  if (weldExitFlag == true)
  {
    contWeld = true
  }
}

void Weld()  //Actual weld
{
  int wait;
  if ((SrvPotMap1 && SrvPotMap2) == 0)        //disables servo when both servo pot values are zero and sets weld interval
  {
    wait = 700;
  }
  else
  {
    wait = 0;
  }
  delay(wait);
  lcd.backlight();
  myServo.attach(servoPin);
  digitalWrite(rdy, LOW);
  ServoStart();
  buttonState = digitalRead(buttonPin);
  zeroCrossingFlag = false; //set flag false and wait for next zero crossing
  while (!zeroCrossingFlag) {};
  delayMicroseconds(tgr_dly);
  digitalWrite(TRIAC, HIGH);
  delay(pre);               //preWeld time ms
  digitalWrite(TRIAC, LOW);
  delay(pause);
  zeroCrossingFlag = false; //set flag false and wait for next zero crossing
  while (!zeroCrossingFlag) {};
  delayMicroseconds(tgr_dly);
  digitalWrite(TRIAC, HIGH);
  delay(WeldTime);
  digitalWrite(TRIAC, LOW);
  ServoReturn();
  myServo.detach();
  digitalWrite(bzr, HIGH);
  delay(100);
  digitalWrite(bzr, LOW);
}

void continousWeld()
{
 
  int countWeldCycle;
  int bzrCount;
  lcd.backlight();
  lcd.setCursor(0, 1);
  lcd.print("W1:");
  lcd.print(pre);
  lcd.print("ms ");
  //lcd.print(char(0xE4));
  //lcd.print("s");
  lcd.setCursor(9, 1);
  lcd.print("W2:");
  lcd.print(rotaryEncoder());
  lcd.print("ms");
  while (bzrCount < 2)
  {
    digitalWrite(bzr, HIGH);
    delay(60);
    digitalWrite(bzr, LOW);
    delay(60);
    bzrCount++;
  }
  buttonState = digitalRead(buttonPin);
  while (contWeld = false)
  {
    weldExitFlag = true;
    countWeldCycle++;
    lcd.setCursor(0, 3);
    lcd.print("Weld Cycle(s):");
    lcd.print(countWeldCycle);
    delay(100);
    buttonState = digitalRead(buttonPin);
    Weld();
    delay(500);
  }
  digitalWrite(bzr, HIGH);
  Display();
  lcd.backlight();
  delay(200);
  digitalWrite(bzr, LOW);
  delay(200);
  weldExitFlag = false;
}

void setFlag()
{
  zeroCrossingFlag = true; //interrupt sets flag true
}

void loop()
{
  switch (checkButton())
  {
    case shortPress:
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Mode: Manual Weld    ");
      lcd.setCursor(0, 2);
      lcd.print("W1:");
      lcd.print(pre);
      //lcd.print(char(0xE4));
      lcd.print("ms");
      lcd.setCursor(9, 2);
      lcd.print("P:");
      lcd.print(pause);
      lcd.print("ms");
      lcd.setCursor(0, 3);
      lcd.print("W2:");
      lcd.print(WeldTime);
      lcd.print("ms ");
      lcd.backlight();
      Weld();
      break;

    case longPress:
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Mode: Automatic Weld");
      continousWeld();
      break;

    case longerPress:
      configMenu();
      break;
  }
  zeroCrossingFlag = false;
  rotaryEncoder();

byte checkButton()
{
  byte event = noEvent;
  buttonState = digitalRead(buttonPin);

  //button pressed
  if (buttonState == LOW && previousButtonState == HIGH)
  {
    delay(20);   //blocking debounce routine
    buttonState = digitalRead(buttonPin);//read button again
    if (buttonState == LOW && previousButtonState == HIGH)
    {
      buttonPressStartTimeStamp = millis();
      startTimeout = true;
    }
  }

  //button released
  if (buttonState == HIGH && previousButtonState == LOW)
  {
    delay(20);//blocking debounce routine
    buttonState = digitalRead(buttonPin);//read button again
    if (buttonState == HIGH && previousButtonState == LOW)
    {
      buttonPressDuration = (millis() - buttonPressStartTimeStamp);
      startTimeout = false;//duration determined no timeout required
    }
  }

  if (buttonPressDuration > 0 && buttonPressDuration <= shortTime)
  {
    event = shortPress;
    buttonPressDuration = 0;
  }

  if (buttonPressDuration > longTime && buttonPressDuration <= longerTime)
  {
    event = longPress;
    buttonPressDuration = 0;
  }

  //button not released and still timing
  if (buttonState == LOW && startTimeout == true && (millis() - buttonPressStartTimeStamp) > longerTime)
  {
    event = longerPress;
    startTimeout = false;
  }

  buttonPressDuration = 0;
  previousButtonState = buttonState;
  return event;
}

changed the ISR chage the condition in the while loop to false and that fixed it.