/******************
lcd
*******************/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
/******************
Rotary Encoder
*******************/
const unsigned int ROTARY_ENC_PIN_A = 2;
const unsigned int ROTARY_ENC_PIN_B = 3;
const unsigned int ROTARY_ENC_SWITCH = 4;
#define NO_CHANGE 0
#define TURN_CW 1
#define TURN_CCW 2
//Direction ┌─ ccw ─┐ N ┌─ cw ─┐
//Index 0 1 2 3 4 5 6 7 8
byte aState[] = {3, 2, 0, 1, 3, 2, 0, 1, 3};
byte lastState = 3;
volatile int count = 0;
unsigned int index = 4;
volatile byte encoderStatus = NO_CHANGE;
void readEncoderStatus() {
byte A_Output = digitalRead(ROTARY_ENC_PIN_A);
byte B_Output = digitalRead(ROTARY_ENC_PIN_B);
byte currState = (A_Output * 2) + B_Output;
if (currState != lastState) {
if (currState == aState[index + 1]) {
index++;
if (index == 8) {
count++;
index = 4;
encoderStatus = TURN_CW;
}
}
else if (currState == aState[index - 1]) {
index--;
if (index == 0) {
count--;
// Cannot be negative length
if (count < 0) {
count = 0;
}
index = 4;
encoderStatus = TURN_CCW;
}
}
lastState = currState;
}
}
void displayGetWireLength(int len) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Wire Len");
lcd.setCursor(0, 1);
lcd.print("in CMs: ");
lcd.print(len);
}
void displayGetStripLength(int len) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Strip Len");
lcd.setCursor(0, 1);
lcd.print("in CMs: ");
lcd.print(len);
}
/******************
states
There are lots of ways to create values to track your states...
//Defines
#define WELCOME_MSG 0
#define GET_WIRE_LENGTH 1
...
// Constants
const byte WELCOME_MSG = 0;
const byte GET_WIRE_LENGTH = 1;
...
But I prefer enumerations shown below
In the pointers course we talk about these - super handy!
*******************/
// Enumeration
enum STATES {
WELCOME_MSG, // this is automatically assigned 0
GET_WIRE_LENGTH, // this is automatically assigned 1
GET_STRIP_LENGTH, // this is automatically assigned 2
STRIP_WIRE, //this is automatically assigned 3
CUT_WIRE
};
// Global state variables
byte current_state = WELCOME_MSG; // What value do you think this holds right now?
int wire_length = 0;
int strip_length = 0;
//|--------------| -> 16 char measuring stick
void setup() {
// Setup up RE
attachInterrupt(digitalPinToInterrupt(ROTARY_ENC_PIN_A), readEncoderStatus, CHANGE);
attachInterrupt(digitalPinToInterrupt(ROTARY_ENC_PIN_B), readEncoderStatus, CHANGE);
pinMode(ROTARY_ENC_SWITCH, INPUT_PULLUP);
// Init the LCD
lcd.begin(16, 2);
/******************
WELCOME MESSAGE
*******************/
lcd.setCursor(0, 0);
lcd.print("Wire Stripper");
lcd.setCursor(0, 1);
lcd.print("Program");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Turn Knob to");
lcd.setCursor(0, 1);
lcd.print("choose values");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Press Knob");
lcd.setCursor(0, 1);
lcd.print("to select");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Press Knob");
lcd.setCursor(0, 1);
lcd.print("now to start!");
// Wait until user presses button
while (current_state == WELCOME_MSG) {
// Check if button pressed
if (!digitalRead(ROTARY_ENC_SWITCH)) {
current_state = GET_WIRE_LENGTH;
//debounce switch press
delay(100);
while (!digitalRead(ROTARY_ENC_SWITCH));
delay(100);
displayGetWireLength(wire_length);
}
} // End while
} // End setup
void loop() {
/******************
GET WIRE LENGTH
*******************/
if (current_state == GET_WIRE_LENGTH) {
// Did they enter a new value?
if (encoderStatus != NO_CHANGE) {
int tempCount;
noInterrupts();
tempCount = count;
interrupts();
encoderStatus = NO_CHANGE;
wire_length = count;
displayGetWireLength(wire_length);
}
// Check if button pressed
if (!digitalRead(ROTARY_ENC_SWITCH)) {
count = 0; // resest count for next state
current_state = GET_STRIP_LENGTH; //switch state
displayGetStripLength(strip_length);
//debounce switch press
delay(100);
while (!digitalRead(ROTARY_ENC_SWITCH));
delay(100);
}
}
/******************
GET STRIP LENGTH
*******************/
if (current_state == GET_STRIP_LENGTH) {
// Did they enter a new value?
if (encoderStatus != NO_CHANGE) {
int tempCount;
noInterrupts();
tempCount = count;
interrupts();
encoderStatus = NO_CHANGE;
strip_length = count;
displayGetStripLength(strip_length);
}
// Check if button pressed
if (!digitalRead(ROTARY_ENC_SWITCH)) {
count = 0; // resest count for next state
current_state = STRIP_WIRE; // This moves us to the next state
//debounce switch press
delay(100);
while (!digitalRead(ROTARY_ENC_SWITCH));
delay(100);
}
}
}