Наливатор - автоматизированная машина, которая будет разливать алкоголь по стопкам.

sarsab
Offline
Зарегистрирован: 23.01.2020

у Романа готовый модуль энкодера,там все проще все разведено на плате.

Носмас
Offline
Зарегистрирован: 13.06.2020

И вот ещё что заметил: судя по приветственному экрану при включении "ну начали" - обе прошивки это модификации одной и той же

raven78
Offline
Зарегистрирован: 03.11.2019

Я например паял голый энкодер без всякой обвязки,  подтяжка есть в самой ардуино

sarsab
Offline
Зарегистрирован: 23.01.2020

Носмас пишет:

И вот ещё что заметил: судя по приветственному экрану при включении "ну начали" - обе прошивки это модификации одной и той же

Возможно, все таки тему начинали Павел и Алексей,а Роман доводит все как можно лучше,и по своей схеме и разными доп опциями,так как более никто не помогает.

Носмас
Offline
Зарегистрирован: 13.06.2020
Носмас
Offline
Зарегистрирован: 13.06.2020

дубль

sarsab
Offline
Зарегистрирован: 23.01.2020

Носмас пишет:

 

извините за ссылки, не могу изображение вставить (ссылки первые попавшие)

сделай первый как на картинке которую я дал выше,это схема Алексея,поставь резисторы и подключи как там нарисовано,скетч потом ставь какой угодно из этой темы

raven78
Offline
Зарегистрирован: 03.11.2019

Носмас пишет:

дубль

Не надо несколько раз на кнопку нажимать))). Тормозит форум

Для этих энкодеров нужно вести все пять проводов, для голого энкодера четыре. Но разницы никакой, у меня такой же , судя по всему второй тип. Кстати в моей прошивке нет смены типа энкодера, по умолчанию второй тип, есть только смена направления.

Носмас
Offline
Зарегистрирован: 13.06.2020

неделю я изучаю вашу прошивку в 20-х есть, в 30-х нет.

в сущности форум читаю с прошлого лета наверно, но общаюсь иногда с вами в ватсапе )))

raven78
Offline
Зарегистрирован: 03.11.2019

Я ещё чего забыл, если отсутствует всё что связано с акб, то в скетче нужно закомментировать строку

#define BAT_MONITOR_ON 

сделать так и прошить

//#define BAT_MONITOR_ON 

Мониторинг может давать такой эффект, т.к. отсутствует обвязка  на пине А7 ардуино и не подключен АКБ

Носмас
Offline
Зарегистрирован: 13.06.2020

Поздно, проверить не смогу с ходу, все провода отключил (я уже и думать не знаю что: провода длинноваты, и 90% на разъемах. были...

Носмас
Offline
Зарегистрирован: 13.06.2020

Начал паять с ноля.

Снова подключены только энкодер, дисплей и светодиоды.

Сейчас перемещение чёткое, спасибо.

Сейчас при включении идёт перемаргивание диодов и остаётся гореть 4-е место, 3-е моргает как неконтакт, но контакт там норм.

Ленту сейчас перемою спиртом, других причин не вижу, хотя флюс может в колодке на ардуино

Да и вообще батюшку что ли вызвать :)))

Носмас
Offline
Зарегистрирован: 13.06.2020

это не флюс.

Помыл диоды, ардуинку - ровно тоже самое, причем на 21-й прошивке и на 36-й.

При чём ардуинка думает что там стоит рюмка, значит ей даёт сигнал голая её нога.

Может там что то должно уже быть + или -?

aleks_raichel
Offline
Зарегистрирован: 27.08.2019

Носмас пишет:

это не флюс.

Помыл диоды, ардуинку - ровно тоже самое, причем на 21-й прошивке и на 36-й.

При чём ардуинка думает что там стоит рюмка, значит ей даёт сигнал голая её нога.

Может там что то должно уже быть + или -?

Может попробовать ардуинку поменять? Непомню уже точно, какой то глюк тоже был, поменял ардуинку, все встало на свои места.

Носмас
Offline
Зарегистрирован: 13.06.2020

aleks_raichel пишет:

Носмас пишет:

это не флюс.

Помыл диоды, ардуинку - ровно тоже самое, причем на 21-й прошивке и на 36-й.

При чём ардуинка думает что там стоит рюмка, значит ей даёт сигнал голая её нога.

Может там что то должно уже быть + или -?

Может попробовать ардуинку поменять? Непомню уже точно, какой то глюк тоже был, поменял ардуинку, все встало на свои места.

менял, не помогает

Носмас
Offline
Зарегистрирован: 13.06.2020

Носмас пишет:

это не флюс.

Помыл диоды, ардуинку - ровно тоже самое, причем на 21-й прошивке и на 36-й.

При чём ардуинка думает что там стоит рюмка, значит ей даёт сигнал голая её нога.

Может там что то должно уже быть + или -?

отвечу сам себе. там по схеме по резюку стоит по 10к с минуса

Носмас
Offline
Зарегистрирован: 13.06.2020

кто использовал ttp229 выпаивали коденсаторы и если выпаивали то по сколько (а то уже пара версий гуляет по сети)

Носмас
Offline
Зарегистрирован: 13.06.2020

заработала связка ардуино, дисплей, светодиоды и сенсоры с ttp229/

c ttp получилась инверсия. т.е. при включении светодиоды загораются, ставишь рюмки и "льёт" как раз в пустые места.

в 36 прошивке есть строка

#define SWITCH_LEVEL 1    // концевики 1 - высокий сигнал при замыкании, 0 - низкий

где, как я понимаю, нужно поменять 1 и 0.

36 прошивка мне непонятна, например "один за всех" :), а в 21 не увидел такой строки

Есть где нибудь описание аппарата: как калибровать серву и насос (в меню есть, но не пробывал) и пр.?

а вообще - спасибо огромное!

raven78
Offline
Зарегистрирован: 03.11.2019

На гитхабе есть небольшая инструкция в текстовике, ну а так пощёлкайте сами везде , всё там интуитивно понятно

 

 

Носмас
Offline
Зарегистрирован: 13.06.2020

raven78 пишет:

На гитхабе есть небольшая инструкция в текстовике, ну а так пощёлкайте сами везде , всё там интуитивно понятно

Аппарат получился сложный :)) Вам нужно уже видеоинструкцию по настройке и использованию аппарата

aleksandr1612
aleksandr1612 аватар
Offline
Зарегистрирован: 18.12.2017

raven78 пишет:

На гитхабе есть небольшая инструкция в текстовике, ну а так пощёлкайте сами везде , всё там интуитивно понятно


Роман, доброе утро, скажите пожалуйста, для того, чтобы использовать новые версии ваших прошивок для mega 2560, необходимо скетч пере собирать или есть проще варианты? Конечно, то что вы сделали скетч для mega 2560 работает отлично, за что вам огромная благодарность, и в принципе можно на нем и остаться, просто интересно на сколько это сложно)))

raven78
Offline
Зарегистрирован: 03.11.2019

Доброго. Сделал под мегу, все изменения пришли от 38 скетча. По возможности буду и под мегу вносить изменения.

Можно смотреть изменения например notepad++( советую поставить, очень годная вещь) и плагин к нему compare(гугл в помощь). Открываем в нём два файла от разных плат и сравниваем. Но на меге есть некоторые специфические моменты и надо их знать, сравнить действующие две одинаковые рабочие  версии от разных плат и запомнить чем они уже должны отличаться.

На гитхабе тоже можно смотреть какие изменения я внёс, нотам мне показалось как то сложно всё

ГИТ

 

VICLER
Offline
Зарегистрирован: 30.12.2019

microsoft visual studio code очень классный лёгкий редактор (и не только). Там уже есть встроенная возможность сравнивать два файла. К тому же кроссплатформенность, подсветка синтаксиса, подсказки, интеграция github. С фреймворком platformIO так заменяет среду arduino ide

aleksandr1612
aleksandr1612 аватар
Offline
Зарегистрирован: 18.12.2017

raven78 пишет:

Доброго. Сделал под мегу, все изменения пришли от 38 скетча. По возможности буду и под мегу вносить изменения.

Можно смотреть изменения например notepad++( советую поставить, очень годная вещь) и плагин к нему compare(гугл в помощь). Открываем в нём два файла от разных плат и сравниваем. Но на меге есть некоторые специфические моменты и надо их знать, сравнить действующие две одинаковые рабочие  версии от разных плат и запомнить чем они уже должны отличаться.

На гитхабе тоже можно смотреть какие изменения я внёс, нотам мне показалось как то сложно всё

ГИТ

 

Благодарю, воспользуюсь вашим советом и буду изучать, самому интересно все освоить, чтобы вас не отвлекать и не дергать лишний раз)))!

Gridzilla
Offline
Зарегистрирован: 25.10.2019

Подумалось тут сделать сон для ардуино. Наткнулся на это https://tsibrov.blogspot.com/2018/02/arduino-power-down.html Кто-нибудь реализовывал подобное? Реально помогает? Или может просто вырубить дисплей и надписи? Он жрет не мало. 

Или может не стоит заморачиваться? Тут светик на ардуине, светики на датчиках (у меня KY-032) тоже жрут свою порцию с АКБ. Или же тут сон так, как бы в виде игрушки, мол засиделись, пора налить.... Кстати, можно вместо сна так и сделать по таймеру... Хм.. 

Gridzilla
Offline
Зарегистрирован: 25.10.2019

Еще вопрос. Может кто подтолкнет в нужном направлении. Есть у меня так https://www.youtube.com/watch?v=RnQTOkb_UKU&feature=youtu.be Как практика показала, не хватает режима, когда он будет ждать установки рюмки. Бесконечно ждать и сразу наливать в поставленную, потом в следующую и т.д. Прошивка такая 

#include <OLED_I2C.h>
#include <Servo.h>
#include "Adafruit_NeoPixel.h"
#include <SoftwareSerial.h>//добавляем библиотеки
#include <DFPlayer_Mini_Mp3.h>//добавляем библиотеку МП3 плейера

