Hello all. I cam across some odd behaviour on a Leonardo. Basically, after I call...
attachInterrupt(digitalPinToInterrupt(clk), isr, LOW);
Any interaction with the LCD causes the board to lock up. All of the interaction with the LCD prior to attaching the interrupt work fine. The goal here is to turn an encoder and increment a counter, then use the counter value to move a cursor up or down on the LCD. This is a menu system. The encoder code works fine, increments the counter and prints results to the serial monitor. As soon as I uncomment this code...
//lcd.setCursor(0, currentPosition);
//lcd.write(0);
The counter freezes on 1, the program locks up and nothing happens on the LCD. If I comment these 2 lines and upload again, the program runs, encoder works and counter updates.
The full code is below. Any ideas on what could be going on? The LCD library I'm using is LiquidCrystal_I2C from Arduino.
Thanks
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
//#include <SD.h>
const int clk = 3; // Used for generating interrupts using CLK signal
const int dt = 2; // Used for reading DT signal
const int btn = 4; // Used for the push button switch
const int linePos = 1; // Start position for menu line items
const int cursorPos = 0; // Start position for menu cursor
int lastPosition = 0; // Keep track of last rotary value
volatile int currentPosition = 0; // Updated by the ISR
String menu[8] = { "Hurricane","Mojito","Bahama Mama","Painkiller","Orange Crush","Adios MF","Liquid Marijana","Alabama Slammer" };
// Set the LCD address to 0x27
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Custom menu cursor character
byte menuCursor[] = {
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F
};
// ------------------------------------------------------------------
// INTERRUPT --------------------------------------------------------
// ------------------------------------------------------------------
void isr () {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
// If interrupts come faster than 5ms, assume it's a bounce and ignore
if (interruptTime - lastInterruptTime > 5) {
if (digitalRead(dt) == LOW)
{
currentPosition-- ; // Could be -5 or -10
}
else {
currentPosition++ ; // Could be +5 or +10
}
// Restrict value from 0 to +100
currentPosition = min(20, max(0, currentPosition));
}
// Keep track of when we were here last (no more than every 5ms)
lastInterruptTime = interruptTime;
}
// ------------------------------------------------------------------
// SETUP ------------------------------------------------------------
// ------------------------------------------------------------------
void setup() {
int i; // Loop variable
// Just whilst we debug, view output on serial monitor
Serial.begin(9600);
//Init the LCD and create the cursor character
lcd.begin();
lcd.createChar(0, menuCursor);
lcd.home();
//lcd.write(0);
// Write first 4 menu items to display
// lcd.print("test2");
for (i = 0; i < 4; i++) {
lcd.setCursor(linePos, i);
lcd.print(menu[i]);
}
// Write cursor to disay
lcd.setCursor(cursorPos, 0);
lcd.write(0);
// Switch is floating so use the in-built PULLUP so we don't need a resistor
pinMode(btn, INPUT_PULLUP);
pinMode(clk, INPUT_PULLUP);
pinMode(dt, INPUT_PULLUP);
// Attach the routine to service the interrupts
attachInterrupt(digitalPinToInterrupt(clk), isr, LOW);
}
// ------------------------------------------------------------------
// MAIN LOOP --------------------------------------------------------
// ------------------------------------------------------------------
void loop() {
// Is someone pressing the rotary switch?
if ((!digitalRead(btn))) {
currentPosition = 0;
while (!digitalRead(btn))
delay(10);
Serial.println("Reset");
}
// If the current rotary switch position has changed then update everything
if (currentPosition != lastPosition) {
// Write out to serial monitor the value and direction
if (currentPosition > lastPosition) {
Serial.print("UP: ");
Serial.println(currentPosition);
//lcd.setCursor(cursorPos, currentPosition - 1);
//lcd.print(" ");
//lcd.setCursor(0, 1);
//lcd.write(0);
} else {
Serial.print("DOWN: ");
Serial.println(currentPosition);
}
// Keep track of this new value
lastPosition = currentPosition ;
}
//delay(100);
}
