/* ----------------------------------------------------------
* Encoder_KY-040_Upgraded_V2.ino
* without using interrupt for Encoder SW pin
*
* How to use Rotary Encoder KY-040 in Arduino
* to set a counter value. The incremental value
* can be changed by pressing the encoder button
* with the change value in units, tens, hundreds and thousands
*
* By : Rilles Eko Prianto
* ----------------------------------------------------------
*/
#include <LiquidCrystal_I2C.h>
// unchanged variables
int pinA = 2;
int pinB = 4;
int pinBtn = 5;
int bzr(8);
const String mul[4]={"UNITS", "TENS", "HUNDREDS", "THOUSANDS" };
const int MIN_COUNTER = 1;
const int MAX_COUNTER = 3000;
LiquidCrystal_I2C lcd(0x27, 16,2);
byte tanda[4][8] = {
{
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b01110
},
{
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b01110,
0b00000,
0b01110
},
{
0b00000,
0b00000,
0b00000,
0b01110,
0b00000,
0b01110,
0b00000,
0b01110
},
{
0b00000,
0b01110,
0b00000,
0b01110,
0b00000,
0b01110,
0b00000,
0b01110
}};
// variables that changed
float counter = 1;
volatile byte fired = 0;
volatile byte sA = 0;
int dir = 1; //-1 = turn left 1 = turn right
byte tekan = 0;
byte step = 0;
void setup() {
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
pinMode(pinBtn, INPUT_PULLUP);
pinMode(bzr, OUTPUT);
digitalWrite(bzr,0);
lcd.init();
// turn on the backlight
lcd.backlight();
for (int i=0;i<=3;i++) lcd.createChar(i, tanda[i]);
lcd.setCursor(0,0);
lcd.print(" HELLO, WELCOME");
lcd.setCursor(0,1);
lcd.print(" TO ARDUINO");
delay(1000);
lcd.clear();
// 0123456789012345
lcd.print("CNT: ");
lcd.print(counter,0);
lcd.setCursor(15,0);
lcd.write(0);
Serial.begin(115200);
// set interrupt for encoder CLK pin
attachInterrupt(digitalPinToInterrupt(pinA), isr, CHANGE);
sA = digitalRead(pinA);
// Serial.println("Arduino ready....");
delay(1000);
}
void loop() {
if (fired) {
// if (dir==1) Serial.print("-->>"); else Serial.print("<<--");
fired = 0;
counter += dir * (pow(10,step)); // using pow()--> return var type must be float
// the value of counter is limitted within range 0-3000
counter = constrain(counter, MIN_COUNTER, MAX_COUNTER);
lcd.setCursor(5,0);
lcd.print(" ");
lcd.setCursor(5,0);
lcd.print(counter,0);
// Serial.println(counter);
}
if (digitalRead(pinBtn)==LOW){tekan=1; delay(15);}
if (tekan){
step++;
bell();
if (step>3) step = 0;
// Serial.println(mul[step]);
lcd.setCursor(15,0);
lcd.write(step);
delay(100);
tekan = 0;
}
}
void isr(){
byte stateA = digitalRead(pinA);
byte stateB = digitalRead(pinB);
// if (stateA != sA){ // use this if running on physical Arduino
if (stateA != sA && stateA==LOW){ // use this if running on simulator
if (stateA != stateB) dir = 1; else dir = -1;
fired = 1;
}
sA = stateA ;
}
void bell(){
tone(bzr, 4000);
delay(40);
noTone(bzr);
}