//-------------рисунок перед загрузкой---------------------
const uint8_t graf[] PROGMEM={ //graf - название, ниже вставить свои данные
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0E, 0x0E, 0x12, 0x24, 0x28, 0x48, 0x50, 0x90,
0xB0, 0x20, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x04, 0x09, 0x09, 0x12,
0x12, 0x24, 0x24, 0x48, 0x48, 0x90, 0x90, 0x20, 0x20, 0x40, 0x40, 0xC0, 0xA0, 0x20, 0xA0, 0x20,
0x20, 0x20, 0x20, 0x38, 0x38, 0x58, 0x5F, 0x78, 0x28, 0xE8, 0xD0, 0xA0, 0xF0, 0xAC, 0x24, 0xE4,
0x66, 0x46, 0x44, 0x44, 0x47, 0x44, 0x44, 0x46, 0x46, 0x46, 0x44, 0x44, 0x78, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x08, 0x08, 0x08, 0x00, 0x24, 0x24, 0x24, 0x1B,
0x00, 0x0C, 0x0E, 0x0B, 0x09, 0x3F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x1F,
0x02, 0xFC, 0x04, 0x38, 0x29, 0x71, 0x6A, 0x21, 0x93, 0x02, 0x65, 0x19, 0x01, 0x09, 0x00, 0xFC,
0x03, 0x02, 0xFE, 0x03, 0x01, 0x01, 0xC1, 0xE0, 0x60, 0x58, 0x58, 0x0C, 0x06, 0x0E, 0x18, 0xB0,
0xE0, 0xE0, 0x00, 0x00, 0x01, 0x0E, 0x7A, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
0x80, 0x40, 0x40, 0x40, 0x40, 0x43, 0x44, 0x48, 0x4B, 0x7C, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x5F, 0x5C, 0x58, 0x49, 0x5C, 0x48, 0x48, 0x70, 0x63, 0x7A,
0xCA, 0xCA, 0x8A, 0x5E, 0xD4, 0xD4, 0x53, 0x76, 0x30, 0x30, 0x30, 0x30, 0x30, 0x68, 0x69, 0x6E,
0x38, 0x18, 0x18, 0x38, 0x20, 0x20, 0x30, 0x10, 0x10, 0xD0, 0x20, 0x20, 0x20, 0x20, 0x70, 0xD0,
0x10, 0x10, 0x30, 0x60, 0x40, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0xC0, 0x20, 0x60, 0x50, 0x68,
0x4C, 0x46, 0x02, 0x43, 0xC3, 0x19, 0x64, 0x22, 0x60, 0x01, 0xE1, 0x9F, 0xA1, 0x92, 0x9E, 0x80,
0x80, 0x80, 0xB0, 0xD8, 0xC4, 0xC0, 0xC7, 0xC4, 0xC4, 0xC7, 0xC5, 0xC4, 0xB6, 0x9F, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xA0, 0x80, 0xFC, 0x83, 0x88, 0x8C, 0x84, 0x83, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40,
0x4F, 0x4C, 0x48, 0x58, 0x58, 0x4C, 0x4B, 0x48, 0x58, 0x48, 0x58, 0x6C, 0x67, 0x40, 0x40, 0x40,
0xC0, 0x00, 0x00, 0x00, 0x00, 0x70, 0xCE, 0x43, 0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xF8,
0x4C, 0x87, 0xC3, 0xA0, 0x90, 0x88, 0x88, 0x84, 0x82, 0x81, 0x81, 0x98, 0x9C, 0x94, 0x92, 0x91,
0x9B, 0x89, 0x8B, 0x89, 0xB9, 0x21, 0x21, 0x27, 0x21, 0x21, 0x11, 0x09, 0x05, 0x03, 0x00, 0x40,
0x70, 0x4C, 0xC3, 0xC0, 0xC8, 0x08, 0x08, 0x08, 0x88, 0x88, 0x80, 0x40, 0xF0, 0x1E, 0x19, 0x28,
0x08, 0x08, 0x58, 0xB8, 0xF8, 0x58, 0xB8, 0x58, 0x94, 0x94, 0xB4, 0xD4, 0x34, 0x54, 0x98, 0x54,
0x14, 0xD4, 0xB4, 0x5C, 0xAC, 0xDC, 0x6C, 0x84, 0x2C, 0x4A, 0xAA, 0x6A, 0xA6, 0xEA, 0x9A, 0x7A,
0x9E, 0xDC, 0xE5, 0x75, 0xD7, 0xA2, 0x42, 0x46, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x39,
0x69, 0xA9, 0xA9, 0xA8, 0xA8, 0xA8, 0xAB, 0xBC, 0xAB, 0xCF, 0x03, 0x04, 0x08, 0xD0, 0xE0, 0x20,
0x20, 0x20, 0xE0, 0xA0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0xE0, 0xE1, 0x41, 0xC1, 0x41, 0x41, 0x41,
0xC1, 0xC1, 0xC1, 0x41, 0xC1, 0xC1, 0x41, 0x41, 0x41, 0x4F, 0x71, 0xE8, 0xAA, 0xA8, 0xA8, 0xA0,
0xAA, 0xAA, 0xAA, 0x8F, 0xB0, 0xCC, 0x00, 0x78, 0x07, 0xA7, 0x00, 0x70, 0x33, 0x39, 0xFE, 0x01,
0xC3, 0xFF, 0x00, 0x09, 0xFC, 0xC7, 0x00, 0xFF, 0xA1, 0xFF, 0x08, 0xD7, 0x00, 0xDE, 0x6F, 0xBE,
0x8C, 0xCF, 0x28, 0x7F, 0xDE, 0xBB, 0xC6, 0xFF, 0x73, 0xF0, 0x04, 0x44, 0xC3, 0x41, 0x31, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x06, 0x0E, 0x0A, 0x1A, 0x1A,
0x1A, 0x1B, 0x1A, 0x1C, 0x1D, 0x0E, 0x0D, 0x0E, 0x0F, 0x0D, 0x0B, 0x09, 0x0B, 0x09, 0x0C, 0x09,
0x03, 0x04, 0x03, 0x03, 0x07, 0x07, 0x07, 0x04, 0x01, 0x03, 0x02, 0x03, 0x03, 0x02, 0x02, 0x02,
0x02, 0x01, 0x00, 0x01, 0x02, 0x04, 0x08, 0x18, 0x68, 0x68, 0x68, 0x60, 0x60, 0x61, 0x54, 0x5F,
0x5B, 0x54, 0x7C, 0x7A, 0x34, 0x3B, 0x27, 0x21, 0x35, 0x2E, 0x2D, 0x1C, 0x1F, 0x1A, 0x18, 0x18,
0x1A, 0x0D, 0x0C, 0x0F, 0x0D, 0x0C, 0x0D, 0x0E, 0x0F, 0x02, 0x03, 0x06, 0x06, 0x03, 0x07, 0x07,
0x01, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 
};
 
OLED myOLED(SDA, SCL, 8); //Подключение экрана А4-SDA-зеленый, А5-SCL-желтый
extern uint8_t MegaNumbers[];
extern uint8_t RusFont[];
extern uint8_t SmallFont[];
unsigned long currentTime;
unsigned long loopTime;
unsigned long ledTime;
// Переменные для энкодера -----------
const int pin_A = 2;       // Подключение вывода A (CLK) энкодера
const int pin_B = 3;       // Подключение вывода B (DT) энкодера
const int pin_SW = 4;       // Подключение вывода кнопки (SW) энкодера
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev = 0;
unsigned char encoder_sw_prew = 1;
//Массив , обозначаем подключенные оптопары по выводам . Оптопары подключены, A0,A1,A2,A3,A6
const byte  Optics[] = {0, 1, 2, 3, 6};
// Значения порога срабатывания датчика для каждой рюмки
const unsigned int Optics_porog[] = {300,300,300,300,300};
//Серво
const int PIN_SERVO = 9;
Servo servo;
//Позиция каждой рюмки 
const byte Rumka_pos[] = {52,68,84,101,117}; //53,69,84,101,117
const byte servo_speed=25; // Скорость поворота серво,  10 - норм, 20 медленно, 30 очень медленно
byte  Menu = 0;
byte MenuFlag = 0; // Здесь храниться уровень меню. 0 находимся в  Главном меню. 1 Вошли в меню Авто, 2 вошли в  Ручное управление
byte  Drink = 15; // По умолчанию в рюмку наливаем  15 мл.
//----- Минимальные и максимальные значения наполняемой жидкости и задержки для наполнения. 
const byte  min_Drink = 5; // Минимум в рюмку - 5 мл.
const byte  max_Drink = 50; // Максимум в рюмку - 50 мл.
// Калибровка работы насосика. Значения для налива min_Drink и max_Drink соотвественно 
const unsigned int min_Drink_delay = 300; 
const unsigned int max_Drink_delay = 6000;
//--------
byte  DrinkCount = 1; //По умолчанию, для ручного режима - 1 рюмка
const byte  max_DrinkCount = 5; //Максимальное кол-во рюмок - 5
// Насосик
const byte PIN_PUMP = 12;
// Светодиоды
const int PIN_LED = 5;// Сюда подключаются светодиоды
const int LED_COUNT = max_DrinkCount;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, PIN_LED, NEO_GRB + NEO_KHZ800);
//-------

byte tick = 0;  

void pump_enable() {
  digitalWrite(PIN_PUMP, 1); //вкл реле
}

void pump_disable() {
  digitalWrite(PIN_PUMP, 0); //выкл реле
}

void pump_timer(byte Drink) {
  digitalWrite(PIN_PUMP, 1); //вкл реле
  delay(map(Drink, min_Drink,  max_Drink, min_Drink_delay, max_Drink_delay));
  digitalWrite(PIN_PUMP, 0); //выкл реле
}
// старое меню со скобками
//void oled_menu(int Menu) {
//  myOLED.clrScr();
//  myOLED.setFont(RusFont);
//  myOLED.print(F("N-34 *YFKBDFNJH*"), CENTER, 0);//Т-34 *НАЛИВАТОР* 
//  myOLED.print(F("FDNJ JUJYM"), CENTER, 25);//АВТО ОГОНЬ    15
//  myOLED.print(F("HEXYJQ PFHZL"), CENTER, 40);//РУЧНОЙ ЗАРЯД     30
//  myOLED.print(F("GHJRFXRF CBCNTVS"), CENTER, 55);//ПРОКАЧКА СИСТЕМЫ    45
//  myOLED.setFont(SmallFont);
//  myOLED.print(F(">"), LEFT, (Menu * 15) + 25);  // 15+15
//  myOLED.print(F("<"), RIGHT, (Menu * 15) + 25);  //  15+15
//  myOLED.update();
//
//}

