//*********************************************************
#include <GyverOLED.h>
GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;
//*********************************************************
#include <Adafruit_NeoPixel.h>
//#ifdef __AVR__
// #include <avr/power.h>
//#endif
//*********************************************************
#define pinBtnOk 10
#define pinBtnUp 12
#define pinBtnDown 11
#define pinRelay 3
#define pinLed 7
#define numPixels 8
Adafruit_NeoPixel pixels(numPixels, pinLed, NEO_GRB + NEO_KHZ800);
//*********************************************************
#include <Arduino.h>
#include <EncButton.h>
#define EB_DEB_TIME 20
Button btnUp(12);
Button btnDown(11);
Button btnOk(10);
VirtButton btnDouble; // виртуальная
byte stepIncrease=1;
byte brCoef=100;
//*********************************************************
#include "GyverTimer.h"
GTimer warmupTimer(MS); // создать миллисекундный таймер
GTimer workTimer(MS); // создать миллисекундный таймер
GTimer downTimer(MS); // создать миллисекундный таймер
GTimer displayTimer(MS); // создать миллисекундный таймер
int preTime=60;//количество секунд в минуте
uint32_t timerLength;
//*********************************************************
struct devSetting { //Общие свойства устройства
int warmUp=1;
int timeWork=5;
int timeDown=0;
int brightness=5;
} ds;
//*********************************************************
#include <EEManager.h> // подключаем либу
EEManager memory(ds);
byte menuLevel=0;
byte menuItem=0;
String menuList[]={" Прогрев "," Работа ", " Простой ", " Яркость ", "мин", "мин", "мин", "%"};
int menuValue[]={ds.warmUp, ds.timeWork, ds.timeDown, ds.brightness};
byte menuMapY[]={4,18,32,46};
byte menuMapX[]={8,70,110};
bool stateRelay=false;
void setup() {
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
blinkLed(255,0,0);
delay(3000);
warmupTimer.stop();
workTimer.stop();
downTimer.stop();
Serial.begin(115200);
Serial.println();
Serial.println("go party");
byte stat = memory.begin(0, 'b');
/*
Коды возврата:
0 - ключ совпал, данные прочитаны из епром
1 - ключ не совпал (первый запуск), данные записаны в епром
2 - ошибка, в епроме не хватает места
*/
menuValue[0]=ds.warmUp;
menuValue[1]=ds.timeWork;
menuValue[2]=ds.timeDown;
menuValue[3]=ds.brightness;
pinMode(pinRelay, OUTPUT);
// #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
// clock_prescale_set(clock_div_1);
// #endif
setupOLED();
// Serial.println(1000*preTime);
// Serial.println(ds.warmUp*60000);
// Serial.println(ds.timeWork*60000);
// Serial.println(ds.timeDown*60000);
// Serial.println(ds.warmUp*60000);
// timerLength=ds.warmUp*preTime*100*10;
// Serial.println(timerLength);
warmupTimer.setInterval(ds.warmUp*60000);
displayTimer.setInterval(30000);
blinkLed(128,0,128);
}
void loop() {
btnUp.tick();
btnDown.tick();
btnOk.tick();
// обработка одновременного нажатия двух кнопок
btnDouble.tick(btnUp, btnOk);
if (btnUp.click()) {
stepIncrease=1;
clickUp();
}
if (btnDown.click()) {
stepIncrease=1;
clickDown();
}
if (btnOk.click()) {
clickOk();
}
if (btnDouble.click()) {
stateRelay=!stateRelay;
useRelay();
}
if (btnDouble.step()) asm volatile("jmp 0x00");
if (btnUp.step()) {
stepIncrease=10;
clickUp();
}
if (btnDown.step()) {
stepIncrease=10;
clickDown();
}
if (warmupTimer.isReady()) {
warmupTimer.stop();
stateRelay=true;
useRelay();
workTimer.setInterval(ds.timeWork*60000);
}
if (workTimer.isReady()) {
if (ds.timeDown>0) {
workTimer.stop();
stateRelay=false;
useRelay();
downTimer.setInterval(ds.timeDown*60000);
}
}
if (downTimer.isReady()) {
if (ds.timeWork>0) {
downTimer.stop();
stateRelay=true;
useRelay();
workTimer.setInterval(ds.timeWork*60000);
}
}
if (displayTimer.isReady()) {
oled.setPower(false);
displayTimer.stop();
}
}
void useRelay() {
digitalWrite(3,stateRelay);
// Serial.print("Realy state: ");
// Serial.println(stateRelay);
if (stateRelay) blinkLed(0,255,0);
else blinkLed(0,0,255);
}
String getFormat(int val) {
String shiftX="";
if (val<=9) shiftX+=" ";
if (val<=99) shiftX+=" ";
if (val<=999) shiftX+=" ";
shiftX+=String(val);
return shiftX;
}
void menuWorked() {
if (menuItem==255) menuItem=3;
if (menuItem==4) menuItem=0;
if (menuLevel==0) {
for (int i=0;i<4;i++) {
oled.setCursorXY(menuMapX[0], menuMapY[i]);
if (menuItem==i) oled.invertText(true);
else oled.invertText(false);
oled.print(menuList[i]);
}
oled.update();
}
if (menuLevel==1) {
for (int i=0;i<4;i++) {
oled.setCursorXY(menuMapX[1], menuMapY[menuItem]);
oled.invertText(true);
oled.print(getFormat(menuValue[menuItem]));
}
oled.update();
}
}
void clickUp() {
if (!displayTimer.isEnabled()) {
setupOLED();
displayTimer.start();
return;
}
else displayTimer.reset();
if (menuLevel==0) {
menuItem--;
menuWorked();
}
if (menuLevel==1) {
menuValue[menuItem]+=stepIncrease;
if ((menuItem==2 || menuItem==1) && menuValue[menuItem]>1440) menuValue[menuItem]=1440;
if (menuItem==3 && menuValue[menuItem]>brCoef) menuValue[menuItem]=brCoef;
menuWorked();
}
}
void clickDown() {
if (!displayTimer.isEnabled()) {
setupOLED();
displayTimer.start();
return;
}
else displayTimer.reset();
if (menuLevel==0) {
menuItem++;
menuWorked();
}
if (menuLevel==1) {
menuValue[menuItem]-=stepIncrease;
//if (menuValue[menuItem]<1) menuValue[menuItem]=1;
if (menuItem<2 && menuValue[menuItem]<1) menuValue[menuItem]=1;
if (menuItem==2 && menuValue[menuItem]<=0) {
menuValue[menuItem]=0;
}
if (menuItem==3 && menuValue[menuItem]<0) menuValue[menuItem]=0;
menuWorked();
}
}
void clickOk() {
if (!displayTimer.isEnabled()) {
setupOLED();
displayTimer.start();
return;
}
else displayTimer.reset();
updateDisplay();
menuLevel++;
if (menuLevel==2) menuLevel=0;
if (menuLevel==255) menuLevel=1;
menuWorked();
ds.warmUp=menuValue[0];
ds.timeWork=menuValue[1];
ds.timeDown=menuValue[2];
ds.brightness=menuValue[3];
memory.updateNow();
if (menuItem==3) {
if (warmupTimer.isEnabled() && !stateRelay) blinkLed(128,0,128);
else
if (stateRelay) blinkLed(0,255,0);
else blinkLed(0,0,255);
}
}
void updateDisplay() {
if (menuLevel==1) {
oled.setCursorXY(menuMapX[1], menuMapY[menuItem]);
oled.invertText(false);
oled.print(getFormat(menuValue[menuItem]));
oled.update();
}
if (menuLevel==0) {
oled.setCursorXY(menuMapX[0], menuMapY[menuItem]);
oled.invertText(false);
oled.print(menuList[menuItem]);
oled.update();
}
}
void blinkLed(byte colorR, byte colorG, byte colorB) {
pixels.clear();
for(int i=0; i<numPixels; i++) {
pixels.setPixelColor(i, pixels.Color(ds.brightness*colorR/brCoef, ds.brightness*colorG/brCoef, ds.brightness*colorB/brCoef));
pixels.show();
}
}
void setupOLED() {
oled.init(); // инициализация
Wire.setClock(400000L);
oled.clear();
oled.update();
for (int i=0;i<4;i++) {
oled.setCursorXY(menuMapX[0], menuMapY[i]);
if (menuLevel==0 && menuItem==i) oled.invertText(true);
else oled.invertText(false);
oled.print(menuList[i]);
oled.setCursorXY(menuMapX[1], menuMapY[i]);
if (menuLevel==1 && menuItem==i) oled.invertText(true);
else oled.invertText(false);
oled.print(getFormat(menuValue[i]));
oled.invertText(false);
oled.setCursorXY(menuMapX[2], menuMapY[i]);
oled.print(menuList[i+4]);
}
oled.update();
}