#define _LCD_TYPE 1
#include "LCD_1602_RUS_ALL.h"
#include "GyverEncoder.h" // Библиотека энкодера
#include <EEPROM.h> // Библиотека энергонезависимой памяти
#include <FastLED.h> // Библиотека RGB-ленты
#define PIN_CLKe 32 // ПИН энкодера
#define PIN_DTe 33 // ПИН энкодера
#define PIN_SWe 25 // ПИН энкодера
#define PIN_btn1 34 // ПИН концевика 1 (горизонтальный)
#define PIN_btn2 35 // ПИН концевика 2 (вертикальный)
#define PIN_DIRs1 27 // ПИН шаговика 1 (горизонтальный)
#define PIN_STEPs1 26 // ПИН шаговика 1 (горизонтальный)
#define PIN_DIRs2 12 // ПИН шаговика 2 (вертикальный) // boot fail if pulled high
#define PIN_STEPs2 18 // ПИН шаговика 2 (вертикальный)
#define PIN_ENs 13 // ПИН шаговиков (вертикальный)
#define MP3pin 17 // пин подключения 17-на RX , 16 на TX (не обязательно)
#define mp3Serial Serial2
#define PIN_rgb 19 // ПИН RGB-ленты
#define NUM_LEDS 3 // Диодов в RGB-ленте
// Настройки шаговиков
//int turnstep1 = 45; // Шагов оборотов на 1 сантиметр шаговика 1 (горизонтальный) - если ремень
int turnstep1 = 120; // Шагов оборотов на 1 сантиметр шаговика 1 (горизонтальный) - если винт как у вертикального
int turnstep2 = 1716; // Шагов оборотов на 1 сантиметр шаговика 2 (вертикальный)
int delaystep1 = 525; // Задержка между шагами в микросекундах шаговика 1 (горизонтальный)
int delaystep2 = 62; // Задержка между шагами в микросекундах шаговика 2 (вертикальный)
int directmotor1 = 0; // Направление шаговика 1 (0 - по часовой, 1 - против часовой)
int directmotor2 = 1; // Направление шаговика 2 (0 - по часовой, 1 - против часовой)
int lengthmotor1 = 0; // Перемещение каретки 1 в сантиметрах (горизонтальный)
int lengthmotor2 = 0; // Перемещение каретки 2 в сантиметрах (вертикальный)
uint32_t stepmotor1; // Шаги шаговика 1 (горизонтальный)
uint32_t stepmotor2; // Шаги шаговика 2 (вертикальный)
uint32_t timeportion = 4; // Время наливания порции в секундах
uint32_t timewait = 4; // Время ожидания между порциями бутылки в секундах
int width = 10; // Растояние между бутылками
float height = 2.9; // Высота до дозатора в сантиметрах
float subheight = 1.8; // Высота полунажатия в сантиметрах
// Параметры для запуска
int modeeeprom = 0; // Режим работы с памятью
int modergb = 0; // Режим работы RGB-ленты (0 - выкл, 1 - ожидание, 2 - наливание, 3 - готово)
int mode = 0; // Режим работы (0-2 - калибровка при старте, 3 - режим меню, 4 - наливание)
int modefill; // Режимы наливания
int menu = 1; // Раздел меню
int menubottle = 0; // Меню выбора бутылок коктейля
int menudrink = 1; // Меню количество коктейлей
int menuposition = 0; // Меню выбора позиции
int maxdrink = 10; // Возможных коктейлей
int modebottle = 6; // Количество бутылок
byte modeportion1[10][6]; // Порции 6 бутылок на 10 коктейлей
byte modeportion2[15][9]; // Порции 9 бутылок на 15 коктейлей
byte modeportion3[25][12]; // Порции 12 бутылок на 25 коктейлей
byte modeposition[12]; // Шагов до бутылок
byte counter; // Шаг радуги
int numberportion = 0; // Подсчет налитых порций с бутылки
// Таймеры
uint32_t timer_cursor; // Таймер мигания курсора
uint32_t timer_step1; // Таймер импульсов шаговика 1
uint32_t timer_step2; // Таймер импульсов шаговика 2
uint32_t timer_portion; // Таймер наливания порций
uint32_t timer_rgb; // Таймер RGB
uint32_t timer;
// Вспомогательные индексы
bool index_button1 = 0; // Индекс нажатия концевика 1
bool index_button2 = 0; // Индекс нажатия концевика 2
bool index_disp = 1; // Индекс отображения на экране
bool index_cursor = 0; // Индекс мигания курсора
bool index_motor1 = 0; // Индекс работы шаговика 1
bool index_motor2 = 0; // Индекс работы шаговика 2
bool index_step1 = 0; // Индекс шага шаговика 1
bool index_step2 = 0; // Индекс шага шаговика 2
bool index_finish1 = 0; // Индекс завершения задания шаговика 1
bool index_finish2 = 0; // Индекс завершения задания шаговика 2
bool index_rgb = 1; // Индекс отображения RGB-ленты
int index_enc_right = 0; // Индекс поворота энкодера направо
int index_enc_left = 0; // Индекс поворота энкодера налево
bool index_subheight = 0; // Индекс полунажатия
Encoder enc(PIN_CLKe, PIN_DTe, PIN_SWe); // Создание энкодера
LCD_1602_RUS lcd(0x27, 16, 2); // Создаем дисплей Создаем дисплей 0x3F, 0x27, 0x26(код, столбцов, строк)
CRGB leds[NUM_LEDS]; // Создаем RGB-ленту
uint8_t ready_ans = 0;
hw_timer_t *My_timer = NULL;
void setup() {
Serial.begin(115200);
FastLED.addLeds<WS2812, PIN_rgb, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // Инициализация RGB-ленты
FastLED.setBrightness(200); // Яркость RGB-ленты
setBlue();
pinMode(PIN_btn1, INPUT);
pinMode(PIN_btn2, INPUT);
pinMode(PIN_DIRs1, OUTPUT); // ПИН шаговика 1 (горизонтальный)
pinMode(PIN_STEPs1, OUTPUT); // ПИН шаговика 1 (горизонтальный)
pinMode(PIN_DIRs2, OUTPUT); // ПИН шаговика 2 (вертикальный)
pinMode(PIN_STEPs2, OUTPUT); // ПИН шаговика 2 (вертикальный)
pinMode(PIN_ENs, OUTPUT); // ПИН шаговика 2 (вертикальный)
digitalWrite(PIN_ENs, HIGH); // Выкл драйвер 1 (горизонтальный)
EEPROM.begin(1024);
if (EEPROM.read(80) != 6) { // Если первый запуск
EEPROM.write(80, 6); // Помечаем, что первый запуск был
EEPROM_update(); // Сохранение данных в энергонезависимую память
//EEPROM.updateByte(80, 0); // Стираю сохранение первого запуска (только для ТЕСТА)
}
EEPROM_read(); // Чтение данных из энергонезависимой памяти
mp3init();
setVolume(30);
lcd.init(); // Инициализация дисплея
lcd.clear(); // Очистка дисплея
lcd.display(); // Вкл отображение
lcd.backlight(); // Вкл подсветки
enc.setType(TYPE2);
My_timer = timerBegin(0, 24000, true);
timerAttachInterrupt(My_timer, &IT_34, true);
timerAlarmWrite(My_timer, 10, true);
timerAlarmEnable(My_timer);
setBlack();
if (mode == 0) { // Если калибровки при старте
index_motor1 = 1; // Вкл шаговик 1 (горизонтальный)
digitalWrite(PIN_ENs, LOW); // Вкл драйвер 1 (горизонтальный)
}
}
void loop() {
/*
lcd.setCursor(0,0);
lcd.print(digitalRead(PIN_btn1), DEC);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(digitalRead(PIN_btn2), DEC);
lcd.print(" ");
delay(100);
return;
*/
disp(); // Дисплей
motor1(); // Шаговый двигатель 1 (горизонтальный)
motor2(); // Шаговый двигатель 2 (вертикальный)
button1(); // Концевик 1 (горизонтальный)
button2(); // Концевик 2 (вертикальный)
rgb(); // Светодиодная лента
if (mode == 3) { // Если вся калибровка при старте закончена
enkoder(); // Энкодер
}
if (mode == 4) { // Если режим наливания
converter(); // Наливание
}
}
static portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
IRAM_ATTR void IT_34()
{
portENTER_CRITICAL_ISR(&timerMux);
if (index_motor1 == 0) { // Если не работает шаговик 1 (горизонтальный)
enc.tick(); // Опрос изменения энкодера
}
portEXIT_CRITICAL_ISR(&timerMux);
}