Last active
December 27, 2015 14:59
-
-
Save calaveraInfo/cd60cb4bab480a7fefe7 to your computer and use it in GitHub Desktop.
Use rotary encoder with Arduino Micro to increase/decrease a value and show that value on SSD1306 display. Based on https://learn.adafruit.com/pro-trinket-rotary-encoder/example-rotary-encoder-volume-control
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SPI.h> | |
#include <Wire.h> | |
#include <Adafruit_GFX.h> | |
#include <Adafruit_SSD1306.h> | |
#define OLED_DC 6 | |
#define OLED_CS 7 | |
#define OLED_RESET 8 | |
#define PIN_ENCODER_A 4 //Micro pin 4 - encoder A | |
#define PIN_ENCODER_B 6 | |
#define PIN_ENCODER_BX 12 //Micro pin 12 - encoder B | |
#define ARDUINO_PINx PIND | |
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS); | |
static uint8_t enc_prev_pos = 0; | |
static uint8_t enc_flags = 0; | |
int displayedNumber = 0; | |
const int ledPin = 13; | |
void setup() | |
{ | |
// set pins as input with internal pull-up resistors enabled | |
pinMode(PIN_ENCODER_A, INPUT); | |
pinMode(PIN_ENCODER_BX, INPUT); | |
digitalWrite(PIN_ENCODER_A, HIGH); | |
digitalWrite(PIN_ENCODER_BX, HIGH); | |
display.begin(SSD1306_SWITCHCAPVCC); | |
display.display(); // show splashscreen | |
//delay(2000); | |
//display.clearDisplay(); | |
// get an initial reading on the encoder pins | |
if (digitalRead(PIN_ENCODER_A) == LOW) | |
{ | |
enc_prev_pos |= (1 << 0); | |
} | |
if (digitalRead(PIN_ENCODER_BX) == LOW) | |
{ | |
enc_prev_pos |= (1 << 1); | |
} | |
} | |
void loop() | |
{ | |
int8_t enc_action = 0; // 1 or -1 if moved, sign is direction | |
// note: for better performance, the code will now use | |
// direct port access techniques | |
// http://www.arduino.cc/en/Reference/PortManipulation | |
uint8_t enc_cur_pos = 0; | |
// read in the encoder state first | |
if (bit_is_clear(ARDUINO_PINx, PIN_ENCODER_A)) | |
{ | |
enc_cur_pos |= (1 << 0); | |
} | |
if (bit_is_clear(ARDUINO_PINx, PIN_ENCODER_B)) | |
{ | |
enc_cur_pos |= (1 << 1); | |
} | |
// if any rotation at all | |
if (enc_cur_pos != enc_prev_pos) | |
{ | |
if (enc_prev_pos == 0x00) | |
{ | |
// this is the first edge | |
if (enc_cur_pos == 0x01) | |
{ | |
enc_flags |= (1 << 0); | |
} | |
else if (enc_cur_pos == 0x02) | |
{ | |
enc_flags |= (1 << 1); | |
} | |
} | |
if (enc_cur_pos == 0x03) | |
{ | |
// this is when the encoder is in the middle of a "step" | |
enc_flags |= (1 << 4); | |
} | |
else if (enc_cur_pos == 0x00) | |
{ | |
// this is the final edge | |
if (enc_prev_pos == 0x02) | |
{ | |
enc_flags |= (1 << 2); | |
} | |
else if (enc_prev_pos == 0x01) | |
{ | |
enc_flags |= (1 << 3); | |
} | |
// check the first and last edge | |
// or maybe one edge is missing, if missing then require the middle state | |
// this will reject bounces and false movements | |
if (bit_is_set(enc_flags, 0) && (bit_is_set(enc_flags, 2) || bit_is_set(enc_flags, 4))) | |
{ | |
enc_action = 1; | |
} | |
else if (bit_is_set(enc_flags, 2) && (bit_is_set(enc_flags, 0) || bit_is_set(enc_flags, 4))) | |
{ | |
enc_action = 1; | |
} | |
else if (bit_is_set(enc_flags, 1) && (bit_is_set(enc_flags, 3) || bit_is_set(enc_flags, 4))) | |
{ | |
enc_action = -1; | |
} | |
else if (bit_is_set(enc_flags, 3) && (bit_is_set(enc_flags, 1) || bit_is_set(enc_flags, 4))) | |
{ | |
enc_action = -1; | |
} | |
enc_flags = 0; // reset for next time | |
} | |
} | |
enc_prev_pos = enc_cur_pos; | |
if (enc_action > 0) | |
{ | |
draw(++displayedNumber); | |
digitalWrite(ledPin, HIGH); | |
} | |
else if (enc_action < 0) | |
{ | |
digitalWrite(ledPin, LOW); | |
draw(--displayedNumber); | |
} | |
else { | |
// do nothing | |
} | |
} | |
void draw(int number) { | |
display.clearDisplay(); | |
display.setTextSize(1); | |
display.setTextColor(WHITE); | |
display.setCursor(0,0); | |
display.println(number); | |
display.display(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment