#define BTN_PIN 16 // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
#define LED1_PIN 25
#define LED2_PIN 26
#define LED3_PIN 27
#define EX_PIN 17
enum modesenum { mode1=1,mode2,mode3 };
//enum modesenum { mode1, mode2, mode3 };
//void printMyMenu(byte item_selected);
/*
void threeled_blink (byte count, int t1, int t2);
void led_run_right(byte count, int t);
void led_run_left(byte count, int t);
void led_run_and_back(byte count, int t);
void configMode(modesenum mode);
void welcome();
void configure();
void myoled(byte scale, byte x, byte y);
void stop_func();
void timerIsr();
*/
modesenum modes;
#include <Arduino.h>
//#include <ESP_EEPROM.h>
#include "GyverOLED.h"
#include "GyverButton.h"
#include "Blinker.h"
//#include <EEManager.h> // подключаем либу
Blinker led1(LED1_PIN);
Blinker led2(LED2_PIN);
Blinker led3(LED3_PIN);
GButton butt1(BTN_PIN);
GyverOLED<SSD1306_128x64, OLED_BUFFER> oled;
int value = 0;
static byte led_on=0;
static byte leds = 0;
byte selector=0;
static byte current_menu_item;
const byte character_width[]={ 6, 12, 18};
const byte maxchars[]={20, 10, 7};
char* menu[]={ "200мл", "300мл", "400мл"};
struct Data {
uint32_t modetime[3]= {2000, 4000, 6000};
};
Data data; // переменная, с которой мы работаем в программе
//EEManager memory(data); // передаём нашу переменную (фактически её адрес)
// можно задать таймаут обновления, по умолч. 5 секунд (5000мс)
//EEManager memory(data, 1000);
void threeled_blink (byte count, int t1, int t2) {
digitalWrite(LED1_PIN, HIGH);
digitalWrite(LED2_PIN, HIGH);
digitalWrite(LED3_PIN, HIGH);
delay(t1);
digitalWrite(LED1_PIN, LOW);
digitalWrite(LED2_PIN, LOW);
digitalWrite(LED3_PIN, LOW);
delay(t2);
}
void led_run_right(byte count, int t) { // біжучий вогник count - кількість, t - таймаут
for (int i=0; i<count; i++) {
digitalWrite(LED2_PIN, LOW);
digitalWrite(LED3_PIN, LOW);
digitalWrite(LED1_PIN, HIGH);
delay(t);
digitalWrite(LED2_PIN, HIGH);
digitalWrite(LED1_PIN, LOW);
delay(t);
digitalWrite(LED3_PIN, HIGH);
digitalWrite(LED2_PIN, LOW);
delay(t);
digitalWrite(LED3_PIN, LOW);
delay(t);
}
}
void led_run_left(byte count, int t) {
for (int i=0; i<count; i++) {
digitalWrite(LED1_PIN, LOW);
digitalWrite(LED2_PIN, LOW);
digitalWrite(LED3_PIN, HIGH);
delay(t);
digitalWrite(LED2_PIN, HIGH);
digitalWrite(LED3_PIN, LOW);
delay(t);
digitalWrite(LED1_PIN, HIGH);
digitalWrite(LED2_PIN, LOW);
delay(t);
digitalWrite(LED1_PIN, LOW);
delay(t);
}
}
void led_run_and_back(byte count, int t) {
led_run_right(count,t);
led_run_left(count,t);
}
void switch_led(byte id,bool res=true) {
switch (id) {
case 1: digitalWrite(LED1_PIN, res);
break;
case 2: digitalWrite(LED2_PIN, res);
break;
case 3: digitalWrite(LED3_PIN, res);
break;
}
}
void myoled(byte scale=2, byte x=0, byte y=0) {
oled.autoPrintln(true);
oled.clear();
oled.home();
oled.setScale(scale);
oled.setCursor(x,y);
}
void led_null(byte id) {
switch(id) {
case 1: digitalWrite(LED1_PIN,LOW);
break;
case 2: digitalWrite(LED1_PIN,LOW);
break;
case 3: digitalWrite(LED3_PIN,LOW);
break;
case 0: digitalWrite(LED1_PIN,LOW);
digitalWrite(LED2_PIN,LOW);
digitalWrite(LED3_PIN,LOW);
break;
}
}
void led_blink(byte id, byte count=1, int t1=300, int t2=500) {
switch(id) {
case 1: led1.blink(count,t1,t2);
break;
case 2: led2.blink(count,t1,t2);
break;
case 3: led3.blink(count,t1,t2);
break;
}
}
void led_inc() {
led_null(0);
digitalWrite(LED1_PIN,HIGH);
delay(300);
digitalWrite(LED2_PIN,HIGH);
delay(300);
digitalWrite(LED3_PIN,HIGH);
delay(1500);
led_null(0);
}
/*
void configMode(modesenum mode){
led1.blink(3,500,300);
digitalWrite(LED1_PIN,HIGH);
led2.blink(3,500,300);
digitalWrite(LED2_PIN,HIGH);
led3.blink(3,500,300);
digitalWrite(LED3_PIN, HIGH);
delay(500);
digitalWrite(LED1_PIN,LOW);
digitalWrite(LED2_PIN,LOW);
digitalWrite(LED3_PIN,LOW);
if (mode=mode1) digitalWrite(LED1_PIN,HIGH);
while (true) { // wait for key
butt1.tick();
if (butt1.isSingle()) break; // 1 click - exit
if (butt1.isHolded()) { // hold
uint32_t flowtimer=millis();
digitalWrite(EX_PIN,HIGH); // start motor
while (true) { // wait for key
butt1.tick();
if (butt1.isClick()) { // 1 click - stop and calculate
digitalWrite(EX_PIN,LOW); // stop motor
uint32_t result=millis()-flowtimer;
digitalWrite(LED1_PIN,HIGH);
delay(100);
digitalWrite(LED2_PIN,HIGH);
delay(100);
digitalWrite(LED3_PIN,HIGH);
delay(100);
switch(mode) {
case mode1: data.modetime[0]=result;
break;
case mode2: data.modetime[1]=result;
break;
case mode3: data.modetime[2]=result;
break;
}
// memory.update(); // write data to EEPROM
}
while (true) {
led_run_and_back(1,200);
butt1.tick();
if (butt1.isClick()) break;
}
}
}
}
}
*/
uint8_t print_center(char msg[], byte scale=1, byte line=0) {
// if (strlen(msg)*character_width[scale-1]<=128) {
// Serial.print("scale=");
//Serial.println(scale);
// Serial.print("msg=");
// Serial.println(msg);
// Serial.print("strlen(msg)=");
// Serial.println(strlen(msg));
byte startpos=byte((128-strlen(msg)*character_width[scale-1])/2);
oled.setScale(scale);
oled.setCursor(startpos,line);
oled.print(msg);
oled.update();
// } else {
// Serial.println(strlen(msg)*character_width[scale-1]);
// Serial.println("Message too long");
// return 100;
// }
}
void welcome() {
oled.clear();
oled.home();
oled.setScale(1);
oled.setCursor(40,1);
oled.print("Welcome");
oled.setCursor(56,3);
oled.print("to");
oled.setCursor(10,5);
oled.setScale(2);
oled.invertText(true);
oled.print(" DrinkMix ");
oled.invertText(false);
oled.setScale(1);
oled.setCursor(20,8);
oled.print(F("by Arest, 2024"));
oled.update();
delay(1500);
// oled.clear();
// oled.home();
// oled.update();
}
void myheader() {
oled.clear();
oled.setCursor(10,1);
oled.setScale(2);
oled.invertText(true);
oled.println(" DrinkMix ");
oled.invertText(false);
oled.update();
}
void printMyMenu(byte item_selected=0) {
Serial.println("Print menu");
Serial.println(item_selected);
oled.clear();
oled.home();
oled.setScale(1);
oled.print(F("Виберiть напiй:"));
for (byte m=0; m<sizeof(menu);m++) {
oled.setScale(2);
oled.setCursor(20,2*(m+1));
Serial.print("m=");
Serial.println(m);
if (item_selected=m+1) oled.invertText(true);
oled.print(menu[m]);
oled.invertText(false);
oled.update();
}
printSelector(item_selected);
}
void printSelector(byte pos) {
Serial.println("Print selector");
byte bitpos=0;
switch (pos) {
case 1: Serial.println("Selected mode 1");
bitWrite(bitpos,0,1);
break;
case 2: Serial.println("Selected mode 2");
oled.setCursor(0,4);
bitWrite(bitpos,1,1);
break;
case 3: Serial.println("Selected mode 3");
oled.setCursor(0,6);
bitWrite(bitpos,2,1);
break;
case 0: Serial.println("Selected mode 0 - clearing all.");
oled.textMode(!bitRead(bitpos,0));
oled.setCursor(0,2);
oled.print(">");
oled.textMode(!bitRead(bitpos,1));
oled.setCursor(0,4);
oled.print(">");
oled.textMode(!bitRead(bitpos,2));
oled.setCursor(0,6);
oled.print(">");
oled.update();
oled.textMode(BUF_ADD);
}
oled.setCursor(0,2);
oled.textMode(!bitRead(bitpos,0));
oled.print(">");
oled.setCursor(0,4);
oled.textMode(!bitRead(bitpos,1));
oled.print(">");
oled.setCursor(0,6);
oled.textMode(!bitRead(bitpos,2));
oled.print(">");
oled.textMode(BUF_ADD);
current_menu_item=pos;
oled.update();
}
/*
for (byte l=0; l<8 ; l++) {
for (byte x=0; x<128; x+=8) {
oled.setCursor(x,l);
oled.drawByte(i);
oled.update();
i++;
delay(20);
}
}
}*/
/*
void configure() {
while (true) {
butt1.tick(); // опрашиваем в скетче, иначе не будут работать проверки по времени!
if (butt1.isClick()) {
if (butt1.isSingle()) { // 1 click - exit
break;
}
if (butt1.isHold()) { // Button hold - start configuration
while (true) {
if (butt1.isClick()) {
if (butt1.isSingle()) { // configure mode 1
}
if (butt1.isDouble()) { //configure mode 2
}
if (butt1.isTriple()) { // configure mode 3
}
}
}
}
}
}
}
*/
/*
void stop_func() {
myoled();
// for (byte pos=0; pos<16; pos++) {
oled.setScale(2);
oled.setCursor(0,0);
oled.print(" DrinkMix ");
oled.fastLineH(0,80,115);
oled.setScale(1);
oled.rect(12,17,107,19,OLED_FILL);
oled.update();
delay(1500);
oled.clear();
oled.update();
oled.rect(70,0,127,24,OLED_STROKE);
oled.setCursorXY(75,9);
oled.print("DrinkMix");
// oled.setCursor(0,4);
// oled.print("(c) by Arest, 2024");
oled.update();
delay(1200);
oled.clear();
oled.setCursorXY(74,6);
// oled.invertText(true);
oled.print("DrinkMix");
// oled.invertText(false);
oled.setCursor(0,0);
oled.print("Select");
oled.setCursor(0,1);
oled.print("your drink");
oled.setContrast(250);
oled.setScale(2);
oled.setCursor(0,4);
oled.print(" * DRINK 1");
oled.setScale(1);
oled.setCursor(0,7);
oled.print("01234567890123456789");
oled.update();
delay(1000);
oled.fastLineH(51,0,127); // (a,b,c) a - висота лінії, b - початок, с - кінець
oled.update();
oled.setContrast(120);
delay(3000);
oled.autoPrintln(true);
for (;;);
// }
}
*/
//##############################################
//############## SETUP #######################
//##############################################
void setup() {
pinMode(BTN_PIN, INPUT_PULLUP);
pinMode(2,OUTPUT);
oled.init();
Serial.begin(115200);
Serial.println("Hello, ESP32!");
welcome();
// show_chars();
/*
EEPROM.begin(sizeof(Data));
//stop_func();
if(EEPROM.percentUsed()>=0) {
EEPROM.get(0, data);
}
*/
//welcome();
// stop_func();
// byte stat = memory.begin(0, 'Q');
/*
Коды возврата:
0 - ключ совпал, данные прочитаны из епром
1 - ключ не совпал (первый запуск), данные записаны в епром
2 - ошибка, в епроме не хватает места
*/
/*
oled.autoPrintln(true);
myoled();
oled.println("STD MODE");
delay(1000);
myoled();
oled.println("To configure");
oled.println("triple press a key");
while (true) {
butt1.tick();
if (butt1.isTriple()) {
configure();
}
}
myoled();
oled.println("ERROR!");
oled.println("NO SPACE");
oled.println("ON EEPROM");
//led1.blink(3,500,300);
//led3.blink(3,500,300);
//led3.blink(3,500,300);
*/
// выведем в порт всё содержимое блока памяти, включая ключ
/*
for (uint16_t i = memory.startAddr(); i < memory.endAddr() + 1; i++)
Serial.write(EEPROM.read(i));
Serial.println();
*/
//data.val = 'X'; // изменим данные в переменной
//memory.update(); // отложим обновление
// примечание: если нужно создать ещё один блок следующим в памяти -
// запускаем его на адресе memory.endAddr() + 1, это первый
// свободный байт после первого блока
attachInterrupt(1, isr, CHANGE);
butt1.setDebounce(80); // настройка антидребезга (по умолчанию 80 мс)
butt1.setTimeout(300); // настройка таймаута на удержание (по умолчанию 500 мс)
digitalWrite(2,HIGH);
// led_run_and_back(1,500);
led_inc();
myheader();
oled.setScale(2);
oled.invertText(false);
oled.setCursor(0,5);
print_center("Press",2,3);
print_center("a key!",2,5);
// oled.println("Press");
// oled.println("a key!");
/* for (;;) {
butt1.tick();
if (butt1.isSingle()) {
oled.clear();
oled.home();
break;
printMyMenu(1);
printSelector(1);
}
}
*/
}
void isr() { // прерывание таймера
butt1.tick(); // отработка теперь находится здесь
}
uint32_t start_t;
//##############################################
//############## LOOP #######################
//##############################################
void loop() {
led1.tick();
led2.tick();
led3.tick();
butt1.tick(); // опрашиваем в скетче, иначе не будут работать проверки по времени!
//printSelector(led_on);
if (butt1.isClick()) {
Serial.println("Click"); // проверка на один клик
// if (butt1.isSingle()) {
led_on++;
Serial.print("Selected mode ");
Serial.println(led_on);
if (led_on>3) led_on=1;
current_menu_item=led_on;
printMyMenu(led_on);
printSelector(led_on);
// leds=0;
leds=bit(led_on-1);
digitalWrite(LED1_PIN, bitRead(leds,0));
digitalWrite(LED2_PIN, bitRead(leds,1));
digitalWrite(LED3_PIN, bitRead(leds,2));
delay(100);
}
if (butt1.isHolded() && led_on!=0 ) {
Serial.println("HOLD detected!");
myheader();
oled.println("Наливаю");
oled.println(menu[led_on]);
led_blink(led_on,3);
digitalWrite(EX_PIN, HIGH);
uint32_t start_t=millis();
for (;;) {
if (millis()-start_t > data.modetime[led_on-1]) {
digitalWrite(EX_PIN,LOW);
// show_chars();
led_inc();
break;
}
}
}
if (butt1.isTriple()) Serial.println("Triple"); // проверка на тройной клик
if (butt1.hasClicks()) // проверка на наличие нажатий
Serial.println(butt1.getClicks()); // получить (и вывести) число нажатий
// if (butt1.isPress()) Serial.println("Press"); // нажатие на кнопку (+ дебаунс)
// if (butt1.isRelease()) Serial.println("Release"); // отпускание кнопки (+ дебаунс)
// if (butt1.isHolded()) Serial.println("Holded"); // проверка на удержание
//if (butt1.isHold()) Serial.println("Hold"); // возвращает состояние кнопки
// delay(1000); // чилим
// put your main code here, to run repeatedly:
delay(10); // this speeds up the simulation
}