#define ENC_CLK 2
#define ENC_DT 3
#define ENC_BTN 4
#define DISP_CLK 5
#define DISP_DIO 6
#define BUZZER 8
#define ONE_SECOND_MS 1000
#define MAX_SECONDS 5999 // 99:99
#include <EncButton.h>
#include "GyverTM1637.h"
#include <ezBuzzer.h> // ezBuzzer library
/*
* Dev notes:
* - build for Arduino Nano with mega328p (old bootloader)
*/
//ezBuzzer buzzer(BUZZER); // create ezBuzzer object that attach to a pin;
// notes in the melody:
int melody[] = {
NOTE_E5, NOTE_B5, NOTE_E6};
// note durations: 4 = quarter note, 8 = eighth note, etc, also called tempo:
int noteDurations[] = {
4, 8, 2};
EncButton<EB_TICK, ENC_CLK, ENC_DT, ENC_BTN> enc; // энкодер с кнопкой
GyverTM1637 disp(DISP_CLK, DISP_DIO);
uint32_t Now, clocktimer;
boolean flag;
const uint8_t blank[] = {0x00, 0x00, 0x00, 0x00};
// int numberToDisplay = 500;
int numberToDisplay = 0;
boolean startCountdown = false;
long currentMillis = 0;
long prevMillis = 0;
long timeoutMillis = 0;
boolean sleepScreen = false;
void onDecrease()
{
if (startCountdown == false)
{
int decreaseStep = 1;
if (numberToDisplay > 120)
{
decreaseStep = 30;
}
else if (numberToDisplay > 20)
{
decreaseStep = 5;
}
numberToDisplay = max(numberToDisplay - decreaseStep, 0);
}
Serial.println("left");
}
void onIncrease()
{
disp.brightness( BRIGHT_TYPICAL);
sleepScreen = false;
if (startCountdown == false)
{
if (numberToDisplay >= 120)
{
numberToDisplay = min(numberToDisplay + 30, MAX_SECONDS);
}
else if (numberToDisplay >= 20)
{
numberToDisplay += 5;
}
else
{
numberToDisplay++;
}
}
Serial.print("right ");
Serial.println(numberToDisplay);
}
void onBtnRelease()
{
Serial.println("release");
startCountdown = true;
}
void onDblCick()
{
Serial.println("onDblCick");
}
bool pointFlag = false;
long pointFlagDelay;
void buzz() {
pinMode(BUZZER, OUTPUT);
tone(BUZZER, 1000);
delay(350);
noTone(BUZZER);
delay(150);
tone(BUZZER, 1000);
delay(350);
noTone(BUZZER);
pinMode(BUZZER, INPUT);
}
byte *convertSecondsToClockByteArray(int theNumber) {
byte *result = (byte*) malloc(2 * sizeof(byte));
result[0] = (byte) (theNumber / 60);
result[1] = (byte) (theNumber % 60);
return result;
}
void turnOffScreen() {
disp.displayByte(_empty, _empty, _empty, _empty);
disp.point(false);
}
void setup()
{
Serial.begin(9600);
// pinMode(BUZZER, OUTPUT);//initialize the BUZZER pin as an output
disp.clear();
disp.displayByte(_empty, _empty, _empty, _empty);
disp.brightness( BRIGHT_DARKEST ); // яркость, 0 - 7 (минимум - максимум)
currentMillis = millis();
prevMillis = currentMillis;
pointFlagDelay = currentMillis;
}
void loop()
{
currentMillis = millis();
enc.tick(); // опрос происходит здесь
// =============== ЭНКОДЕР ===============
// обычный поворот
if (enc.turn())
{
Serial.println("turn");
timeoutMillis = currentMillis;
sleepScreen = false;
// можно ещё:
Serial.println(enc.counter); // вывести счётчик
Serial.println(enc.fast()); // проверить быстрый поворот
Serial.println(enc.dir()); // вывести направление поворота
}
// "нажатый поворот"
if (enc.turnH())
Serial.println("hold + turn");
if (enc.left())
{
onDecrease();
}
if (enc.right())
{
onIncrease();
}
if (enc.leftH())
Serial.println("leftH"); // нажатый поворот налево
if (enc.rightH())
Serial.println("rightH"); // нажатый поворот направо
// =============== КНОПКА ===============
if (enc.press())
Serial.println("press");
if (enc.click())
Serial.println("click");
if (enc.release())
{
onBtnRelease();
}
if (enc.held())
Serial.println("held"); // однократно вернёт true при удержании
// if (enc.hold()) Serial.println("hold"); // будет постоянно возвращать true после удержания
if (enc.step())
Serial.println("step"); // импульсное удержание
if (enc.releaseStep())
Serial.println("release step"); // отпущена после импульсного удержания
// проверка на количество кликов
if (enc.hasClicks(1))
Serial.println("action 1 clicks");
if (enc.hasClicks(2))
onDblCick();
// вывести количество кликов
if (enc.hasClicks())
{
Serial.print("has clicks ");
Serial.println(enc.clicks);
}
if (startCountdown == true && currentMillis - pointFlagDelay >= ONE_SECOND_MS/2)
{
pointFlag = !pointFlag;
pointFlagDelay = currentMillis;
disp.point(pointFlag);
}
if (startCountdown == true && currentMillis - prevMillis >= ONE_SECOND_MS)
{
numberToDisplay = max(numberToDisplay - 1, 0);
prevMillis = currentMillis;
}
if (startCountdown || numberToDisplay != 0) {
disp.brightness( BRIGHT_TYPICAL);
}
if (startCountdown || numberToDisplay > 0) {
disp.brightness( BRIGHT_TYPICAL );
byte *result = convertSecondsToClockByteArray(numberToDisplay);
byte mins = result[0];
byte seconds = result[1];
// additional code
free(result);
disp.displayClock(mins, seconds);
timeoutMillis = currentMillis;
}
if (startCountdown && numberToDisplay == 0)
{
// finsih
startCountdown = false;
int length = sizeof(noteDurations) / sizeof(int);
// buzzer.playMelody(melody, noteDurations, length); // playing
buzz();
timeoutMillis = currentMillis;
turnOffScreen();
}
}
void runningSleepText() {
byte welcome_banner[] = {_S, _L, _E, _E, _P };
disp.runningString(welcome_banner, sizeof(welcome_banner), 200); // 200 это время в миллисекундах!
delay(200);
disp.clear();
}