More interrupt questions.

I previously posted a question about interrupts, and since managed to get them working. However, I am getting some weird behaviour.

When I press the button, the program doesn't seem to go back to the loop, rather the screen goes blank. The interrupt still works, as if I put a serial output in it, it shows that it is being pressed, but it doesn't seem to go back to the program.

The code is below:

float Version = 0.7;

//Settings
int pulsesPerRev = 4;
int pulsesPerRot = 6;
/*Wheel circumference in metres*/
double wheelCircumference = 1.5;

//Libraries
#include <EEPROM.h>
#include <LiquidCrystal.h>

//LCD Pins
int rs = 32;
int enable = 33;
int d4 = 34;
int d5 = 35;
int d6 = 36;
int d7 = 37;

//LCD Initialisation
LiquidCrystal lcd(rs,enable,d4,d5,d6,d7);

//Pins
//Digital
int RPMPin = 41;
//Analog
int lambdaPin= 0;
int Temp1Pin = 1;
int Temp2Pin = 2;
//Interrupts
/*The line from the speedometer should be attached to digital 2.
  The line from button 1 should be attached to digital 3.
  The line from button 2 should be attached to digital 21. */

//Variables to be loaded from EEPROM
int setting = 0;
int imperialMetric = 0;
/* The total distance travelled in m. */
double TotalDistance = 0;

//External Variables
int numberOfSettings = 2;
int newDisplay = 456;
double speed;
volatile int numPulses = 0;
volatile unsigned long pulseDebounce;
volatile unsigned long buttonDebounce;
unsigned long lastSpeedTime;
int rpmSample = 1000;



void setup(){
  //Start LCD
  lcd.begin(16,2);
  //Setup interrupts.
  attachInterrupt(0,pulse,RISING);
  attachInterrupt(1,button1Press,FALLING);
  attachInterrupt(2,button2Press,FALLING);
  //Display startup on LCD
  lcd.print("Speeduino");
  lcd.setCursor(0,1);
  lcd.print("Version ");
  lcd.print(Version);
  delay(2000);
  lcd.clear();
  pinMode(RPMPin,INPUT);
}
void loop(){
  unsigned long timer;
  if (setting == 0) displayODO();
  if (setting == 1) displayRPM();
  
  if (millis() > timer + 1500){
    updateSpeedDist();
    timer = millis();
  }
}
void pulse(){
  if (millis()> pulseDebounce + 100) {
    numPulses++;
    pulseDebounce = millis();
  }
}
void button1Press(){
  if (millis()>buttonDebounce+100) {
    setting++;
    setting = setting % (numberOfSettings);
    buttonDebounce = millis();
  }
}
void button2Press(){
  if (millis()>buttonDebounce+100) {
    imperialMetric++;
    imperialMetric = imperialMetric % 2;
    buttonDebounce = millis();
    newDisplay = 897;
  }
}
void updateSpeedDist(){
  unsigned long newSpeedTime = millis();
  double speedMps = (((double)numPulses/(double)pulsesPerRot)*wheelCircumference)/(((double)newSpeedTime - (double)lastSpeedTime)/1000);
  speed = speedMps * 2.23693629;
  
  double newDist = (((double) numPulses/(double)pulsesPerRot)*wheelCircumference);
  TotalDistance = newDist + TotalDistance;
  numPulses = 0;
}
int getRPM(){
  unsigned long time = millis();
  int voltage = 1;
  int previousRead = 0;
  int newtime = millis();
  int revCount = 0;
  
  while (newtime < time + rpmSample){
    voltage = digitalRead(RPMPin);
    if ((voltage==HIGH)&&(previousRead==0)) {
      revCount++;
      previousRead = 1;
    }
    else if (voltage == LOW){
      previousRead = 0;
    }
  }
  return (int)((((double)revCount/(double)((double)rpmSample/1000))*60)/(double)pulsesPerRev);
}
void displayODO(){
  if (newDisplay != 0){
    lcd.clear();
    newDisplay = 0;
  }
  lcd.setCursor(0,0);
  if (imperialMetric == 0){
    lcd.print("Speed: ");
    lcd.print(speed);
    lcd.print("mph");
    lcd.setCursor(0,1);
    lcd.print("Dist: ");
    lcd.print((TotalDistance*0.000621371192));
    lcd.print("M");
  }
  if (imperialMetric == 1){
    lcd.print("Speed: ");
    lcd.print(speed*1.609344);
    lcd.print("kph");
    lcd.setCursor(0,1);
    lcd.print("Dist: ");
    lcd.print(TotalDistance*0.0001);;
    lcd.print("km");
  }
}
void displayRPM(){
  if (newDisplay != 1){
    lcd.clear();
    newDisplay = 1;
  }
  int rpm = getRPM();
  lcd.setCursor(0,0);
  if (imperialMetric == 0){
    lcd.print("Speed: ");
    lcd.print(speed);
    lcd.print("mph");
    lcd.setCursor(0,1);
    lcd.print("RPM: ");
    lcd.print(rpm);
  }
  if (imperialMetric == 1){
    lcd.print("Speed: ");
    lcd.print(speed*1.609344);
    lcd.print("kph");
    lcd.setCursor(0,1);
    lcd.print("RPM: ");
    lcd.print(rpm);
  }
}

I only have button 1 connected at the moment, but I don't see why that would make any difference.

Thanks :slight_smile:

You have some of your variables that are shared between interrupt and main program declared as 'volatile', which is correct. But shouldn't 'setting' and 'imperialMetric' also be declared 'volatile'?

Yes, but that doesn't seem to be the problem having fixed that. Writing a simpler program, I can get the button to work as expected, so it isn't the board. Am I doing something stupid within one of the functions?

attachInterrupt(0,pulse,RISING);
  attachInterrupt(1,button1Press,FALLING);
  attachInterrupt(2,button2Press,FALLING);

Any reason for not using the names that you've given these pins (and any reason those names are not constants)?

Umm, mainly because I had forgotten how to define constants? #define pinName x?

I'm sorry, I'd assumed these were your pin numbers.

int lambdaPin= 0;
int Temp1Pin = 1;
int Temp2Pin = 2;

They are going to be for additional sensors once I have the basics working. If I am right with the define code above, I will swap that in.

If I put a serial output in the loop, it prints until I press the button, and then it stops. Odd.

it prints until I press the button

Which button?

Reset :wink:

AWOL:
Which button?

Button 1.