//Arduino Code - Rotary Encoder w push button
/*
TODO:
-Edit mode <==
-second input (or more) |=> more possibilities => ability to scroll
-working sd card save
-should be easy?
-file handling
-undo/redo
*/
#include <BfButton.h>
#include "SimpleMenu.h"
#include <LiquidCrystal.h>
#include <LcdProgressBar.h>
int btnPin=6; //GPIO #3-Push button on encoder
int DT=5; //GPIO #4-DT on encoder (Output B)
int CLK=4; //GPIO #5-CLK on encoder (Output A)
BfButton btn(BfButton::STANDALONE_DIGITAL, btnPin, true, LOW);
BfButton btn2(BfButton::STANDALONE_DIGITAL, 3, true, LOW);
#define LCD_RS 12
#define LCD_EN 11
#define LCD_D4 10
#define LCD_D5 9
#define LCD_D6 8
#define LCD_D7 7
String userText = "";
int currentStateCLK;
int lastStateCLK;
int charPos = 0;
int cursorPos = 0;
int minCursorX;
int minCursorY;
int sensitivity = 0;
int rotarDelay = 0;
byte lcdNumCols = 16; // -- number of columns in the LCD
const int alphabetSize = 26;
char lowerCase[alphabetSize];
char upperCase[alphabetSize];
enum MenuStates
{
MainMenu,
Sensitivity,
Write
};
enum CharacterCase
{
Uppercase,
Lowercase,
};
CharacterCase CharCase = Lowercase;
MenuStates State = MainMenu;
LiquidCrystal lcd = LiquidCrystal(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
LcdProgressBar lpg(&lcd, 1, lcdNumCols);
void Foo(){
Serial.println("dostuff");
}
SimpleMenu MenuSub[3] = {
SimpleMenu("Sensitivity",setSensitivity),
SimpleMenu("Char map",Foo),
SimpleMenu("Credits",Credits)
};
SimpleMenu Menu[3] = {
SimpleMenu("Write mode",writeMode),
SimpleMenu("Settings",3,MenuSub),
SimpleMenu("Save to SD",Foo)
};
SimpleMenu TopMenu(3,Menu);
void setSensitivity()
{
btn.read();
State = Sensitivity;
drawPgsBar();
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(CLK,INPUT_PULLUP);
pinMode(DT,INPUT_PULLUP);
lcd.begin(16, 2);
for (int i = 0; i < alphabetSize; i++) {
lowerCase[i] = 'a' + i;
}
for (int i = 0; i < alphabetSize; i++) {
upperCase[i] = 'A' + i;
}
//Button settings
btn.onPress(pressHandler)
.onDoublePress(pressHandler) // default timeout
.onPressFor(pressHandler, 500); // custom timeout for 1 second
btn2.onPress(pressHandler2)
.onDoublePress(pressHandler2) // default timeout
.onPressFor(pressHandler2, 500); // custom timeout for 1 second
lpg.setMinValue(0);
lpg.setMaxValue(8);
lcd.println("Wordman 1.0");
lcd.setCursor(0,1);
lcd.print("lcd edition");
delay(1500);
lcd.clear();
TopMenu.begin(display);
}
//Button press hanlding function
void pressHandler (BfButton *btn2, BfButton::press_pattern_t pattern) {
switch (pattern) {
case BfButton::SINGLE_PRESS:
switch(State){
case MainMenu:
lcd.clear();
TopMenu.select();
break;
case Write:
switch(CharCase){
case Uppercase:
userText += upperCase[charPos];
break;
case Lowercase:
userText += lowerCase[charPos];
break;
}
cursorPos++;
Serial.println("Char moved");
Serial.println(userText);
break;
}
Serial.println("Single push");
break;
case BfButton::DOUBLE_PRESS:
Serial.println("Double push");
if(CharCase == Lowercase){
CharCase = Uppercase;
}
else{
CharCase = Lowercase;
}
break;
case BfButton::LONG_PRESS:
Serial.println("Long push");
State = MainMenu;
lcd.clear();
display(Menu);
TopMenu.back();
break;
}
}
void pressHandler2 (BfButton *btn, BfButton::press_pattern_t pattern) {
switch (pattern) {
case BfButton::SINGLE_PRESS:
Serial.println("Single");
break;
case BfButton::DOUBLE_PRESS:
Serial.println("double");
break;
case BfButton::LONG_PRESS:
Serial.println("long");
break;
}
}
void readRotar() {
bool currentStateCLK = digitalRead(CLK);
if (currentStateCLK != lastStateCLK && currentStateCLK == 1) {
if (rotarDelay < sensitivity) {
rotarDelay++;
} else {
rotarDelay = 0;
if (digitalRead(DT) != currentStateCLK) {
// Move right
switch (State) {
case MainMenu:
TopMenu.down();
break;
case Write:
charPos++;
Serial.println(charPos);
break;
case Sensitivity:
sensitivity++;
Serial.println(sensitivity);
lcd.setCursor(0, 0);
lcd.println(sensitivity);
//lpg.draw(sensitivity);
break;
}
} else {
// Move left
switch (State) {
case MainMenu:
TopMenu.up();
break;
case Write:
charPos--;
Serial.println(charPos);
break;
case Sensitivity:
sensitivity--;
Serial.println(sensitivity);
lcd.setCursor(0, 0);
lcd.println(sensitivity);
//lpg.draw(sensitivity);
break;
}
}
}
}
lastStateCLK = currentStateCLK;
}
void initLpg()
{
lcd.println(sensitivity);
lcd.setCursor(0,0);
lpg.draw(sensitivity);
Serial.println(sensitivity);
//-- Set min and max values
//-- Draw it: the frame
}
void drawPgsBar()
{
initLpg();
lpg.draw(sensitivity);
while(State == Sensitivity)
{
lpg.draw(sensitivity);
btn.read();
readRotar();
//if(!sensitivity){break;}
//-- draw progress bar
if (sensitivity > 8)
{
//--- Duration's over: delay and start again!
sensitivity = 0;
Serial.println(sensitivity);
lcd.setCursor(0,0);
lcd.println(sensitivity);
lpg.draw(sensitivity);
initLpg();
}
else if(sensitivity < 0)
{
sensitivity = 8;
Serial.println(sensitivity);
lcd.setCursor(0,0);
lcd.println(sensitivity);
lpg.draw(sensitivity);
}
}
}
void display(SimpleMenu *_menu)
{
if(State == MainMenu)
{
lcd.clear();
lcd.print(">");
lcd.print(_menu->name);
SimpleMenu *next = TopMenu.next();
if(next != NULL)
{
lcd.setCursor(1,1);
lcd.print(next->name);
}
}
}
void writeMode(){
if(State != Write){
State = Write;
lcd.clear();
lcd.setCursor(0, 0);
lcd.println(userText);
lcd.setCursor(cursorPos, 0);
}
if(State == Write){
readRotar();
btn.read();
if (charPos < 0 ) {
charPos = alphabetSize - 1;
}
else if (charPos >= alphabetSize + 1) {
charPos = 0;
}
switch(CharCase){
case Uppercase:
lcd.print(upperCase[charPos]);
break;
case Lowercase:
lcd.print(lowerCase[charPos]);
break;
}
lcd.setCursor(cursorPos, 0);
}
}
void Credits(){
lcd.setCursor(0,0);
lcd.println("Created by me");
delay(5000);
lcd.clear();
lcd.println("thanks to google");
delay(5000);
lcd.clear();
lcd.println("and study lesson");
lcd.setCursor(0,1);
lcd.print("for distracting");
delay(5000);
lcd.clear();
}
void loop() {
switch(State)
{
case MainMenu:
readRotar();
btn.read();
break;
case Write:
writeMode();
btn2.read();
break;
}
}