void oled_menu(int Menu) {
  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print(F("N-34 *YFKBDFNJH*"), CENTER, 4);//Т-34 *НАЛИВАТОР* 
  myOLED.print(F("FDNJ JUJYM"), CENTER, 28);//АВТО ОГОНЬ
  myOLED.print(F("HEXYJQ PFHZL"), CENTER, 40);//РУЧНОЙ ЗАРЯД
  myOLED.print(F("GHJRFXRF CBCNTVS"), CENTER, 52);//ПРОКАЧКА СИСТЕМЫ
  myOLED.drawRect(12, Menu * 12 + 26, 116, Menu * 12 + 36); //рамка вокруг названий
  myOLED.update();

}
//  выводит строчку по чуть чуть, в самый раз и тд. Передается номер строки, на которой выводить сообщение
void DrinkInfo(byte pos) {
  if (Drink < 15) {
    myOLED.print(F("YB J XTV"), CENTER, pos);//НИ О ЧЕМ
  } else if (Drink < 28) {
    myOLED.print(F("GJ XENM - XENM"), CENTER, pos);//ПО ЧУТЬ - ЧУТЬ
  } else if (Drink < 38) {
    myOLED.print(F("D CFVSQ HFP"), CENTER, pos);//В САМЫЙ РАЗ
  } else if (Drink < 48) {
    myOLED.print(F("GJ GJKYJQ"), CENTER, pos);//ПО ПОЛНОЙ
  } else {
    myOLED.print(F("LJ RHFTD"), CENTER, pos);//ДО КРАЕВ
  }

}

  void Tost() {
  randomSeed(currentTime);
  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print(F("YE!"), CENTER, 15); //НУ!
  // Рандом - 1
  switch (random(18)) {  // case 0...17
  case 0:
      myOLED.print(F("PF DCNHTXE!"), CENTER, 30); //ЗА ВСТРЕЧУ!
      mp3_play (2);  // Проигрываем "mp3/0002.mp3"
    delay(100);
    break;
  case 1:
      myOLED.print(F("PF RHFCJNE!"), CENTER, 30); //ЗА КРАСОТУ!
      mp3_play (3);  // Проигрываем "mp3/0003.mp3"
    delay(100);
    break;
  case 2:
      myOLED.print(F("PF LHE;,E!"), CENTER, 30); //ЗА ДРУЖБУ!
      mp3_play (4);  // Проигрываем "mp3/0004.mp3"
    delay(100);
    break;
  case 3:
      myOLED.print(F("DS <KBY"), CENTER, 30); //ВЫ БЛИН
      myOLED.print(F("LFTNT!"), CENTER, 45); //ДАЕТЕ!
      mp3_play (20);  // Проигрываем "mp3/0020.mp3"
    delay(100);
	break;
  case 4:
      myOLED.print(F("PF ,HFNCNDJ!"), CENTER, 30); //ЗА БРАТСТВО!
      mp3_play (5);  // Проигрываем "mp3/0005.mp3"
    delay(100);
    break;
  case 5:
      myOLED.print(F("PF"), CENTER, 30); //за
    myOLED.print(F("CGHFDTLKBDJCNM!"), CENTER, 45); //СПРАВЕДЛИВОСТЬ!
      mp3_play (6);  // Проигрываем "mp3/0006.mp3"
    delay(100);
    break;
  case 6:
      myOLED.print(F("PF HS,FKRE!"), CENTER, 30); //ЗА РЫБАЛКУ!
      mp3_play (7);  // Проигрываем "mp3/0007.mp3"
    delay(100);
    break;
  case 7:
      myOLED.print(F("PF BCRECCNDJ!"), CENTER, 30); //ЗА ИСКУССТВО!
      mp3_play (8);  // Проигрываем "mp3/0008.mp3"
    delay(100);
    break;
  case 8:
      myOLED.print(F("PF HFPEV!"), CENTER, 30); //ЗА РАЗУМ!
      mp3_play (9);  // Проигрываем "mp3/0009.mp3"
    delay(100);
    break; 
  case 9:
      myOLED.print(F("PF BCNBYYS["), CENTER, 30); //ЗА ИСТИННЫХ
      myOLED.print(F(":TYOBY!"), CENTER, 45); //ЖЕНЩИН!
      mp3_play (10);  // Проигрываем "mp3/0010.mp3"
    delay(100);
    break;
  case 10:
      myOLED.print(F("PF GJYBVFYBT!"), CENTER, 30); //ЗА ПОНИМАНИЕ!
      mp3_play (11);  // Проигрываем "mp3/0011.mp3"
    delay(100);
    break;
  case 11:
      myOLED.print(F("PF TLBYTYBT!"), CENTER, 30); //ЗА ЕДИНЕНИЕ!
      mp3_play (13);  // Проигрываем "mp3/0013.mp3"
    delay(100);
    break;
  case 12:
      myOLED.print(F("PF GJ,TLE!"), CENTER, 30); //ЗА ПОБЕДУ!
      mp3_play (16);  // Проигрываем "mp3/0016.mp3"
    delay(100);
    break;
  case 13:
      myOLED.print(F("PF HJLBYE!"), CENTER, 30); //ЗА РОДИНУ!
      mp3_play (21);  // Проигрываем "mp3/0021.mp3"
    delay(100);
    break;
  case 14:
      myOLED.print(F("XNJ, UJKJDF"), CENTER, 30); //ЧТОБ ГОЛОВА
    myOLED.print(F("YT NHTOFKF!"), CENTER, 45); //НЕ ТРЕЩАЛА!
      mp3_play (17);  // Проигрываем "mp3/0017.mp3"
    delay(100);
    break;
  case 15:
      myOLED.print(F("PF CJKBLYJT"), CENTER, 30); //ЗА СОЛИДНОЕ
    myOLED.print(F("VE;CRJT VJKXFYBT"), CENTER, 45); //МУЖСКОЕ МОЛЧАНИЕ
      mp3_play (12);  // Проигрываем "mp3/0012.mp3"
    delay(100);
    break;
  case 16:
      myOLED.print(F("XNJ, VJHOBKJ"), CENTER, 30); //ЧТОБ МОРЩИЛО
    myOLED.print(F("YFC VTYMIT!"), CENTER, 45); //НАС МЕНЬШЕ!
      mp3_play (18);  // Проигрываем "mp3/0018.mp3"
    delay(100);
    break;
  case 17:
      myOLED.print(F("XNJ, D CNJHJYE"), CENTER, 30); //ЧТОБ В СТОРОНУ
    myOLED.print(F("YT DBKMYEKJ!"), CENTER, 45); //НЕ ВИЛЬНУЛО!
      mp3_play (19);  // Проигрываем "mp3/0019.mp3"
    delay(100);
    break;      
  }
  delay(2000);
  myOLED.update();

}

// Меню Авто режим
void oled_auto(int Drink) {

  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print(F("FDNJ JUJYM"), CENTER, 4); //АВТО ОГОНЬ
  DrinkInfo(52);
  //  myOLED.print(DrinkInfo[map(Drink, 2, max_Drink, 0, 4)], CENTER, 57);
  myOLED.setFont(MegaNumbers);
  myOLED.print(String(Drink), CENTER, 13);
  myOLED.update();
}

// Меню Ручной режим
void oled_manual(int DrinkCount, int Drink) {

  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print(F("HEXYJQ PFHZL"), CENTER, 4); //РУЧНОЙ ЗАРЯД 
  DrinkInfo(52);
  // myOLED.print(DrinkInfo[map(Drink, 2, max_Drink, 0, 4)], CENTER, 57);
  myOLED.print(F("H>V"), 24, 27);  // РЮМ
  myOLED.print(F("VK "), RIGHT, 27);
  myOLED.setFont(MegaNumbers);
  myOLED.print(String(DrinkCount), LEFT, 13);
  myOLED.print(String(Drink), (Drink < 10) ? 80 : 57, 13);
  myOLED.update();
}


void oled_naliv(int MenuFlag) {
  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print((MenuFlag == 1) ? F("FDNJ JUJYM") : F("HEXYJQ PFHZL") , CENTER, 4); // АВТО ОГОНЬ   РУЧНОЙ ЗАРЯД 

  myOLED.print(F("JNRHSDF> JUJYM"), CENTER, 27); //ОТКРЫВАЮ ОГОНЬ
  DrinkInfo(47);
  myOLED.update();
}

void oled_nalito(int MenuFlag, int Nalito) {
  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print((MenuFlag == 1) ? F("FDNJ JUJYM") : F("HEXYJQ PFHZL") , CENTER, 4); // АВТО ОГОНЬ   РУЧНОЙ ЗАРЯД
  
  if (Nalito == 1) {
    myOLED.print(F("G J H F : T Y F"), CENTER, 20); // ПОРАЖЕНА
    myOLED.print(F("W T K M"), CENTER, 55); //ЦЕЛЬ
  } else if (Nalito <= 4 ) {
    myOLED.print(F("G J H F : T Y J"), CENTER, 20); // ПОРАЖЕНО
    myOLED.print(F("W T K B"), CENTER, 55); //ЦЕЛИ
  } else {
    myOLED.print(F("G J H F : T Y J"), CENTER, 20); // ПОРАЖЕНО
    myOLED.print(F("W T K T Q"), CENTER, 55); //ЦЕЛЕЙ
  }

  myOLED.setFont(SmallFont);
  myOLED.print(String(Nalito), CENTER, 36);
  myOLED.update();
}

void ServoNaliv(byte rumka) {
  servo.attach(PIN_SERVO);
  for (int pos = servo.read(); pos <= Rumka_pos[rumka]; pos += 1) { 
    // с шагом в 1 градус
    servo.write(pos); // даем серве команду повернуться в положение, которое задается в переменной 'pos'
    delay(servo_speed); // ждем , пока ротор сервы выйдет в заданную позицию
  }
  servo.detach();
}

void ServoParking () {
  //Serial.println(servo.read());
  servo.attach(PIN_SERVO);
  for (int pos = servo.read();  pos >= 0; pos -= 1) {     // с шагом в 1 градус
    servo.write(pos); // даем серве команду повернуться в положение, которое задается в переменной 'pos'
    delay(servo_speed); // ждем , пока ротор сервы выйдет в заданную позицию
  }
  servo.detach();
}
// Старая подсветка
//void CvetoMuzik() {
//  for (int i = 0; i <= 7; i++) {
//    for (int y = 0; y < max_DrinkCount; y++) {
//      strip.setPixelColor(y, strip.Color(255, 0, 0));
//      strip.show();
//     delay(30);
//    }
//    for (int y = 0; y < max_DrinkCount; y++) {
//      strip.setPixelColor(y, strip.Color(0, 255, 0));
//      strip.show();
//      delay(30);
//    }
//    for (int y = 0; y < max_DrinkCount; y++) {
//      strip.setPixelColor(y, strip.Color(0, 0, 255));
//      strip.show();
//      delay(30);
//    }
//  }
//}


// Новая подсветка для проверки
void CvetoMuzik() {
    for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 768) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(10);  // Pause for a moment
  }

    tick++;
if (tick == 5) {

            randomSeed(currentTime);
  switch (random(3)) {  // case 0...2
    case 0:
      mp3_play (188);  // Проигрываем "mp3/0002.mp3"
    delay(100);
    break;
  case 1:
      mp3_play (166);  // Проигрываем "mp3/0003.mp3"
    delay(100);
    break;
  case 2:
      mp3_play (177);  // Проигрываем "mp3/0004.mp3"
    delay(100);
    break;
  }

tick = 0;
  }
}


void celi()  {   // Мелодия перед наливом
            myOLED.clrScr();
            myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
            myOLED.setFont(RusFont);
            myOLED.print(F("J<YFHE:TYBT WTKTQ"), CENTER, 20); //ОБНАРУЖЕНИЕ ЦЕЛЕЙ 
            myOLED.print(F("LKZ GJHF:TYBZ"), CENTER, 40); // ДЛЯ ПОРАЖЕНИЯ
            delay(300);
            mp3_play (52);    
            myOLED.update();
            delay(3000);
}

void setup()  {
  Serial.begin(9600);//
  //устанавливаем Serial порт МП3 плейера если вывод в монитор TX(D0) и RX(D1)не нужен 
  mp3_set_serial (Serial);//инициализируем Serial порт МП3 плейера
  delay (100);//Между двумя командами необходимо делать задержку 100 миллисекунд, в противном случае некоторые команды могут работать не стабильно.
  mp3_set_volume (20);// устанвливаем громкость 20
  delay (100);
  mp3_play (1); // Проигрываем "mp3/0001.mp3"
  delay (100);
  //   Volume=EEPROM.read(0);
  myOLED.begin(); // Инициализация дисплея
  //myOLED.invert(1); //инвертировать дисплей

// выводим привествие после включения перед наливом

//-------------рисунок перед загрузкой---------------------
           myOLED.clrScr();
           myOLED.drawBitmap(12, 0, graf, 103, 64); //координата Х координата У, название, ширина и высота изображения
           myOLED.update();
           //myOLED.invert(1);
           delay(5000);
           //myOLED.invert(0);
//---------------------------------------------------------

//  myOLED.clrScr();  
//  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
//  myOLED.setFont(RusFont);
//  myOLED.print(F("PFDJLBVCZ!"), CENTER, 25);// ЗАВОДИМСЯ!
//  myOLED.update(); 
//   delay (4000);
   
   // Выводит на экран Настройка систем 
   myOLED.clrScr();
   myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
   myOLED.setFont(RusFont);
   myOLED.print(F("GHJBPDJ:E"), CENTER, 20); //ПРОИЗВОЖУ 
   myOLED.print(F("YFCNHJQRE CBCNTV"), CENTER, 40); // НАСТРОЙКУ СИТЕМ
   myOLED.update();
   delay(3000);
   
   // Выводит на экран Все системы работают нормально
   myOLED.clrScr();
   myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
   myOLED.setFont(RusFont);
   myOLED.print(F("DCT CBNTVS"), CENTER, 20); //ВСЕ СИСТЕМЫ 
   myOLED.print(F("D YJHVT"), CENTER, 40); // В НОРМЕ
   myOLED.update();
   delay(3000);
   
   
  pinMode(pin_SW, INPUT); // устанавливаем pin pin_SW как вход
  digitalWrite(pin_SW, HIGH); // Поддяжка вывода к 1
  pinMode(pin_A, INPUT);
  pinMode(pin_B, INPUT);
  pinMode(PIN_PUMP, OUTPUT);
  digitalWrite(PIN_PUMP, 0);
  currentTime = millis();
  loopTime = currentTime;
  //---------------
  oled_menu(0);
  strip.begin();
  for (int i = 0; i < 5; i++) {
    pinMode(Optics[i], INPUT);
  }
  ServoParking();

}

void loop()  {
  currentTime = millis();
  if (currentTime >= (loopTime + 5)) { // проверяем каждые 5мс

    //     int  val = analogRead(0);     // считываем значение
    //  Serial.println(val);
    encoder_A = digitalRead(pin_A);     // считываем состояние выхода А энкодера
    encoder_B = digitalRead(pin_B);     // считываем состояние выхода B энкодера
    if ((!encoder_A) && (encoder_A_prev)) {  // если состояние изменилось с положительного к нулю

      //Вращение влево
      if (encoder_B) {
        if (MenuFlag == 0) {
          (Menu <= 0 ) ? Menu = 2 : Menu--; // Перемещение курсора по главному меню назад
          oled_menu(Menu);
        } else if (MenuFlag == 1) {
          (Drink <= min_Drink ) ? Drink = max_Drink : Drink-=5; // Уменьшаем кол-во милилитров в рюмку с шагом 5
          oled_auto(Drink);
        } else if (MenuFlag == 2) {
          (DrinkCount >= max_DrinkCount ) ? DrinkCount = 1 : DrinkCount++; // Влево увечичиваем рюмки для ручного режима
          oled_manual(DrinkCount, Drink);
        }
        //Вращение вправо
      } else {
        if (MenuFlag == 0) {
          (Menu >= 2 ) ? Menu = 0 : Menu++; // Перемещение курсора по главному меню вперед.
          oled_menu(Menu);
        } else if (MenuFlag == 1) {
          (Drink >= max_Drink ) ? Drink = min_Drink : Drink+=5;
          oled_auto(Drink);
        } else if (MenuFlag == 2) {
          (Drink >= max_Drink ) ? Drink = min_Drink : Drink+=5;
          oled_manual(DrinkCount, Drink);
        }
      }

    }

    encoder_A_prev = encoder_A;     // сохраняем значение А для следующего цикла

    int encoder_sw = digitalRead(pin_SW);
    if  (encoder_sw == 0 && encoder_sw != encoder_sw_prew)  { // Нажата кнопка

      int pause_sw = 0;
      boolean promivka = false;
      while (digitalRead(pin_SW) == 0) { // Держим кнопку. Считаем сколько времени прошло...
        delay(100);
        pause_sw++;
        if (pause_sw > 20 && Menu != 2 ) break;

        if (pause_sw > 20 && Menu == 2 && promivka == false) { // Если пункт меню промывка и держим кнопку больше 2 секунд.
          promivka = true;
          pump_enable(); // Включаем насос
          myOLED.clrScr();
          myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
          myOLED.setFont(RusFont);
          myOLED.print(F("GHJRFXRF CBCNTVS"), CENTER, 15); // ПРОКАЧКА СИСТЕМЫ
          myOLED.print(F("* * * * *"), CENTER, 45);
          myOLED.update();
        }
      }

      //После отпускания кнопки , обрабатываем
      if (promivka == true) { //Отпустили кнопку. Если включена промывка, выключаем насос и возвращаемся в главное меню
        promivka = false;
        pump_disable() ; //Выключаем насос
        oled_menu(2);

      } else {
        //Обработка всех нажатий кнопки
        if (Menu == 0 && MenuFlag == 0 &&  pause_sw < 10) { //Нажатие кнопки меню авто
          MenuFlag = 1;
          oled_auto(Drink);
        } else if (MenuFlag == 1 && pause_sw > 20) { //Выход из меню авто в главное
          MenuFlag = 0;
          oled_menu(0);
        } else if (MenuFlag == 1 ) { //Начинается автоматический разлив
          
          celi();           // Мелодия перед наливом в авторежиме
          
          Serial.println("Начало автоматического разлива");
          oled_naliv(MenuFlag); // Выводим на экран наливаем ...
          byte drink_count = 0;
          for (int y = 0; y < max_DrinkCount; y++) {
            if (analogRead(Optics[y]) < Optics_porog[y] ) {
              strip.setPixelColor(y, strip.Color(255, 0, 0)); // Подствечиваем красным цветом
              strip.show();
              ServoNaliv(y); // Перемещяемся к рюмке
              pump_timer(Drink); // Налив.
              strip.setPixelColor(y, strip.Color(0, 255, 0)); // Подствечиваем зеленым , налито.
              strip.show();
              drink_count++;
            }
          }
          if (drink_count > 0) {
            oled_nalito(MenuFlag, drink_count );
            ServoParking();
            //delay(1000);
            Tost();
            CvetoMuzik();
            oled_auto(Drink);
          } else {
            myOLED.clrScr();
            myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
            myOLED.setFont(RusFont);
            myOLED.print(F("YTN WTKTQ!"), CENTER, 10); //НЕТ ЦЕЛЕЙ!
			myOLED.print(F("J<JPYFXMNT WTKM"), CENTER, 30); // ОБОЗНАЧЬТЕ ЦЕЛИ
            myOLED.print(F("LKZ GJHF:TYBZ!"), CENTER, 50); // ДЛЯ ПОРАЖЕНИЯ!
      delay(300);
            mp3_play (88);  // Играем сирену.
            myOLED.update();
            delay(5000);
            oled_auto(Drink);

          }
        } else if (Menu == 1 && MenuFlag == 0 &&  pause_sw < 10) { // Нажатие меню ручное
          MenuFlag = 2;
          oled_manual(DrinkCount, Drink);
        } else if (MenuFlag == 2 && pause_sw > 20) { //Выход из меню ручное в главное
          MenuFlag = 0;
          oled_menu(1);
        } else if (MenuFlag == 2 ) { //Начинается ручной разлив

            celi(); //Мелодия перед ручным наливом
                        
		  oled_naliv(MenuFlag); // Выводим на экран наливаем ...
          for (int y = 0; y < DrinkCount; y++) {
            strip.setPixelColor(y, strip.Color(255, 0, 0)); // Подствечиваем красным цветом
            strip.show();
            ServoNaliv(y); // Перемещяемся к рюмке
            pump_timer(Drink); // Налив.
            strip.setPixelColor(y, strip.Color(0, 255, 0)); // Подствечиваем зеленым , налито.
            strip.show();
          }
          oled_nalito(MenuFlag, DrinkCount );
          ServoParking();
          Tost();
          CvetoMuzik();
          oled_manual(DrinkCount, Drink);
        }
      }
    }

    if (currentTime >= (ledTime + 300)) {
      //Опрашиваем оптопары ... Если рюмка поставлена , светодиод светится синим, нет ничего - не светится
      for (int i = 0; i < max_DrinkCount; i++) {
        
        int val = analogRead(Optics[i]);     // считываем значение
        Serial.println(val);
        if (val < Optics_porog[i]) {
          strip.setPixelColor(i, strip.Color(0, 0, 255)); 
        } else {
          strip.setPixelColor(i, strip.Color(0, 0, 0));
        }
    //    delay(20);

      }
      strip.show();
      ledTime = currentTime;
    }
    encoder_sw_prew = encoder_sw;
    loopTime = currentTime;

  }
}

 

