Using external and internal interrupts

Hello,

I am having an Arduino system with a LCD, a led and a button. Now, what I'm trying to do is to start a timer and increment it every 428 ms. The timer shall start when the button is pressed and increment every 428ms. I used an external interrupt on pin 2 with a flag for the button and an internal interrupt for the timer. If the flag is 1 the timer shall start, the LED and the display should be on. If the flag is 0 the system shall stop: LED and display off, timer stopped. My problem is that I have an index and increment it every 428 ms using the timer interrupt. When it gets to 7 I want to reset it but sometimes I think it overflows and doesn't reset because it goes to 8 9 10 and so on. I added an instruction in the interrupt for the button and reset the counter to 0. What I really want to do is to start timer if the button was a pressed, and stop it otherwise. What I managed to do so far is:

#include <LiquidCrystal.h>

const int buttonPin = 2; // the pin that the pushbutton is attached to
const int ledPin = 10; // the pin that the LED is attached to
const int photoTransistorPin = A5; //the pin that the PhotoTransistor is attached to
volatile bool startFlag = 0; // flag for button interrupt goes from high to low
volatile unsigned int arrayIndex = 0;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 7);

void setup()
{
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);

pinMode(buttonPin, INPUT_PULLUP); // initialize the button pin as an input
pinMode(ledPin, OUTPUT); // initialize the button pin as an output
pinMode(photoTransistorPin, INPUT); //initialize the phototransistor pin as an input

//settings for timer interrupts, but keep timer disabled until push button is pressed
cli();//stop interrupts

//set timer1 interrupt at 2.336448598Hz = 428ms
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
// set compare match register for 2.336448598Hz = 428ms increments
OCR1A = 6686;// = (1610^6) / (2.3364485981024) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12 and CS10 bits for 1024 prescaler
TCCR1B |= (1 << CS12) | (1 << CS10);
// disable timer by default
TIMSK1 &= ~(1 << OCIE1A);
sei();//allow interrupts

attachInterrupt(0, buttonPin_ISR, RISING); //attach interrupt on rising edge on push button
}

void loop()
{
if (startFlag == 1)
{
startMeasurements();
}
else
{
shutDownSystem();
}

}

void buttonPin_ISR()
{
// adding a small delay prevents reading the buttonState to fast
// ( debouncing
delay(40);

startFlag =! startFlag;

//reset counter
arrayIndex = 0;
}

void shutDownSystem()
{
//stop timer
cli();
TIMSK1 &= ~(1 << OCIE1A);
sei();

//turn off LED
digitalWrite(ledPin, LOW);

// turn off the display
lcd.noDisplay();
delay(500);
}

void startMeasurements()
{
unsigned int lightValue = 0; //used to store the read value from the photoTransistorPin

//turn on display
lcd.display();
delay(500);

cli();
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei();

digitalWrite(ledPin, HIGH);

/display current light every 3 seconds/
if (arrayIndex == 7)
{
//reset index
arrayIndex = 0;

}

}

//timer interrupt each 428ms to increment index
ISR(TIMER1_COMPA_vect)
{
arrayIndex++;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(arrayIndex);
}

void buttonPin_ISR()
{ 
  // adding a small delay prevents reading the buttonState to fast
  // ( debouncing
  delay(40);

You can NOT use delay() in an ISR. It is stupid to even think about it.

Frankly, I see no reason to use an interrupt to read the state of a pin with a switch pressed by a human connected to it.

ISR(TIMER1_COMPA_vect)
{
  arrayIndex++;
  lcd.clear();

Clearing the LCD takes longer than an interrupt service routine should take. Do NOT do that here.

  if (arrayIndex == 7)
  {
       //reset index

Resetting the index in the ISR makes more sense. So does resetting it if it is greater than 6.

OK. Thank you.

Because of the "delay(500);" in startMeasurements() the counter is only checked about twice per second. Since the number changes every 428 mS you could easily miss the time that it is 7.

PaulS:
Frankly, I see no reason to use an interrupt to read the state of a pin with a switch pressed by a human connected to it.

To send emergency services as quickly as possible, to disconnect the human so they can lead a normal life?