#include "GyverButton.h"
#include "EEPROMextent.h"
#define LED_PIN 2
#define SENSOR_PIN 3
#define BTN_PIN SENSOR_PIN
#define EXEC_PIN 5
#define mode1_default 2000
#define mode2_default 4000
#define mode3_default 6000
struct MyObject {
uint16_t key;
uint16_t save_modes[3];
uint16_t nextaddr;
};
uint16_t modes[3] = {mode1_default, mode2_default, mode3_default};
uint16_t eeAddress=0;
MyObject eeBuffer;
GButton butt1(BTN_PIN);
int value = 0;
uint16_t t_start;
uint32_t t1;
byte runmode=1;
void blink(byte count=1, byte pin=LED_PIN, uint16_t on_delay=350, uint16_t off_delay=500){
for (byte i=0 ; i<count; i++) {
digitalWrite(LED_PIN,HIGH);
uint16_t t_sub=millis();
while ( 1 ) {
butt1.tick();
if (millis()-t_sub >= on_delay) {
digitalWrite(LED_PIN,LOW);
break;
}
}
t_sub=millis();
while (1) {
butt1.tick();
if (millis()-t_sub >= off_delay) {
break;
}
}
}
}
uint16_t get_delay(byte mode) {
bool record=false;
uint16_t t_start;
blink(5,LED_PIN,200,200);
blink(1,LED_PIN,500,1000);
while (1) {
butt1.tick();
if (!record && butt1.isClick()) { // in stendby mode waiting for click to start recording
// start recording period
t_start=millis();
record=true; // record mode on
}
if (record) { // in record mode
blink(mode,LED_PIN,100,0); // turn led on
} else { // in stendby mode
blink(mode,LED_PIN,100,100); // blink with delay 100
}
if (record && butt1.isClick()) { // in record mode waiting for a click to stop recording
return millis()-t_start; // return recorded value
}
}
}
void setup() {
pinMode(LED_PIN,OUTPUT);
pinMode(EXEC_PIN,OUTPUT);
attachInterrupt(BTN_PIN, isr, CHANGE);
EEPROMextent.readAnything(eeAddress, eeBuffer);
if (eeBuffer.key != 0xFF77) {
eeBuffer.key=0xFF77;
eeBuffer.save_modes[0]=mode1_default;
eeBuffer.save_modes[1]=mode2_default;
eeBuffer.save_modes[2]=mode3_default;
eeBuffer.nextaddr=0;
EEPROMextent.writeAnything(eeAddress, eeBuffer);
} else {
butt1.tick();
if (butt1.state()) {
// perform calibration
for (byte j=0; j<3; j++) {
eeBuffer.save_modes[j]=get_delay(j+1);
blink(j+1,LED_PIN,200,100);
blink(1,LED_PIN,5000,1000);
}
eeAddress=eeAddress+sizeof(eeBuffer);
eeBuffer.nextaddr=eeAddress;
eeBuffer.key=0xFF77;
EEPROMextent.writeAnything(eeAddress, eeBuffer);
blink(10);
}
}
butt1.setDebounce(80); // настройка антидребезга (по умолчанию 80 мс)
butt1.setTimeout(300);
}
void isr() {
butt1.tick(); // опрашиваем в прерывании, чтобы поймать нажатие в любом случае
}
void loop() {
butt1.tick(); // опрашиваем в скетче, иначе не будут работать проверки по времени!
// if (butt1.isClick()) Serial.println("Click"); // проверка на один клик
if (butt1.isPress()){
digitalWrite(EXEC_PIN,HIGH);
digitalWrite(LED_PIN,HIGH);
t1=millis();
}
if (butt1.isSingle()) {
runmode=1;
}
if (butt1.isDouble()) {
runmode=2;
}
if (butt1.isTriple()) {
runmode=3;
}
uint16_t timeout=eeBuffer.save_modes[runmode-1];
if (butt1.isRelease()) {
if (runmode==1 || runmode==2 || runmode==3) {
while (1) {
butt1.tick();
if (millis()-t1>timeout) {
digitalWrite(EXEC_PIN,LOW);
digitalWrite(LED_PIN,LOW);
break;
}
}
} else {
digitalWrite(EXEC_PIN,LOW);
digitalWrite(LED_PIN,LOW);
}
}
}