Ok here its, its a simple countdown timer...
#include <Arduino.h>
#include <Wire.h>
#include "AiEsp32RotaryEncoder.h"
#include <TM1637Display.h>
#define output 16 // output for lights can by realy module or BJT,Mosfet
#define buzzer 25
#define runningLED 23 //Red, timer is running
#define readyLED 26 //Green, timer is ready
#define CLK 21 // TM1637 CLK
#define DIO 22 // TM1637 DIO
// Create a TM1637 display object
TM1637Display display(CLK, DIO);
// Timer settings
int minutes = 0;
int seconds = 0;
int setminutes = 0;
int setseconds = 0;
boolean timeState = false;
int testminutes = 5;
int testseconds = 7;
int HMS = 2; // 1 for Minnutes, 2 for seconds, boot with seconds selected
// I reversed the pin conections A and B, for rotating clockwise!!
#define ROTARY_ENCODER_A_PIN 18 //CLK right ------->>>>> Real connection is pin 27 <<<----- !!!!!!!!!!
#define ROTARY_ENCODER_B_PIN 27 //DT left ------->>>>> Real connection is pin 18 <<<----- !!!!!!!!!!
#define ROTARY_ENCODER_BUTTON_PIN 19 //SW switch
//depending on your encoder - try 1,2 or 4 to get expected behaviour
#define ROTARY_ENCODER_STEPS 4
//#define ROTARY_ENCODER_STEPS 4 = default
AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, -1, ROTARY_ENCODER_STEPS);
#define ROTARY_ENCODER_VCC_PIN -1 // put -1 if Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */
/
unsigned long shortPressAfterMiliseconds = 50; //how long short press shoud be. Do not set too low to avoid bouncing (false press events).
unsigned long longPressAfterMiliseconds = 500; //how long long press shoud be.
void buzz() {
digitalWrite(buzzer, HIGH);
delay(100);
digitalWrite(buzzer, LOW);
}
void on_button_short_click() {
if (!timeState) { // if false (running)
switch (HMS) {
case 1:
display.clear();
display.showNumberDecEx(testminutes, 0b01000000, true, 2, 4); // 05:__
HMS=2;
break;
case 2:
display.clear();
display.showNumberDecEx(testseconds, 0b01000000, true, 2, 2); // __:07
HMS=1;
break;
}
}
}
void on_button_long_click() {
// if ( minutes >0 or seconds >0) {
// if (minutes == 1 and seconds ==0) {
// minutes = 0;
// seconds = 60;
// }
// lcd.clear();
// lcd.setCursor(2, 0); lcd.print("Creating....");
// timeState = true;
// digitalWrite(output, HIGH);
// digitalWrite(runningLED, HIGH);
// digitalWrite(readyLED, LOW);
// delay(50);
// while (timeState == true) {
// int period = 1000;
// unsigned long time_now = 0;
// time_now = millis();
// while(millis() < time_now + period) { //wait approx. [period] ms}
// }
// seconds = seconds - 1;
// if (seconds == 0 and minutes >= 1) {
// seconds = 60;
// minutes = minutes - 1;
// }
// else if (minutes == 0 and seconds == 0) { //count down alarm
// while (timeState == true) {
// digitalWrite(output, LOW);
// digitalWrite(runningLED, LOW);
// digitalWrite(readyLED, HIGH);
// lcd.clear();
// lcd.setCursor(4, 0);
// lcd.print("Creation");
// lcd.setCursor(6, 1);
// lcd.print("Ready");
// HMS = 2;
// minutes = 0;
// seconds = 0;
// int x = 1;
// while (x < 11) { // 10x beeps if ready
// lcd.clear();
// lcd.setCursor(4, 0);
// buzz();
// lcd.print("Creation");
// lcd.setCursor(6, 1);
// lcd.print("Ready");
// delay(500);
// lcd.clear();
// x = x + 1;
// }
// minutes = setminutes;
// seconds = setseconds;
// timeState = false;
// lcd.clear();
// lcd.setCursor(2, 0);
// lcd.print("Set Seconds");
// lcd.setCursor(5, 1);
// lcd.print("00:00");
// }
// }
// lcd.setCursor(5, 1);
// if (minutes <= 9) {
// lcd.print("0");
// }
// lcd.print(minutes);
// lcd.print(":");
// lcd.setCursor(8, 1);
// if (seconds <= 9) {
// lcd.print("0");
// }
// lcd.print(seconds);
// }
// }
}
void handle_rotary_button() {
static unsigned long lastTimeButtonDown = 0;
static bool wasButtonDown = false;
bool isEncoderButtonDown = rotaryEncoder.isEncoderButtonDown();
//isEncoderButtonDown = !isEncoderButtonDown; //uncomment this line if your button is reversed
if (isEncoderButtonDown) {
// //Serial.print("+"); //REMOVE THIS LINE IF YOU DONT WANT TO SEE
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("+");
if (!wasButtonDown) {
// //start measuring
lastTimeButtonDown = millis();
}
//else we wait since button is still down
wasButtonDown = true;
return;
}
// button is up
if (wasButtonDown) {
// // Serial.println(""); //REMOVE THIS LINE IF YOU DONT WANT TO SEE
// // //click happened, lets see if it was short click, long click or just too short
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("Short click");
if (millis() - lastTimeButtonDown >= longPressAfterMiliseconds) {
on_button_long_click();
} else if (millis() - lastTimeButtonDown >= shortPressAfterMiliseconds) {
on_button_short_click();
}
}
wasButtonDown = false;
}
// ********** button handling ----
// ********** button handling ----
// ********** button handling ----
// ********** button handling ----
void rotary_loop() {
if (rotaryEncoder.encoderChanged()) {
digitalWrite(readyLED, LOW);
if (HMS == 1) {
minutes = rotaryEncoder.readEncoder();
if( minutes <1 ) {
minutes = 0;
}
}
else if (HMS == 2) {
seconds = rotaryEncoder.readEncoder();
}
}
handle_rotary_button();
}
void IRAM_ATTR readEncoderISR() {
rotaryEncoder.readEncoder_ISR();
}
void setup() {
Serial.begin(115200);
rotaryEncoder.begin();
rotaryEncoder.setup(readEncoderISR);
pinMode(output, OUTPUT);
pinMode(buzzer, OUTPUT);
digitalWrite(output, LOW);
pinMode(runningLED, OUTPUT);
pinMode(readyLED, OUTPUT);
digitalWrite(runningLED, LOW);
digitalWrite(readyLED, LOW);
display.clear();
display.setBrightness(3);
display.showNumberDecEx(0, 0b01000000, true); // 00:00
digitalWrite(buzzer, HIGH);
delay(100);
digitalWrite(buzzer, LOW);
delay(150);
digitalWrite(buzzer, HIGH);
delay(100);
digitalWrite(buzzer, LOW);
// Rotary acceleration introduced 25.2.2021.
// * in case range to select is huge, for example - select a value between 0 and 1000 and we want 785
// * without accelerateion you need long time to get to that number
// * Using acceleration, faster you turn, faster will the value raise.
// * For fine tuning slow down.
rotaryEncoder.disableAcceleration(); //acceleration is now enabled by default - disable if you dont need it
//rotaryEncoder.setAcceleration(250); //or set the value - larger number = more accelearation; 0 or 1 means disabled acceleration
//set boundaries and if values should cycle or not
//in this example we will set possible values between 1 and 60;
bool circleValues = true;
rotaryEncoder.setBoundaries(0, 60, circleValues); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
}
void loop() {
//in loop call your custom function which will process rotary encoder values
rotary_loop();
delay(50);
}