#define modeBtn A5 // кнопка выбора режима
#define pinEn A2 // кнопка энкодера (обрабатывается не библиотекой а как простая кнопка)
#define ledPinBlue 5 // светодиод Синий МОЙКА
#define ledPinGreen 3 // светодиод зеленый ОБДУВ
#define ledPinRed 6 // светодиод Красный ЗАСВЕТКА
#define pinBuzz 7 // пин бузера
#define ledPinFan 8 // выход на обдув ( голубой диод имитирует включение ветиляторов )
#define uvPin 9 // выход на всветодиоды засветки ( фиолетовый диод имитирует включение засветки )
#define stepperDir 10 // A4988 DIR
#define stepperStep 11 // A4988 Step
#define displayDio A1 // TM1637 пин дисплея DIO
#define displayClk A0 // TM1637 пин дисплея CLK
#define encoderClk A3 // Энкодер CLK
#define encoderDT A4 // Энкодер DT
#define stepdivide 2 // Пин делителя шагов
#define WashTiime 10 // Время режима мойки по умолчанию минуты
#define DryTime 15 // Время режима сушки по умолчанию минуты
#define UvTime 5 // Время режима засветки по умочанию минуты
#include "GyverTimers.h" // Поделюченные библиотеки можно посмотреть во вкладке "Library Manager"
#include "GyverTM1637.h"
#include "GyverStepper2.h"
#include <EncButton.h>
GyverTM1637 disp(displayClk, displayDio); // CLK, DIO подключаем дисплей
GStepper2 <STEPPER2WIRE> stepper(400, stepperStep, stepperDir); // STEP, DIR подключаем шаговик
EncButton<EB_TICK, encoderClk, encoderDT > enc; // CLK, TD подключаем энкодер
bool dirstep ; // направление вращениия шаговика
bool rotor = 1 ; //
uint32_t Now; // для таймера обратного отсчета
boolean flag =0; // флаг таймера
bool buzz_flag=1; // флаг бузера должно (быть buzz )
bool flagbri = 1 ; // для изменения яркости таймера
unsigned long timbri; // для изменения яркости таймера
bool stready = 1; // для изменения яркости таймера
byte mode = 0; // выбор режима
unsigned long last_press; // for button
unsigned long last_pressEn; // for en button
bool button_flag = 0; // флаг кнопки
bool btnEn_flag; // flag encoder
int bri=7; // яркость дисплея
bool dir;
bool dirl;
byte mode1_flag = 0;
bool work =0;
int mins ; // минуты
int sek ; // секунды
uint8_t bit0 ; // 1 - 4 разряд дисплея
uint8_t bit1 ;
uint8_t bit2 ;
uint8_t bit3 ;
uint32_t tmr; // Для плавного мигания светодиодами
int val = 1;
bool dirled = true;
ISR(TIMER1_A) { // пускаем шаговик по таймеру
stepper.tick();
}
void setup() {
Serial.begin(9600);
//Timer1.setFrequency(3); // Высокоточный таймер 1 для первого прерывания, частота - 3 Герца
Timer1.setPeriod(100); // то же самое! Частота 3 Гц это период 333 333 микросекунд
//Timer1.setFrequencyFloat(4.22); // Если нужна дробная частота в Гц
Timer1.enableISR(); // Запускаем прерывание (по умолч. канал А)
pinMode(ledPinBlue, OUTPUT);
pinMode(ledPinGreen, OUTPUT);
pinMode(ledPinRed, OUTPUT);
pinMode(ledPinFan, OUTPUT);
pinMode(stepdivide, OUTPUT);
pinMode(modeBtn, INPUT_PULLUP);
pinMode(uvPin, OUTPUT);
digitalWrite(stepdivide, LOW);
digitalWrite(modeBtn, HIGH);
digitalWrite(ledPinRed, LOW);
digitalWrite(ledPinBlue, HIGH);
digitalWrite(ledPinFan, LOW);
digitalWrite(uvPin, LOW);
pinMode(pinEn, INPUT_PULLUP);
disp.clear();
disp.brightness(bri); // яркость, 0 - 7 (минимум - максимум)
disp.clear();
disp.point(1);
disp.displayByte(_8, _8, _8, _8);
delay(500);
stepper.setMaxSpeed(1800); // скорость движения к цели
stepper.setAcceleration(600); // ускорение
stepper.setTarget(0);
}
// LL OOOOOOO OOOOOOO PPPPPPP
// LL OO OO OO OO PP PP
// LL OO OO OO OO PP PP
// LL OO OO OO OO PPPPPP
// LLLLLLL OOOOOOO OOOOOOO PP
void loop() {
enc.tick(); // запуск обработки энкодера
buttonRead(); // запуск обработки кнопок
if (mode==0 && mode1_flag==0) // выбор режима работы мойки
{
mins=WashTiime;
sek=0;
displ();
digitalWrite(ledPinBlue, HIGH);
digitalWrite(ledPinGreen, LOW);
digitalWrite(ledPinRed, LOW);
mode1_flag = 1;
}
if (mode==1 && mode1_flag==1){ // выбор режима работы Сушка
mins=DryTime;
sek=0;
displ();
digitalWrite(ledPinBlue, LOW);
digitalWrite(ledPinGreen, HIGH);
digitalWrite(ledPinRed, LOW);
mode1_flag = 2;
}
if (mode==2 && mode1_flag==2){ // выбор режима работы засветка
mins=UvTime;
sek=0;
displ();
digitalWrite(ledPinBlue, LOW);
digitalWrite(ledPinGreen, LOW);
digitalWrite(ledPinRed, HIGH);
mode1_flag = 0;
}
if (mode==0 && work==1 ) // режим мойки
{
ledblinkB();
rotorFast();
timer();
buzz_flag=1;
digitalWrite(stepdivide, LOW); // выключение деления шагов
}
if (mode==1 && work==1 ) // режим обдува
{
ledblinkG();
rotorSlow();
timer();
digitalWrite(stepdivide, HIGH); // включение деления шагов
digitalWrite(ledPinFan , HIGH); // включает вентиляторы
buzz_flag=1;
}
if (mode==2 && work==1 ) // режим засвета
{
ledblinkR();
rotorSlow();
timer();
digitalWrite(stepdivide, HIGH);
digitalWrite(uvPin , HIGH); //включает засвет
buzz_flag=1;
}
if (enc.right() && mins>0) {
mins-- ;
displ();
} // поворот налево
if (enc.left() && mins<99) {
mins++ ; // поворот направо
displ();
}
if ( work == 0) {
if (mode == 0) digitalWrite(ledPinBlue, 255);
if (mode == 1) digitalWrite(ledPinGreen, 255);
if (mode == 2) digitalWrite(ledPinRed, 255);
val = 1;
dirled = true;
digitalWrite(uvPin , LOW); // выключаем засвет
digitalWrite(ledPinFan , LOW); // выключаем обдув
rotor = 1; // для повтоного запуска шаговика
stepper.stop();
//stepper.reset();
if (stepper.getStatus() == 0) {
brightness(); // мигаем дисплеем
disp.point(true);
}
}
}
// LL OOOOOOO OOOOOOO PPPPPPP EEEEEEEEE NNN NN DDDDDd
// LL OO OO OO OO PP PP EE NN N NN DD DD
// LL OO OO OO OO PP PP EEEEE NN N NN DD DD
// LL OO OO OO OO PPPPPP EE NN N NN DD DD
// LLLLLLL OOOOOOO OOOOOOO PP EEEEEEEEE NN NNN DDDDDd
// Вращение шаговика БЫСТРО туда сюда (режим мойки)
void rotorFast() {
stepper.setMaxSpeed(1800); // скорость движения к цели
stepper.setAcceleration(400);
if (mins==0 && sek<5) stepper.stop();
if (stepper.ready() || rotor==1 ) {
rotor=0;
dirstep=!dirstep;
stepper.setTarget(dirstep *100000);
}
}
// вращение медленно (сушка, засветка)
void rotorSlow() {
stepper.setMaxSpeed(50); // скорость движения к цели
stepper.setAcceleration(200);
if (stepper.ready()) stepper.reset(); // если вдруг докрутил до максимального - с
stepper.setTarget(2147483647); // тупо максимальное значение
}
//ВЫ ВОД НА ДИСПЛЕЙ
void displ() {
bit0 = mins/10;
bit1 = mins % 10;
bit2 = sek/10;
bit3 = sek % 10;
disp.display(bit0, bit1, bit2, bit3); // display taimer
}
// обработка кнопок
void buttonRead() {
bool btn = !digitalRead(modeBtn);
bool btnEn = !digitalRead(pinEn); // текеущее положение кнопки
if (btn == true && button_flag==0 && millis() - last_press > 400) {
last_press = millis();
tone(pinBuzz, 4000, 50);
button_flag = 1;
mode ++;
if (mode >2) mode =0;
work = 0;
}
if (btn == 0 && button_flag==1) {
button_flag = 0;
}
if ( btnEn==1 && btnEn_flag == 0 && millis()- last_pressEn > 400 ) {
last_pressEn = millis();
tone(pinBuzz, 5000, 50);
if (work==0) sek++; // Возвращаем украденную таймером секунду
btnEn_flag = 1;
work = !work;
}
if ( btnEn==0 && btnEn_flag == 1 ) {
btnEn_flag = 0;
}
}
// ТАЙМЕР
void timer() {
if (sek ==0 && mins>0) { sek=60; mins--; }
if (millis() - Now > 1000 && ((mins + sek) != 0) ) {
Now = millis();
sek--;
displ();
flag = !flag;
disp.point(flag); // выкл/выкл точки
}
if (mins <0) mins = 59;
if (mins==0 && sek == 0) { // если время закончилось
disp.point(1); // включаем точки
work=0;
if (buzz_flag==1) {
tone(pinBuzz, 5000, 500); // пищим об окончании
buzz_flag=0;
if (mode < 2 ) mode = mode + 1; // Переключаем на следующий режим
}
}
}
// МИГАЕМ ДИСПЛЕЕМ
void brightness() {
if ( sek == 0 && mins == 0 && bri != 0 && (millis()-timbri) > 100 && flagbri==1) {
timbri = millis();
bri--;
disp.brightness(bri);
if ( bri == 0 ) flagbri = 0;
}
if ( sek == 0 && mins == 0 && bri <= 7 && millis() - timbri > 100 && flagbri==0) {
bri++;
disp.brightness(bri);
timbri = millis();
if ( bri == 7 ) flagbri = 1;
}
if ( mins + sek !=0) disp.brightness(7);
}
// ПЛАВНО МИГАЕМ СВЕТОДИОДОМ
void ledblinkR() {
if (millis() - tmr >5) {
tmr=millis();
if ( dirled == true ) val++;
if ( dirled == false) val--;
if (val == 255 || val == 0) dirled = !dirled;
analogWrite(ledPinRed, val);
//Serial.println(val);
}
}
void ledblinkB() {
if (millis() - tmr > 5) {
tmr=millis();
if ( dirled == true ) val++;
if ( dirled == false) val--;
if (val == 255 || val == 0) dirled = !dirled;
analogWrite(ledPinBlue, val);
}
}
void ledblinkG() {
if (millis() - tmr > 5) {
tmr = millis();
if ( dirled == true ) val++;
if ( dirled == false) val--;
if (val == 255 || val == 0) dirled = !dirled;
analogWrite(ledPinGreen, val);
}
}
// Переключеие индикации режимов
void ledMode(){
if (mode==0) // выбор режима работы мойки
{
digitalWrite(ledPinBlue, HIGH);
digitalWrite(ledPinGreen, LOW);
digitalWrite(ledPinRed, LOW);
}
if (mode==1){ // выбор режима работы Сушка
digitalWrite(ledPinBlue, LOW);
digitalWrite(ledPinGreen, HIGH);
digitalWrite(ledPinRed, LOW);
}
if (mode==2){ // выбор режима работы засветка
digitalWrite(ledPinBlue, LOW);
digitalWrite(ledPinGreen, LOW);
digitalWrite(ledPinRed, HIGH);
}
}