VICLER
Offline
Зарегистрирован: 30.12.2019

А автоматический режим разве не так работает? Ждёт рюмки и разливает во все поставленные рюмки
Upd: сорри, не нашёл, что только после нажатия начинает разливать

sarsab
Offline
Зарегистрирован: 23.01.2020

в скетче от Романа все это реализовано!в настройках есть бармен,если включить этот режим то он будет при установки рюмки наливать сразу же в режиме авто и режиме мультиразлив. Сон тоже реализован,реализовано также показание акб.

VICLER
Offline
Зарегистрирован: 30.12.2019

немного изменил прошивку, можете попробовать. Теперь в авто режиме всегда должен ждать новую рюмку и как только она появится тут же наливать. Я не добавлял нового режима, только изменил старый автоматический


#include <OLED_I2C.h>
#include <Servo.h>
#include "Adafruit_NeoPixel.h"
#include <SoftwareSerial.h>//добавляем библиотеки
#include <DFPlayer_Mini_Mp3.h>//добавляем библиотеку МП3 плейера

//-------------рисунок перед загрузкой---------------------
const uint8_t graf[] PROGMEM={ //graf - название, ниже вставить свои данные
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0E, 0x0E, 0x12, 0x24, 0x28, 0x48, 0x50, 0x90,
0xB0, 0x20, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80,
0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x04, 0x09, 0x09, 0x12,
0x12, 0x24, 0x24, 0x48, 0x48, 0x90, 0x90, 0x20, 0x20, 0x40, 0x40, 0xC0, 0xA0, 0x20, 0xA0, 0x20,
0x20, 0x20, 0x20, 0x38, 0x38, 0x58, 0x5F, 0x78, 0x28, 0xE8, 0xD0, 0xA0, 0xF0, 0xAC, 0x24, 0xE4,
0x66, 0x46, 0x44, 0x44, 0x47, 0x44, 0x44, 0x46, 0x46, 0x46, 0x44, 0x44, 0x78, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x08, 0x08, 0x08, 0x00, 0x24, 0x24, 0x24, 0x1B,
0x00, 0x0C, 0x0E, 0x0B, 0x09, 0x3F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x1F,
0x02, 0xFC, 0x04, 0x38, 0x29, 0x71, 0x6A, 0x21, 0x93, 0x02, 0x65, 0x19, 0x01, 0x09, 0x00, 0xFC,
0x03, 0x02, 0xFE, 0x03, 0x01, 0x01, 0xC1, 0xE0, 0x60, 0x58, 0x58, 0x0C, 0x06, 0x0E, 0x18, 0xB0,
0xE0, 0xE0, 0x00, 0x00, 0x01, 0x0E, 0x7A, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
0x80, 0x40, 0x40, 0x40, 0x40, 0x43, 0x44, 0x48, 0x4B, 0x7C, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x5F, 0x5C, 0x58, 0x49, 0x5C, 0x48, 0x48, 0x70, 0x63, 0x7A,
0xCA, 0xCA, 0x8A, 0x5E, 0xD4, 0xD4, 0x53, 0x76, 0x30, 0x30, 0x30, 0x30, 0x30, 0x68, 0x69, 0x6E,
0x38, 0x18, 0x18, 0x38, 0x20, 0x20, 0x30, 0x10, 0x10, 0xD0, 0x20, 0x20, 0x20, 0x20, 0x70, 0xD0,
0x10, 0x10, 0x30, 0x60, 0x40, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0xC0, 0x20, 0x60, 0x50, 0x68,
0x4C, 0x46, 0x02, 0x43, 0xC3, 0x19, 0x64, 0x22, 0x60, 0x01, 0xE1, 0x9F, 0xA1, 0x92, 0x9E, 0x80,
0x80, 0x80, 0xB0, 0xD8, 0xC4, 0xC0, 0xC7, 0xC4, 0xC4, 0xC7, 0xC5, 0xC4, 0xB6, 0x9F, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xA0, 0x80, 0xFC, 0x83, 0x88, 0x8C, 0x84, 0x83, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40,
0x4F, 0x4C, 0x48, 0x58, 0x58, 0x4C, 0x4B, 0x48, 0x58, 0x48, 0x58, 0x6C, 0x67, 0x40, 0x40, 0x40,
0xC0, 0x00, 0x00, 0x00, 0x00, 0x70, 0xCE, 0x43, 0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xF8,
0x4C, 0x87, 0xC3, 0xA0, 0x90, 0x88, 0x88, 0x84, 0x82, 0x81, 0x81, 0x98, 0x9C, 0x94, 0x92, 0x91,
0x9B, 0x89, 0x8B, 0x89, 0xB9, 0x21, 0x21, 0x27, 0x21, 0x21, 0x11, 0x09, 0x05, 0x03, 0x00, 0x40,
0x70, 0x4C, 0xC3, 0xC0, 0xC8, 0x08, 0x08, 0x08, 0x88, 0x88, 0x80, 0x40, 0xF0, 0x1E, 0x19, 0x28,
0x08, 0x08, 0x58, 0xB8, 0xF8, 0x58, 0xB8, 0x58, 0x94, 0x94, 0xB4, 0xD4, 0x34, 0x54, 0x98, 0x54,
0x14, 0xD4, 0xB4, 0x5C, 0xAC, 0xDC, 0x6C, 0x84, 0x2C, 0x4A, 0xAA, 0x6A, 0xA6, 0xEA, 0x9A, 0x7A,
0x9E, 0xDC, 0xE5, 0x75, 0xD7, 0xA2, 0x42, 0x46, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x39,
0x69, 0xA9, 0xA9, 0xA8, 0xA8, 0xA8, 0xAB, 0xBC, 0xAB, 0xCF, 0x03, 0x04, 0x08, 0xD0, 0xE0, 0x20,
0x20, 0x20, 0xE0, 0xA0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0xE0, 0xE1, 0x41, 0xC1, 0x41, 0x41, 0x41,
0xC1, 0xC1, 0xC1, 0x41, 0xC1, 0xC1, 0x41, 0x41, 0x41, 0x4F, 0x71, 0xE8, 0xAA, 0xA8, 0xA8, 0xA0,
0xAA, 0xAA, 0xAA, 0x8F, 0xB0, 0xCC, 0x00, 0x78, 0x07, 0xA7, 0x00, 0x70, 0x33, 0x39, 0xFE, 0x01,
0xC3, 0xFF, 0x00, 0x09, 0xFC, 0xC7, 0x00, 0xFF, 0xA1, 0xFF, 0x08, 0xD7, 0x00, 0xDE, 0x6F, 0xBE,
0x8C, 0xCF, 0x28, 0x7F, 0xDE, 0xBB, 0xC6, 0xFF, 0x73, 0xF0, 0x04, 0x44, 0xC3, 0x41, 0x31, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x06, 0x0E, 0x0A, 0x1A, 0x1A,
0x1A, 0x1B, 0x1A, 0x1C, 0x1D, 0x0E, 0x0D, 0x0E, 0x0F, 0x0D, 0x0B, 0x09, 0x0B, 0x09, 0x0C, 0x09,
0x03, 0x04, 0x03, 0x03, 0x07, 0x07, 0x07, 0x04, 0x01, 0x03, 0x02, 0x03, 0x03, 0x02, 0x02, 0x02,
0x02, 0x01, 0x00, 0x01, 0x02, 0x04, 0x08, 0x18, 0x68, 0x68, 0x68, 0x60, 0x60, 0x61, 0x54, 0x5F,
0x5B, 0x54, 0x7C, 0x7A, 0x34, 0x3B, 0x27, 0x21, 0x35, 0x2E, 0x2D, 0x1C, 0x1F, 0x1A, 0x18, 0x18,
0x1A, 0x0D, 0x0C, 0x0F, 0x0D, 0x0C, 0x0D, 0x0E, 0x0F, 0x02, 0x03, 0x06, 0x06, 0x03, 0x07, 0x07,
0x01, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 
};
 
OLED myOLED(SDA, SCL, 8); //Подключение экрана А4-SDA-зеленый, А5-SCL-желтый
extern uint8_t MegaNumbers[];
extern uint8_t RusFont[];
extern uint8_t SmallFont[];
unsigned long currentTime;
unsigned long loopTime;
unsigned long ledTime;
// Переменные для энкодера -----------
const int pin_A = 2;       // Подключение вывода A (CLK) энкодера
const int pin_B = 3;       // Подключение вывода B (DT) энкодера
const int pin_SW = 4;       // Подключение вывода кнопки (SW) энкодера
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev = 0;
unsigned char encoder_sw_prew = 1;
//Массив , обозначаем подключенные оптопары по выводам . Оптопары подключены, A0,A1,A2,A3,A6
const byte  Optics[] = {0, 1, 2, 3, 6};
// Значения порога срабатывания датчика для каждой рюмки
const unsigned int Optics_porog[] = {300,300,300,300,300};
//Серво
const int PIN_SERVO = 9;
Servo servo;
//Позиция каждой рюмки 
const byte Rumka_pos[] = {52,68,84,101,117}; //53,69,84,101,117
const byte servo_speed=25; // Скорость поворота серво,  10 - норм, 20 медленно, 30 очень медленно
byte  Menu = 0;
byte MenuFlag = 0; // Здесь храниться уровень меню. 0 находимся в  Главном меню. 1 Вошли в меню Авто, 2 вошли в  Ручное управление
byte  Drink = 15; // По умолчанию в рюмку наливаем  15 мл.
byte allDone = true; // флаг об окончании налива во все рюмки
//----- Минимальные и максимальные значения наполняемой жидкости и задержки для наполнения. 
const byte  min_Drink = 5; // Минимум в рюмку - 5 мл.
const byte  max_Drink = 50; // Максимум в рюмку - 50 мл.
// Калибровка работы насосика. Значения для налива min_Drink и max_Drink соотвественно 
const unsigned int min_Drink_delay = 300; 
const unsigned int max_Drink_delay = 6000;
//--------
byte  DrinkCount = 1; //По умолчанию, для ручного режима - 1 рюмка
const byte  max_DrinkCount = 5; //Максимальное кол-во рюмок - 5
// Насосик
const byte PIN_PUMP = 12;
// Светодиоды
const int PIN_LED = 5;// Сюда подключаются светодиоды
const int LED_COUNT = max_DrinkCount;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, PIN_LED, NEO_GRB + NEO_KHZ800);
//-------

byte tick = 0;  

void pump_enable() {
  digitalWrite(PIN_PUMP, 1); //вкл реле
}

void pump_disable() {
  digitalWrite(PIN_PUMP, 0); //выкл реле
}

void pump_timer(byte Drink) {
  digitalWrite(PIN_PUMP, 1); //вкл реле
  delay(map(Drink, min_Drink,  max_Drink, min_Drink_delay, max_Drink_delay));
  digitalWrite(PIN_PUMP, 0); //выкл реле
}
// старое меню со скобками
//void oled_menu(int Menu) {
//  myOLED.clrScr();
//  myOLED.setFont(RusFont);
//  myOLED.print(F("N-34 *YFKBDFNJH*"), CENTER, 0);//Т-34 *НАЛИВАТОР* 
//  myOLED.print(F("FDNJ JUJYM"), CENTER, 25);//АВТО ОГОНЬ    15
//  myOLED.print(F("HEXYJQ PFHZL"), CENTER, 40);//РУЧНОЙ ЗАРЯД     30
//  myOLED.print(F("GHJRFXRF CBCNTVS"), CENTER, 55);//ПРОКАЧКА СИСТЕМЫ    45
//  myOLED.setFont(SmallFont);
//  myOLED.print(F(">"), LEFT, (Menu * 15) + 25);  // 15+15
//  myOLED.print(F("<"), RIGHT, (Menu * 15) + 25);  //  15+15
//  myOLED.update();
//
//}

void oled_menu(int Menu) {
  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print(F("N-34 *YFKBDFNJH*"), CENTER, 4);//Т-34 *НАЛИВАТОР* 
  myOLED.print(F("FDNJ JUJYM"), CENTER, 28);//АВТО ОГОНЬ
  myOLED.print(F("HEXYJQ PFHZL"), CENTER, 40);//РУЧНОЙ ЗАРЯД
  myOLED.print(F("GHJRFXRF CBCNTVS"), CENTER, 52);//ПРОКАЧКА СИСТЕМЫ
  myOLED.drawRect(12, Menu * 12 + 26, 116, Menu * 12 + 36); //рамка вокруг названий
  myOLED.update();

}
//  выводит строчку по чуть чуть, в самый раз и тд. Передается номер строки, на которой выводить сообщение
void DrinkInfo(byte pos) {
  if (Drink < 15) {
    myOLED.print(F("YB J XTV"), CENTER, pos);//НИ О ЧЕМ
  } else if (Drink < 28) {
    myOLED.print(F("GJ XENM - XENM"), CENTER, pos);//ПО ЧУТЬ - ЧУТЬ
  } else if (Drink < 38) {
    myOLED.print(F("D CFVSQ HFP"), CENTER, pos);//В САМЫЙ РАЗ
  } else if (Drink < 48) {
    myOLED.print(F("GJ GJKYJQ"), CENTER, pos);//ПО ПОЛНОЙ
  } else {
    myOLED.print(F("LJ RHFTD"), CENTER, pos);//ДО КРАЕВ
  }

}

  void Tost() {
  randomSeed(currentTime);
  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print(F("YE!"), CENTER, 15); //НУ!
  // Рандом - 1
  switch (random(18)) {  // case 0...17
  case 0:
      myOLED.print(F("PF DCNHTXE!"), CENTER, 30); //ЗА ВСТРЕЧУ!
      mp3_play (2);  // Проигрываем "mp3/0002.mp3"
    delay(100);
    break;
  case 1:
      myOLED.print(F("PF RHFCJNE!"), CENTER, 30); //ЗА КРАСОТУ!
      mp3_play (3);  // Проигрываем "mp3/0003.mp3"
    delay(100);
    break;
  case 2:
      myOLED.print(F("PF LHE;,E!"), CENTER, 30); //ЗА ДРУЖБУ!
      mp3_play (4);  // Проигрываем "mp3/0004.mp3"
    delay(100);
    break;
  case 3:
      myOLED.print(F("DS <KBY"), CENTER, 30); //ВЫ БЛИН
      myOLED.print(F("LFTNT!"), CENTER, 45); //ДАЕТЕ!
      mp3_play (20);  // Проигрываем "mp3/0020.mp3"
    delay(100);
	break;
  case 4:
      myOLED.print(F("PF ,HFNCNDJ!"), CENTER, 30); //ЗА БРАТСТВО!
      mp3_play (5);  // Проигрываем "mp3/0005.mp3"
    delay(100);
    break;
  case 5:
      myOLED.print(F("PF"), CENTER, 30); //за
    myOLED.print(F("CGHFDTLKBDJCNM!"), CENTER, 45); //СПРАВЕДЛИВОСТЬ!
      mp3_play (6);  // Проигрываем "mp3/0006.mp3"
    delay(100);
    break;
  case 6:
      myOLED.print(F("PF HS,FKRE!"), CENTER, 30); //ЗА РЫБАЛКУ!
      mp3_play (7);  // Проигрываем "mp3/0007.mp3"
    delay(100);
    break;
  case 7:
      myOLED.print(F("PF BCRECCNDJ!"), CENTER, 30); //ЗА ИСКУССТВО!
      mp3_play (8);  // Проигрываем "mp3/0008.mp3"
    delay(100);
    break;
  case 8:
      myOLED.print(F("PF HFPEV!"), CENTER, 30); //ЗА РАЗУМ!
      mp3_play (9);  // Проигрываем "mp3/0009.mp3"
    delay(100);
    break; 
  case 9:
      myOLED.print(F("PF BCNBYYS["), CENTER, 30); //ЗА ИСТИННЫХ
      myOLED.print(F(":TYOBY!"), CENTER, 45); //ЖЕНЩИН!
      mp3_play (10);  // Проигрываем "mp3/0010.mp3"
    delay(100);
    break;
  case 10:
      myOLED.print(F("PF GJYBVFYBT!"), CENTER, 30); //ЗА ПОНИМАНИЕ!
      mp3_play (11);  // Проигрываем "mp3/0011.mp3"
    delay(100);
    break;
  case 11:
      myOLED.print(F("PF TLBYTYBT!"), CENTER, 30); //ЗА ЕДИНЕНИЕ!
      mp3_play (13);  // Проигрываем "mp3/0013.mp3"
    delay(100);
    break;
  case 12:
      myOLED.print(F("PF GJ,TLE!"), CENTER, 30); //ЗА ПОБЕДУ!
      mp3_play (16);  // Проигрываем "mp3/0016.mp3"
    delay(100);
    break;
  case 13:
      myOLED.print(F("PF HJLBYE!"), CENTER, 30); //ЗА РОДИНУ!
      mp3_play (21);  // Проигрываем "mp3/0021.mp3"
    delay(100);
    break;
  case 14:
      myOLED.print(F("XNJ, UJKJDF"), CENTER, 30); //ЧТОБ ГОЛОВА
    myOLED.print(F("YT NHTOFKF!"), CENTER, 45); //НЕ ТРЕЩАЛА!
      mp3_play (17);  // Проигрываем "mp3/0017.mp3"
    delay(100);
    break;
  case 15:
      myOLED.print(F("PF CJKBLYJT"), CENTER, 30); //ЗА СОЛИДНОЕ
    myOLED.print(F("VE;CRJT VJKXFYBT"), CENTER, 45); //МУЖСКОЕ МОЛЧАНИЕ
      mp3_play (12);  // Проигрываем "mp3/0012.mp3"
    delay(100);
    break;
  case 16:
      myOLED.print(F("XNJ, VJHOBKJ"), CENTER, 30); //ЧТОБ МОРЩИЛО
    myOLED.print(F("YFC VTYMIT!"), CENTER, 45); //НАС МЕНЬШЕ!
      mp3_play (18);  // Проигрываем "mp3/0018.mp3"
    delay(100);
    break;
  case 17:
      myOLED.print(F("XNJ, D CNJHJYE"), CENTER, 30); //ЧТОБ В СТОРОНУ
    myOLED.print(F("YT DBKMYEKJ!"), CENTER, 45); //НЕ ВИЛЬНУЛО!
      mp3_play (19);  // Проигрываем "mp3/0019.mp3"
    delay(100);
    break;      
  }
  delay(2000);
  myOLED.update();

}

// Меню Авто режим
void oled_auto(int Drink) {

  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print(F("FDNJ JUJYM"), CENTER, 4); //АВТО ОГОНЬ
  DrinkInfo(52);
  //  myOLED.print(DrinkInfo[map(Drink, 2, max_Drink, 0, 4)], CENTER, 57);
  myOLED.setFont(MegaNumbers);
  myOLED.print(String(Drink), CENTER, 13);
  myOLED.update();
}

// Меню Ручной режим
void oled_manual(int DrinkCount, int Drink) {

  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print(F("HEXYJQ PFHZL"), CENTER, 4); //РУЧНОЙ ЗАРЯД 
  DrinkInfo(52);
  // myOLED.print(DrinkInfo[map(Drink, 2, max_Drink, 0, 4)], CENTER, 57);
  myOLED.print(F("H>V"), 24, 27);  // РЮМ
  myOLED.print(F("VK "), RIGHT, 27);
  myOLED.setFont(MegaNumbers);
  myOLED.print(String(DrinkCount), LEFT, 13);
  myOLED.print(String(Drink), (Drink < 10) ? 80 : 57, 13);
  myOLED.update();
}


void oled_naliv(int MenuFlag) {
  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print((MenuFlag == 1) ? F("FDNJ JUJYM") : F("HEXYJQ PFHZL") , CENTER, 4); // АВТО ОГОНЬ   РУЧНОЙ ЗАРЯД 

  myOLED.print(F("JNRHSDF> JUJYM"), CENTER, 27); //ОТКРЫВАЮ ОГОНЬ
  DrinkInfo(47);
  myOLED.update();
}

void oled_nalito(int MenuFlag, int Nalito) {
  myOLED.clrScr();
  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
  myOLED.setFont(RusFont);
  myOLED.print((MenuFlag == 1) ? F("FDNJ JUJYM") : F("HEXYJQ PFHZL") , CENTER, 4); // АВТО ОГОНЬ   РУЧНОЙ ЗАРЯД
  
  if (Nalito == 1) {
    myOLED.print(F("G J H F : T Y F"), CENTER, 20); // ПОРАЖЕНА
    myOLED.print(F("W T K M"), CENTER, 55); //ЦЕЛЬ
  } else if (Nalito <= 4 ) {
    myOLED.print(F("G J H F : T Y J"), CENTER, 20); // ПОРАЖЕНО
    myOLED.print(F("W T K B"), CENTER, 55); //ЦЕЛИ
  } else {
    myOLED.print(F("G J H F : T Y J"), CENTER, 20); // ПОРАЖЕНО
    myOLED.print(F("W T K T Q"), CENTER, 55); //ЦЕЛЕЙ
  }

  myOLED.setFont(SmallFont);
  myOLED.print(String(Nalito), CENTER, 36);
  myOLED.update();
}

void ServoNaliv(byte rumka) {
  servo.attach(PIN_SERVO);
  for (int pos = servo.read(); pos <= Rumka_pos[rumka]; pos += 1) { 
    // с шагом в 1 градус
    servo.write(pos); // даем серве команду повернуться в положение, которое задается в переменной 'pos'
    delay(servo_speed); // ждем , пока ротор сервы выйдет в заданную позицию
  }
  servo.detach();
}

void ServoParking () {
  //Serial.println(servo.read());
  servo.attach(PIN_SERVO);
  for (int pos = servo.read();  pos >= 0; pos -= 1) {     // с шагом в 1 градус
    servo.write(pos); // даем серве команду повернуться в положение, которое задается в переменной 'pos'
    delay(servo_speed); // ждем , пока ротор сервы выйдет в заданную позицию
  }
  servo.detach();
}
// Старая подсветка
//void CvetoMuzik() {
//  for (int i = 0; i <= 7; i++) {
//    for (int y = 0; y < max_DrinkCount; y++) {
//      strip.setPixelColor(y, strip.Color(255, 0, 0));
//      strip.show();
//     delay(30);
//    }
//    for (int y = 0; y < max_DrinkCount; y++) {
//      strip.setPixelColor(y, strip.Color(0, 255, 0));
//      strip.show();
//      delay(30);
//    }
//    for (int y = 0; y < max_DrinkCount; y++) {
//      strip.setPixelColor(y, strip.Color(0, 0, 255));
//      strip.show();
//      delay(30);
//    }
//  }
//}


// Новая подсветка для проверки
void CvetoMuzik() {
    for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 768) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(10);  // Pause for a moment
  }

    tick++;
if (tick == 5) {

            randomSeed(currentTime);
  switch (random(3)) {  // case 0...2
    case 0:
      mp3_play (188);  // Проигрываем "mp3/0002.mp3"
    delay(100);
    break;
  case 1:
      mp3_play (166);  // Проигрываем "mp3/0003.mp3"
    delay(100);
    break;
  case 2:
      mp3_play (177);  // Проигрываем "mp3/0004.mp3"
    delay(100);
    break;
  }

tick = 0;
  }
}


void celi()  {   // Мелодия перед наливом
            myOLED.clrScr();
            myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
            myOLED.setFont(RusFont);
            myOLED.print(F("J<YFHE:TYBT WTKTQ"), CENTER, 20); //ОБНАРУЖЕНИЕ ЦЕЛЕЙ 
            myOLED.print(F("LKZ GJHF:TYBZ"), CENTER, 40); // ДЛЯ ПОРАЖЕНИЯ
            delay(300);
            mp3_play (52);    
            myOLED.update();
            delay(3000);
}

void setup()  {
  Serial.begin(9600);//
  //устанавливаем Serial порт МП3 плейера если вывод в монитор TX(D0) и RX(D1)не нужен 
  mp3_set_serial (Serial);//инициализируем Serial порт МП3 плейера
  delay (100);//Между двумя командами необходимо делать задержку 100 миллисекунд, в противном случае некоторые команды могут работать не стабильно.
  mp3_set_volume (20);// устанвливаем громкость 20
  delay (100);
  mp3_play (1); // Проигрываем "mp3/0001.mp3"
  delay (100);
  //   Volume=EEPROM.read(0);
  myOLED.begin(); // Инициализация дисплея
  //myOLED.invert(1); //инвертировать дисплей

// выводим привествие после включения перед наливом

//-------------рисунок перед загрузкой---------------------
           myOLED.clrScr();
           myOLED.drawBitmap(12, 0, graf, 103, 64); //координата Х координата У, название, ширина и высота изображения
           myOLED.update();
           //myOLED.invert(1);
           delay(5000);
           //myOLED.invert(0);
//---------------------------------------------------------

//  myOLED.clrScr();  
//  myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
//  myOLED.setFont(RusFont);
//  myOLED.print(F("PFDJLBVCZ!"), CENTER, 25);// ЗАВОДИМСЯ!
//  myOLED.update(); 
//   delay (4000);
   
   // Выводит на экран Настройка систем 
   myOLED.clrScr();
   myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
   myOLED.setFont(RusFont);
   myOLED.print(F("GHJBPDJ:E"), CENTER, 20); //ПРОИЗВОЖУ 
   myOLED.print(F("YFCNHJQRE CBCNTV"), CENTER, 40); // НАСТРОЙКУ СИТЕМ
   myOLED.update();
   delay(3000);
   
   // Выводит на экран Все системы работают нормально
   myOLED.clrScr();
   myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
   myOLED.setFont(RusFont);
   myOLED.print(F("DCT CBNTVS"), CENTER, 20); //ВСЕ СИСТЕМЫ 
   myOLED.print(F("D YJHVT"), CENTER, 40); // В НОРМЕ
   myOLED.update();
   delay(3000);
   
   
  pinMode(pin_SW, INPUT); // устанавливаем pin pin_SW как вход
  digitalWrite(pin_SW, HIGH); // Поддяжка вывода к 1
  pinMode(pin_A, INPUT);
  pinMode(pin_B, INPUT);
  pinMode(PIN_PUMP, OUTPUT);
  digitalWrite(PIN_PUMP, 0);
  currentTime = millis();
  loopTime = currentTime;
  //---------------
  oled_menu(0);
  strip.begin();
  for (int i = 0; i < 5; i++) {
    pinMode(Optics[i], INPUT);
  }
  ServoParking();

}

void loop()  {
  currentTime = millis();
  if (currentTime >= (loopTime + 5)) { // проверяем каждые 5мс

    //     int  val = analogRead(0);     // считываем значение
    //  Serial.println(val);
    encoder_A = digitalRead(pin_A);     // считываем состояние выхода А энкодера
    encoder_B = digitalRead(pin_B);     // считываем состояние выхода B энкодера
    if ((!encoder_A) && (encoder_A_prev)) {  // если состояние изменилось с положительного к нулю

      //Вращение влево
      if (encoder_B) {
        if (MenuFlag == 0) {
          (Menu <= 0 ) ? Menu = 2 : Menu--; // Перемещение курсора по главному меню назад
          oled_menu(Menu);
        } else if (MenuFlag == 1) {
          (Drink <= min_Drink ) ? Drink = max_Drink : Drink-=5; // Уменьшаем кол-во милилитров в рюмку с шагом 5
          oled_auto(Drink);
        } else if (MenuFlag == 2) {
          (DrinkCount >= max_DrinkCount ) ? DrinkCount = 1 : DrinkCount++; // Влево увечичиваем рюмки для ручного режима
          oled_manual(DrinkCount, Drink);
        }
        //Вращение вправо
      } else {
        if (MenuFlag == 0) {
          (Menu >= 2 ) ? Menu = 0 : Menu++; // Перемещение курсора по главному меню вперед.
          oled_menu(Menu);
        } else if (MenuFlag == 1) {
          (Drink >= max_Drink ) ? Drink = min_Drink : Drink+=5;
          oled_auto(Drink);
        } else if (MenuFlag == 2) {
          (Drink >= max_Drink ) ? Drink = min_Drink : Drink+=5;
          oled_manual(DrinkCount, Drink);
        }
      }

    }

    encoder_A_prev = encoder_A;     // сохраняем значение А для следующего цикла

    byte autoMode = false;
    byte activeShotCount = 0;

    if(MenuFlag == 1){
        for (int y = 0; y < max_DrinkCount; y++) {
            if (analogRead(Optics[y]) < Optics_porog[y])    activeShotCount++;
        }
        if(activeShotCount == 0) allDone == false;
        if(activeShotCount > 0 && !allDone) autoMode = true;
        else autoMode = false;
    }
    else    autoMode = false;
    

    int encoder_sw = digitalRead(pin_SW);
    if  (encoder_sw == 0 && encoder_sw != encoder_sw_prew || autoMode)  { // Нажата кнопка

      int pause_sw = 0;
      boolean promivka = false;
      while (digitalRead(pin_SW) == 0) { // Держим кнопку. Считаем сколько времени прошло...
        delay(100);
        pause_sw++;
        if (pause_sw > 20 && Menu != 2 ) break;

        if (pause_sw > 20 && Menu == 2 && promivka == false) { // Если пункт меню промывка и держим кнопку больше 2 секунд.
          promivka = true;
          pump_enable(); // Включаем насос
          myOLED.clrScr();
          myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
          myOLED.setFont(RusFont);
          myOLED.print(F("GHJRFXRF CBCNTVS"), CENTER, 15); // ПРОКАЧКА СИСТЕМЫ
          myOLED.print(F("* * * * *"), CENTER, 45);
          myOLED.update();
        }
      }

      //После отпускания кнопки , обрабатываем
      if (promivka == true) { //Отпустили кнопку. Если включена промывка, выключаем насос и возвращаемся в главное меню
        promivka = false;
        pump_disable() ; //Выключаем насос
        oled_menu(2);

      } else {
        //Обработка всех нажатий кнопки
        if (Menu == 0 && MenuFlag == 0 &&  pause_sw < 10) { //Нажатие кнопки меню авто
          MenuFlag = 1;
          oled_auto(Drink);
        } else if (MenuFlag == 1 && pause_sw > 20) { //Выход из меню авто в главное
          MenuFlag = 0;
          oled_menu(0);
        } else if (MenuFlag == 1) { //Начинается автоматический разлив
          
          celi();           // Мелодия перед наливом в авторежиме
          
          Serial.println("Начало автоматического разлива");
          oled_naliv(MenuFlag); // Выводим на экран наливаем ...
          byte drink_count = 0;
          for (int y = 0; y < max_DrinkCount; y++) {
            if (analogRead(Optics[y]) < Optics_porog[y] ) {
              strip.setPixelColor(y, strip.Color(255, 0, 0)); // Подствечиваем красным цветом
              strip.show();
              ServoNaliv(y); // Перемещяемся к рюмке
              pump_timer(Drink); // Налив.
              strip.setPixelColor(y, strip.Color(0, 255, 0)); // Подствечиваем зеленым , налито.
              strip.show();
              drink_count++;
            }
          }
          if (drink_count > 0) {
            allDone = true;
            oled_nalito(MenuFlag, drink_count );
            ServoParking();
            //delay(1000);
            Tost();
            CvetoMuzik();
            oled_auto(Drink);
          } else {
            myOLED.clrScr();
            myOLED.drawRect(0, 0, 127, 63); //рамка вокруг
            myOLED.setFont(RusFont);
            myOLED.print(F("YTN WTKTQ!"), CENTER, 10); //НЕТ ЦЕЛЕЙ!
			myOLED.print(F("J<JPYFXMNT WTKM"), CENTER, 30); // ОБОЗНАЧЬТЕ ЦЕЛИ
            myOLED.print(F("LKZ GJHF:TYBZ!"), CENTER, 50); // ДЛЯ ПОРАЖЕНИЯ!
      delay(300);
            mp3_play (88);  // Играем сирену.
            myOLED.update();
            delay(5000);
            oled_auto(Drink);

          }
        } else if (Menu == 1 && MenuFlag == 0 &&  pause_sw < 10) { // Нажатие меню ручное
          MenuFlag = 2;
          oled_manual(DrinkCount, Drink);
        } else if (MenuFlag == 2 && pause_sw > 20) { //Выход из меню ручное в главное
          MenuFlag = 0;
          oled_menu(1);
        } else if (MenuFlag == 2 ) { //Начинается ручной разлив

            celi(); //Мелодия перед ручным наливом
                        
		  oled_naliv(MenuFlag); // Выводим на экран наливаем ...
          for (int y = 0; y < DrinkCount; y++) {
            strip.setPixelColor(y, strip.Color(255, 0, 0)); // Подствечиваем красным цветом
            strip.show();
            ServoNaliv(y); // Перемещяемся к рюмке
            pump_timer(Drink); // Налив.
            strip.setPixelColor(y, strip.Color(0, 255, 0)); // Подствечиваем зеленым , налито.
            strip.show();
          }
          oled_nalito(MenuFlag, DrinkCount );
          ServoParking();
          Tost();
          CvetoMuzik();
          oled_manual(DrinkCount, Drink);
        }
      }
    }

    if (currentTime >= (ledTime + 300)) {
      //Опрашиваем оптопары ... Если рюмка поставлена , светодиод светится синим, нет ничего - не светится
      for (int i = 0; i < max_DrinkCount; i++) {
        
        int val = analogRead(Optics[i]);     // считываем значение
        Serial.println(val);
        if (val < Optics_porog[i]) {
          strip.setPixelColor(i, strip.Color(0, 0, 255)); 
        } else {
          strip.setPixelColor(i, strip.Color(0, 0, 0));
        }
    //    delay(20);

      }
      strip.show();
      ledTime = currentTime;
    }
    encoder_sw_prew = encoder_sw;
    loopTime = currentTime;

  }
}
Gridzilla
Offline
Зарегистрирован: 25.10.2019

VICLER пишет:

немного изменил прошивку, можете попробовать. Теперь в авто режиме всегда должен ждать новую рюмку и как только она появится тут же наливать. Я не добавлял нового режима, только изменил старый автоматический


Ух, спасибо! Но попробовать смогу послезавтра. Умотал в командировку. По сути принцип теперь понятен... На сколько хватает моих познаний...

VICLER
Offline
Зарегистрирован: 30.12.2019

Там в 546 строке нужно вместо allDone == false; убрать один знак =

Gridzilla
Offline
Зарегистрирован: 25.10.2019

VICLER пишет:
Там в 546 строке нужно вместо allDone == false; убрать один знак =

Как-то не хочет работать :( После налива едет в парковку. Если закомментировать 

if (drink_count > 0) {
            allDone = true;
           // oled_nalito(MenuFlag, drink_count );
           // ServoParking();
            ////delay(1000);
            //Tost();
            //CvetoMuzik();
            //oled_auto(Drink);

То стоит и никуда не едет. 

aleksandr1612
aleksandr1612 аватар
Offline
Зарегистрирован: 18.12.2017

raven78 пишет:

Сделал под мегу, все изменения пришли от 38 скетча. По возможности буду и под мегу вносить изменения.

Доброе утро, Роман)))! Погонял 38-ой скетч, вот что заметил, серво мотор периодически при возврате начинает рывками работать и доп лента иногда подвисает вся светится иногда синий сегмент диода горит, вернулся на 36-ой скетч все стало нормально работать, сижу сравниваю скетчи, вроде все нормально.

raven78
Offline
Зарегистрирован: 03.11.2019

Нужно попробовать убрать с 11 пина доп-лед-ленту, на другой пин, вся гребёнка боковая свободна с 22 по 53 пины

aleksandr1612
aleksandr1612 аватар
Offline
Зарегистрирован: 18.12.2017

raven78 пишет:

Нужно попробовать убрать с 11 пина доп-лед-ленту, на другой пин, вся гребёнка боковая свободна с 22 по 53 пины

вечером попробую, спасибо

Acket
Offline
Зарегистрирован: 23.07.2019

Поставил плату, подключил, всё заработало. Разъём воткнутый в ардуинку - d+ и d- завёл на заднюю панель ко водному микроUSB

sarsab
Offline
Зарегистрирован: 23.01.2020

Acket пишет:

Поставил плату, подключил, всё заработало. Разъём воткнутый в ардуинку - d+ и d- завёл на заднюю панель ко водному микроUSB

 

как плату такую прикупить?

Acket
Offline
Зарегистрирован: 23.07.2019

Я, честно говоря про продажу не думал ещё. Но, если будет интересно, то можно обсудить. Но я не планировал доп кнопку и доп ленту, поэтому под них разводку не делал

Acket
Offline
Зарегистрирован: 23.07.2019

Тут где-то обсуждалось про сервопривод. У меня сильно просаживает питание на скорости выше 22, иногда до перезагрузки...доп кондёры не помогают, поди сама серва г-но движок с кз в обмотках? бывает такое?

sarsab
Offline
Зарегистрирован: 23.01.2020

я прям на экран кондер поставил,стало лучше немного.а вот с помпы снял,неработает с ней,как будто кз получается,во время налива экран аж гаснет,поменял кондер все тоже самое в итоге снял его и все норм .

aleksandr1612
aleksandr1612 аватар
Offline
Зарегистрирован: 18.12.2017

использую два модуля XL6009, на микросхему радиатор поставил, никаких падений напряжения не наблюдаю, на входе каждого кондеры стоят, серво мотор mg996r подключен на прямую на 5 вольт, помпу ставил и мембранную и шестерёнчатую (последняя больше потребляет), единственно запитывал от БП и проверял от повербанка.

stpavel
Offline
Зарегистрирован: 09.10.2018

sarsab пишет:

Acket пишет:

Поставил плату, подключил, всё заработало. Разъём воткнутый в ардуинку - d+ и d- завёл на заднюю панель ко водному микроUSB

 

как плату такую прикупить?


А чем jlcpcb не вариант ? Пять плат с доставкой в районе 10 баксов , зато можно под себя нарисовать что душе угодно

Acket
Offline
Зарегистрирован: 23.07.2019

Согласен. Этот вариант самый оптимальный для того, кто хочет сделать устройство под себя.

vitali86899
Offline
Зарегистрирован: 23.05.2020

Acket пишет:
Согласен. Этот вариант самый оптимальный для того, кто хочет сделать устройство под себя.

Уважаемый Acket, можете скинуть вашу плату и ссылки на компоненты и скетч, уж очень хочется собрать сие чудо)). Заранее спасибо! vitali86899@gmail.com

Acket
Offline
Зарегистрирован: 23.07.2019

Скетч использую от Романа, схема его же. Только изначально выводы немного другие использовал, так как прошивка была другая и чтобы не менять соединения просто в скетче поменял, а потом и плату под это развёл... В ней из за спешки было допущено 3 ошибки не критичных, я их исправил:

1) Не вывел отдельным разъёмом OUT+

2) Катод D2 соединённый с реле не соединил с +5

3) Резистор вольтметра с А7 вывел на +5В вместо IN+  с бустеров

Сделал их таких 5шт. 2 запаял. Одну собрал в корпусе, с одной на столе играюсь... Остальные в принципе могу продать, если надо

Тестовый стенд :)

Acket
Offline
Зарегистрирован: 23.07.2019

Роману отправил комплимент на кошелёк 410012586782299 :)

Желаю творческих успехов и возможности к реализации идей!

raven78
Offline
Зарегистрирован: 03.11.2019

Acket пишет:

Роману отправил комплимент на кошелёк 410012586782299 :)

Желаю творческих успехов и возможности к реализации идей!

Спасибо))). Будем стараться))).

vuster
Offline
Зарегистрирован: 11.11.2019

Acket пишет:

Роману отправил комплимент на кошелёк 410012586782299 :)

Желаю творческих успехов и возможности к реализации идей!

я тоже отправил небольшой комплимент :), проект оказался очень 

востребованным!!!

Носмас
Offline
Зарегистрирован: 13.06.2020

Использую ttp229 выпаял два кондёра.
Вместо датчиков использую электрические круглые клеммы, Приклеенные на морду наливатора. Вроде работает, но не так как хотелось бы.
Ставлю 1 и 2 рюмку центром на центр датчика - моргнёт и потухнет, а вот если чуть сдвинуть рюмку - держит норм. Я бы понял если бы рюмку сдвигать в сторону подводящего провода, так нет, в обратную. 3,4 и 5 рюмка работают как часы.
Кто что подскажет

Добавлю.
Другой тип рюмок ставлю- всё работает. При чём ставил с дном меньшего диаметра- на ура работает, чуть в выпуклым дном - тоже, рюмки с фикспрайса - нормально только 3,4 и 5. Хотя дно там прям слегка вогнутое, но есть риски как на хрустале, но не глубокие.

Добавлю ещё.
Описанный случай на прошивке 21, а вот на прошивке 37 всё нормально

Acket
Offline
Зарегистрирован: 23.07.2019

Я купил медную липкую ленту (фольга). Наклеил ее на корпус под площадки подстаканников. Снизу припаялся и подключил к ттр229. Работает нормально.
А про какие круглые клеммы идёт речь?