I'm working on a rather complicated project that involves multiple pushbuttons triggering Pin Change Interrupts and a Timer Interrupt combined with an external RTC chip to keep time (RTC code hasn't been added yet). There's also a 16x4 LCD for output. I'm in the process of building the code up piece by piece (so some things may seem unnecessary right now) but I've hit an error that I cannot explain. My code is as follows:
#include <LiquidCrystal.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define NO_PIN_ARDUINO
#include <PinChangeInt.h>
//button pin definitions
#define BUTTON_ONE A0
#define BUTTON_TWO 8
#define ROTARY_BUTTON 7
#define ROTARY_ENCODER_A 9
#define ROTARY_ENCODER_B 10
LiquidCrystal lcd(A3, 2, 6, 3, 5, 4);
byte copyright[8] = {
B01110,
B10101,
B11011,
B11001,
B11001,
B11011,
B10101,
B01110
};
void setup() {
// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// set compare match register to desired timer count:
OCR1A = 15624;
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
sei(); // enable global interrupts
Serial.begin(9600);
pinMode(A2, INPUT);
digitalWrite(A2, HIGH);
if (digitalRead(A2)) {
int inputPins[] = {BUTTON_ONE, BUTTON_TWO, ROTARY_BUTTON, \
ROTARY_ENCODER_A, ROTARY_ENCODER_B, 11, 12, 13, A1, A4, A5};
for (int i = 0; i < 11; i++) {
pinMode(inputPins[i], INPUT);
if (i >= 5)
digitalWrite(inputPins[i], HIGH);
}
lcd.createChar(0, copyright);
lcd.begin(16, 4);
lcd.print(" SCORE SEEKER");
lcdsetCursor(5, 1);
lcd.write(byte(0));
lcd.print(" 2014");
delay1(1500);
lcdsetCursor(0, 3);
lcd.print("HOLD LEFT: SETUP");
delay1(1500);
attachInterrupt(BUTTON_ONE, func1, CHANGE);
attachInterrupt(ROTARY_BUTTON, func2, CHANGE);
attachInterrupt(BUTTON_TWO, func3, CHANGE);
Serial.println("X");
lcd.clear();
}
void loop() {
}
void delay1(long interval) {
long curr = millis();
long target = curr + interval;
while (millis() < target) {
}
}
//This method takes care of the addressing error in 16x4 LCDs
void lcdsetCursor(int col, int row) {
if (row > 1) {
lcd.setCursor(col - 4, row);
} else {
lcd.setCursor(col, row);
}
}
I did some testing and discovered that delay() (which is why I implemented delay1) and millis() were causing the problem which I'm guessing means something is wrong with Timer0 but I'm using Timer1 for the Timer Interrupt. I also tried commenting out cli() and sei() and that fixed it so it seems like Timer0 is getting disabled but not re-enabled. Any ideas why that might be? Any alternative possibilities?