Skip to content

Instantly share code, notes, and snippets.

@NSBum
Last active April 7, 2018 19:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NSBum/9c857a0e10fa5e702f2dff9cf8956e04 to your computer and use it in GitHub Desktop.
Save NSBum/9c857a0e10fa5e702f2dff9cf8956e04 to your computer and use it in GitHub Desktop.
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
static const uint8_t NUM_MENU_ITEMS = 6;
const char* menu_items[] = {
"Day lo temp",
"Day hi temp",
"Nite lo temp",
"Nite hi temp",
"Heat ON",
"Heat OFF"
};
enum PinAssignments {
encoderPinA = 5, // right
encoderPinB = 6, // left
selectButton = 7
};
volatile unsigned int encoderPos = 0; // a counter for the dial
unsigned int lastReportedPos = 1; // change management
static boolean rotating = false; // debounce management
// interrupt service routine vars
boolean A_set = false;
boolean B_set = false;
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, SCL, SDA, U8X8_PIN_NONE);
void setup() {
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(selectButton, INPUT);
// turn on pullup resistors
digitalWrite(encoderPinA, HIGH);
digitalWrite(encoderPinB, HIGH);
digitalWrite(selectButton, HIGH);
// encoder pin on interrupt 0 (pin 2)
attachInterrupt(digitalPinToInterrupt(encoderPinA), doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
attachInterrupt(digitalPinToInterrupt(encoderPinB), doEncoderB, CHANGE);
attachInterrupt(digitalPinToInterrupt(selectButton), doSelect, RISING);
Serial.begin(115200); // output
u8g2.begin();
u8g2.enableUTF8Print();
u8g2.setFont(u8g2_font_courB12_tr);
u8g2.setFontMode(0);
}
// main loop, work is done by interrupt service routines, this one only prints stuff
void loop() {
rotating = true; // reset the debouncer
if (lastReportedPos != encoderPos) {
encoderPos = (encoderPos > NUM_MENU_ITEMS -1 )?0:encoderPos;
Serial.print("Index:");
Serial.println(encoderPos, DEC);
lastReportedPos = encoderPos;
uint8_t tempPos = encoderPos;
u8g2.clearDisplay();
u8g2.firstPage();
do {
u8g2.setCursor(0, 12);
u8g2.print(menu_items[tempPos++]);
for( uint8_t i = 0; i < NUM_MENU_ITEMS; i++ ) {
if( tempPos < NUM_MENU_ITEMS) {
u8g2.setCursor(0,16 + (i+1)*14);
u8g2.print(menu_items[tempPos++]);
}
}
} while ( u8g2.nextPage() );
}
}
// Interrupt on A changing state
void doEncoderA() {
// debounce
if ( rotating ) delay (1); // wait a little until the bouncing is done
// Test transition, did things really change?
if ( digitalRead(encoderPinA) != A_set ) { // debounce once more
A_set = !A_set;
// adjust counter + if A leads B
if ( A_set && !B_set )
encoderPos += 1;
rotating = false; // no more debouncing until loop() hits again
}
}
// Interrupt on B changing state, same as A above
void doEncoderB() {
if ( rotating ) delay (1);
if ( digitalRead(encoderPinB) != B_set ) {
B_set = !B_set;
// adjust counter - 1 if B leads A
if ( B_set && !A_set )
encoderPos -= 1;
rotating = false;
}
}
void doSelect() {
u8g2.setFont(u8g2_font_courB12_tr);
u8g2.clearDisplay();
u8g2.firstPage();
do {
u8g2.setCursor(2, 32);
u8g2.print(menu_items[encoderPos]);
} while ( u8g2.nextPage() );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment