Поправил код из 181 сообщения, с МП3 плейером, все работает
запятую вместо ? не получилось победить (по раскладке рус - "," англ - "?"), заменил на !
У меня почему то приветствие отображается как тост после налива. Если только с ардуины снять питание (на всё остальное питание подано) то приветствие озвучивается,но не отображается на экране.тосты"за братство"и"ну вы блин даёте"на экране отображаются одновременно накладываясь друг на друга(фото потом выложу).звучит при этом"за братство". Тосты "за дружбу" и "ну вы блин даёте" имеют одинаковый намер трека. В остальном всё нормально, спасибо.
RW3 у меня такая же ерунда, когда первый раз включаешь "НУ на-ча-лиииии" звучит ,так было задумано, на дисплее тоже не отображается, думаю надо вносить задержку, хотя в сетап может и не прописаться.
"ну вы блин даёте" трек 0020 кажется, проглядел сам. кейс 3 и 4 накладываются, причину пока не выяснил.
Я слаб в программировании, похоже все дело в русифицированной библиотеке. Работает все за исключением менюшек: "наливаю" , "налито" и автоматический розлив (кол-во мл не отображается на LCD, в порт все выводится).
Как раз наоборот должно быть. Я в самопал добавлял инвертор и всё хорошо работает.с покупными проблем не должно быть,если только там сигнал два раза не переворачивается. Сейчас жду покупные датчики с инвестором.придут ,посмотрим.
Как раз наоборот должно быть. Я в самопал добавлял инвертор и всё хорошо работает.с покупными проблем не должно быть,если только там сигнал два раза не переворачивается. Сейчас жду покупные датчики с инвестором.придут ,посмотрим.
Прикольно, у меня без инверторов работает! Без рюмки низкий уровень на выходе, с рюмкой - высокий.
Без инвертора тоже будет работать.из левой схемы уберите инвертор и получатся две разные схемы, одна с 1 на выходе другая с 0 .хотя на вид они похожи. Нашли разницу?
У меня сигнал снимается с коллектора , можно было просто перепаять провод, но я залил их со стороны монтажа термо клеем.и с инвертором срабатывание намного чётче из за триггера
У меня сигнал снимается с коллектора , можно было просто перепаять провод, но я залил их со стороны монтажа термо клеем.и с инвертором срабатывание намного чётче из за триггера
Спасибо. Все встало на свои места. Порог какой у датчика с триггером?
void DrinkInfo(byte pos) {
lcd.setCursor(0, 0); // устанавливаем курсор в 1-ю ячейку верхней строки
lcd.print(F("HАЛИТЬ ПО")); // пишем "HАЛИТЬ ПО" (с 1 по 9 ячейку)
lcd.setCursor(10, 0); // устанавливаем курсор в 11-ю ячейку верхней строки
lcd.print(Drink); // пишем переменную "Drink" в 11 и 12 ячейку (2 знака)
Serial.println(Drink); // выводим переменную ""Drink" в монитор порт
lcd.setCursor(13, 0);// устанавливаем курсор в 14-ю ячейку верхней строки
lcd.print(F("мЛ?")); // пишем "мЛ?" (с 14 по 16 ячейку)
Вот Drink и не выводиться на LCD.
Фразы "Ни о чем", "по чуть- чуть", "в самый раз" и др. - при прокручивании энкодера изменяются на дисплее в зависимости от количества Drink. Аналогично и с DrinkCount и Drink в ручном режиме.
Я использую библиотеку Liquid_Crystal_i2c и дисплей с зашитой кириллицей.
Сообщение 116, короткий скетч для проверки и калибровки датчиков. Подключаешь датчики, заливаешь скетч, открываешь монитор порта. Смотришь значения без рюмок, ставишь рюмки , снова смотришь значения, вот эти значения и будут порогом срабатывания.
[/quote]
без рюмки-1001, с рюмкой-81. какое значение вставлять в скетч?
Сообщение 116, короткий скетч для проверки и калибровки датчиков. Подключаешь датчики, заливаешь скетч, открываешь монитор порта. Смотришь значения без рюмок, ставишь рюмки , снова смотришь значения, вот эти значения и будут порогом срабатывания.
[/quote]
без рюмки-1001, с рюмкой-81. какое значение вставлять в скетч?
[/quote]
1. поправить две строчки
432 if (analogRead(Optics[y]) > Optics_porog[y] ) {
490 if (val > Optics_porog[i]) {
поменять ">" (больше) на "<" (меньше).
2. поставвь 500
25 const unsigned int Optics_porog[] = {500,500,500,500,500};
sha-tosik, Вот вкратце процедуру описал для понимания
27 #define tcr1 750//порог ИК датчика 1// выставляй 500, можно оставить как есть 750
28 -31 //аналогично для остальных датчиков
109 //определение наличия стакана
110 int tcrt1 = analogRead(A1); // присваиваем переменной tcrt1 значение считанного с порта А1
111 if( tcrt1<tcr1) // сравниваем - если полученное с А1 значение меньше порога срабатывания датчика 1
374 { //проверка наличия стакана и включение лампочки под присутсвующим
375 if( analogRead(A1)<tcr1) strip[14] = CRGB::Indigo; // тут уже все прнятно
376 else strip[14] = CRGB::Black; // не зажигать 14 пиксель
с порогом разобрался. спасибо! подправьте пожалуйста скетч, чтобы светодиоды загорались так:https://www.youtube.com/watch?v=CzqTpZYdGlc скетч с первой страницы. светодиоды ws2812 5 штук
Там изначально была ещё и шкала налива из светодиодной ленты. В зависимости от количества налитого менялся цвет и количество включенных светодиодов.ссылка на видео это уже второй вариант устройства https://youtu.be/FXt5X5fnGc0
Я бы из первого скетча взял бы во эти строчки
myOLED.print("NS LEHFR?", CENTER, 10);// ты дурак?
239
myOLED.print("GJCNFDM H>VRB B", CENTER, 25);// поставь рюмку!
240
myOLED.print("YF:VB RYJGRE -JR-", CENTER, 40); //нажми ОК
241
myOLED.update();
RW3 у меня такая же ерунда, когда первый раз включаешь "НУ на-ча-лиииии" звучит ,так было задумано, на дисплее тоже не отображается, думаю надо вносить задержку, хотя в сетап может и не прописаться.
"ну вы блин даёте" трек 0020 кажется, проглядел сам. кейс 3 и 4 накладываются, причину пока не выяснил.
вся проблема в рандоме, накладывается кейс 4 накладывается на 3й, на ЛСД1602 накладываются 3,4 и 7й.
doza = map(ml, 1, 40, 125, 4700);// переводим знач перем ml интервала 1-40 в doza 125-4700 в милисекунды, в течение которых работает насос.диапазон подбирается при калибровке
delay(300); //ждем 0.3 секунды
digitalWrite(relPin, HIGH);//вкл реле
strip[i] = CRGB::Red; // красный пиксель на i адресе
FastLED.show();
delay(doza);// 2920=40мл
digitalWrite(relPin, LOW);//выкл реле
strip[i] = CRGB::Green; // зеленый пиксель на i адресе
FastLED.show();
rum+=1;
delay(1500);
}
void check()
{ //проверка наличия стакана и включение лампочки под присутсвующим
if( analogRead(A1)<tcr1) strip[4] = CRGB::Indigo;
else strip[4] = CRGB::Black;
if( analogRead(A2)<tcr2) strip[3] = CRGB::Indigo;
else strip[3] = CRGB::Black;
if( analogRead(A3)<tcr3) strip[2] = CRGB::Indigo;
else strip[2] = CRGB::Black;
if( analogRead(A6)<tcr4) strip[1] = CRGB::Indigo;
else strip[1] = CRGB::Black;
if( analogRead(A7)<tcr5) strip[0] = CRGB::Indigo;
else strip[0] = CRGB::Black;
FastLED.show();
/*
myOLED.setFont(MediumNumbers);//раскомментировать при подборе значений переменных tcr - с датчиков под рюмками.
Пробовал ставить 5, глючит, поэтому пошел от противного, поменял везде пиксели местами, чтобы первые пять диодов для подсветки работали, а остальные 10 как говориться в уме....
То-есть ардуинка подключена к ПК через usb, датчики к ардуино, а как запитываются сами датчики? Отдельно на датчики + и -?
можно от ардуины + - 5в
Поправил код из 181 сообщения, с МП3 плейером, все работает
запятую вместо ? не получилось победить (по раскладке рус - "," англ - "?"), заменил на !
У меня почему то приветствие отображается как тост после налива. Если только с ардуины снять питание (на всё остальное питание подано) то приветствие озвучивается,но не отображается на экране.тосты"за братство"и"ну вы блин даёте"на экране отображаются одновременно накладываясь друг на друга(фото потом выложу).звучит при этом"за братство". Тосты "за дружбу" и "ну вы блин даёте" имеют одинаковый намер трека. В остальном всё нормально, спасибо.
Фото
https://yadi.sk/i/gPs-D_7ATuDz2g
Причину пока не знаю
RW3 у меня такая же ерунда, когда первый раз включаешь "НУ на-ча-лиииии" звучит ,так было задумано, на дисплее тоже не отображается, думаю надо вносить задержку, хотя в сетап может и не прописаться.
"ну вы блин даёте" трек 0020 кажется, проглядел сам. кейс 3 и 4 накладываются, причину пока не выяснил.
точно так же.
Вечером буду изучать....
Forthomo А с индикатором 1602 разобрались?
Я слаб в программировании, похоже все дело в русифицированной библиотеке. Работает все за исключением менюшек: "наливаю" , "налито" и автоматический розлив (кол-во мл не отображается на LCD, в порт все выводится).
case 3: myOLED.print(F("DS <KBY"), CENTER, 38); //ВЫ БЛИН myOLED.print(F("LFTNT!"), CENTER, 55); //ДАЕТЕ! mp3_play (20); // Проигрываем "mp3/0020.mp3" delay(100);вот так надо сделать
mp3_play (20); наверно?
TCRT5000 . Буду ждать прошивку.
По применению датчиков TCRT5000 без переделки и добавления инвертора.
Это только предположение, но возможно в скетче поправить всего две строчки
432 if (analogRead(Optics[y]) > Optics_porog[y] ) {
490 if (val > Optics_porog[i]) {
поменять ">" (больше) на "<" (меньше). Это лучше объяснит автор скетча stpavel.
Был бы датчик попробовал бы.
да, конечно. С отпуска вышел , дергают постоянно.
mp3_play (20); И switch (random(19))
это не нужно, кейсов всего 18 (// case 0...17)
mp3_play (20); поправил
это не нужно, кейсов всего 18 (// case 0...17)
mp3_play (20); поправил
Я просто ещё один тост добавил "за женщин (был "за истинных женщин"), пусть будет.....
тогда конечно - switch (random(19)).
Хорошо бы было визуально заряд батареи прикрутить в уголок экрана, жалко одна свободная лапа осталась.
Здравствуйте!если не трудно есть полный список чего нужно приобрести для данного проекта?
Смотрите пост 163и 168
Никак не могу понять, почему при использовании покупного датчика TCRT5000 с триггером Шмидта возникают проблемы? Логика работы одинакова.
Как раз наоборот должно быть. Я в самопал добавлял инвертор и всё хорошо работает.с покупными проблем не должно быть,если только там сигнал два раза не переворачивается. Сейчас жду покупные датчики с инвестором.придут ,посмотрим.
Прикольно, у меня без инверторов работает! Без рюмки низкий уровень на выходе, с рюмкой - высокий.
Без инвертора тоже будет работать.из левой схемы уберите инвертор и получатся две разные схемы, одна с 1 на выходе другая с 0 .хотя на вид они похожи. Нашли разницу?
Я встречал обе схемы подключения Фототранзистора, у меня Самопал, сигнал снимается с эмитера.
RW3 какая у тебя схема?
У меня сигнал снимается с коллектора , можно было просто перепаять провод, но я залил их со стороны монтажа термо клеем.и с инвертором срабатывание намного чётче из за триггера
Спасибо. Все встало на свои места. Порог какой у датчика с триггером?
Не заморачивался с этим, выставил в скетче все по 50. Срабатывают чётко
А кто-нибудь заморачивался с индикаций заряда батареи на этом дисплее, как в оригинальном изделии автора?
Поделитесь ссылками на годные комплектующие!
void DrinkInfo(byte pos) { lcd.setCursor(0, 0); // устанавливаем курсор в 1-ю ячейку верхней строки lcd.print(F("HАЛИТЬ ПО")); // пишем "HАЛИТЬ ПО" (с 1 по 9 ячейку) lcd.setCursor(10, 0); // устанавливаем курсор в 11-ю ячейку верхней строки lcd.print(Drink); // пишем переменную "Drink" в 11 и 12 ячейку (2 знака) Serial.println(Drink); // выводим переменную ""Drink" в монитор порт lcd.setCursor(13, 0);// устанавливаем курсор в 14-ю ячейку верхней строки lcd.print(F("мЛ?")); // пишем "мЛ?" (с 14 по 16 ячейку)Вот Drink и не выводиться на LCD.
Фразы "Ни о чем", "по чуть- чуть", "в самый раз" и др. - при прокручивании энкодера изменяются на дисплее в зависимости от количества Drink. Аналогично и с DrinkCount и Drink в ручном режиме.
Я использую библиотеку Liquid_Crystal_i2c и дисплей с зашитой кириллицей.
Все нормуль с выводом
void oled_auto(int Drink) { char myStr[16]; lcd.clear(); sprintf(myStr,"Ha\273\270\263. \276o %02d \274\273.",Drink ); lcd.setCursor(0, 1); lcd.print(myStr); DrinkInfo(); } void DrinkInfo() { lcd.setCursor(0, 0); if (Drink < 15) { lcd.print(F(" H\270 o \300\265\274")); } else if (Drink < 28) { lcd.print(F(" \250o \300y\277\304-\300y\277\304")); } else if (Drink < 38) { lcd.print(F(" B ca\274\303\271 pa\267!")); } else if (Drink < 48) { lcd.print(F(" \250o \276o\273\275o\271!")); } else { lcd.print(F(" \340o \272pa\265\263")); } }TCRT5000 . Буду ждать прошивку.
По применению датчиков TCRT5000 без переделки и добавления инвертора.
Это только предположение, но возможно в скетче поправить всего две строчки
432 if (analogRead(Optics[y]) > Optics_porog[y] ) {
490 if (val > Optics_porog[i]) {
поменять ">" (больше) на "<" (меньше). Это лучше объяснит автор скетча stpavel.
Был бы датчик попробовал бы.
Совершенно верно.
Править нужно именно тут. К сожалению датчиков тоже нет, поэтому что они выдают , не знаю.
Я использую библиотеку Liquid_Crystal_i2c и дисплей с зашитой кириллицей.
Все нормуль с выводом
а какая марка дисплея? это похоже отечественный дисплей
Я использую библиотеку Liquid_Crystal_i2c и дисплей с зашитой кириллицей.
Все нормуль с выводом
а какая марка дисплея? это похоже отечественный дисплей
MT-16S2H
Могу опробовать тк сейчас через инвертируй работает
[/quote]
Сообщение 116, короткий скетч для проверки и калибровки датчиков. Подключаешь датчики, заливаешь скетч, открываешь монитор порта. Смотришь значения без рюмок, ставишь рюмки , снова смотришь значения, вот эти значения и будут порогом срабатывания.
[/quote]
без рюмки-1001, с рюмкой-81. какое значение вставлять в скетч?
Сообщение 116, короткий скетч для проверки и калибровки датчиков. Подключаешь датчики, заливаешь скетч, открываешь монитор порта. Смотришь значения без рюмок, ставишь рюмки , снова смотришь значения, вот эти значения и будут порогом срабатывания.
[/quote]
без рюмки-1001, с рюмкой-81. какое значение вставлять в скетч?
[/quote]
1. поправить две строчки
432 if (analogRead(Optics[y]) > Optics_porog[y] ) {
490 if (val > Optics_porog[i]) {
поменять ">" (больше) на "<" (меньше).
2. поставвь 500
25 const unsigned int Optics_porog[] = {500,500,500,500,500};
я про скетч с первой страницы. строки 27-31. там нужно выставить порог под каждый датчик
я про скетч с первой страницы. строки 27-31. там нужно выставить порог под каждый датчик
до вечера подождет? не читал полностью скетч.
подождет
sha-tosik, Вот вкратце процедуру описал для понимания
27 #define tcr1 750//порог ИК датчика 1// выставляй 500, можно оставить как есть 750
28 -31 //аналогично для остальных датчиков
109 //определение наличия стакана
110 int tcrt1 = analogRead(A1); // присваиваем переменной tcrt1 значение считанного с порта А1
111 if( tcrt1<tcr1) // сравниваем - если полученное с А1 значение меньше порога срабатывания датчика 1
374 { //проверка наличия стакана и включение лампочки под присутсвующим
375 if( analogRead(A1)<tcr1) strip[14] = CRGB::Indigo; // тут уже все прнятно
376 else strip[14] = CRGB::Black; // не зажигать 14 пиксель
с порогом разобрался. спасибо! подправьте пожалуйста скетч, чтобы светодиоды загорались так:https://www.youtube.com/watch?v=CzqTpZYdGlc скетч с первой страницы. светодиоды ws2812 5 штук
А как они сейчас у вас загораются?
RW3, приветствую!
вот именно: в скетче указано 15 пикселей
#define LED_COUNT 15// Указываем, какое количество пикселей у нашей ленты.
1й стакан - i=14, 2й - 13, 3й- 12, 4й-11, 5-й - 10.
Вывод: что то не так в скетче. Надо досконально разбираться.
sha-tosik, а с энкодером не проще сделать? Скетч есть, повторили несколько раз.
Там изначально была ещё и шкала налива из светодиодной ленты. В зависимости от количества налитого менялся цвет и количество включенных светодиодов.ссылка на видео это уже второй вариант устройства
https://youtu.be/FXt5X5fnGc0
Я бы из первого скетча взял бы во эти строчки
myOLED.print("NS LEHFR?", CENTER, 10);// ты дурак?
239
myOLED.print("GJCNFDM H>VRB B", CENTER, 25);// поставь рюмку!
240
myOLED.print("YF:VB RYJGRE -JR-", CENTER, 40); //нажми ОК
241
myOLED.update();
Если во время налива убрать рюмку
RW3 у меня такая же ерунда, когда первый раз включаешь "НУ на-ча-лиииии" звучит ,так было задумано, на дисплее тоже не отображается, думаю надо вносить задержку, хотя в сетап может и не прописаться.
"ну вы блин даёте" трек 0020 кажется, проглядел сам. кейс 3 и 4 накладываются, причину пока не выяснил.
вся проблема в рандоме, накладывается кейс 4 накладывается на 3й, на ЛСД1602 накладываются 3,4 и 7й.
В программировании не силен, но с диодами вроде справился по изначальному скетчу
Добрый вечер!есть у кого фото уже законченного наливатора?
В программировании не силен, но с диодами вроде справился по изначальному скетчу
#define LED_COUNT 5// Указываем, какое количество пикселей у нашей ленты -5.
Пробовал ставить 5, глючит, поэтому пошел от противного, поменял везде пиксели местами, чтобы первые пять диодов для подсветки работали, а остальные 10 как говориться в уме....
Вот скетч для LCD1602 без вшитой кирилицы, косяки есть конечно, думаю сообща устраним.
#include <LCD_1602_RUS.h> #include <Servo.h> #include "Adafruit_NeoPixel.h" #include <SoftwareSerial.h>//добавляем библиотеки #include <DFPlayer_Mini_Mp3.h>//добавляем библиотеку МП3 плейера LCD_1602_RUS lcd(0x3F, 16, 2); //Подключение экрана А4-SDA-зеленый, А5-SCL-желтый 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[] = {100,200,200,200,100}; //Серво const int PIN_SERVO = 9; Servo servo; //Позиция каждой рюмки const byte Rumka_pos[] = {3,50,98,145,179}; //12 - 48 - 90 - 135 - 174 const byte servo_speed=20; // Скорость поворота серво, 10 - норм, 20 медленно, 30 очень медленно byte Menu = 0; byte MenuFlag = 0; // Здесь храниться уровень меню. 0 находимся в Главном меню. 1 Вошли в меню Авто, 2 вошли в Ручное управление byte Drink = 20; // По умолчанию в рюмку наливаем 20 мл. //----- Минимальные и максимальные значения наполняемой жидкости и задержки для наполнения. const byte min_Drink = 2; // Минимум в рюмку - 2 мл. const byte max_Drink = 50; // Максимум в рюмку - 50 мл. // Калибровка работы насосика. Значения для налива min_Drink и max_Drink соотвественно const unsigned int min_Drink_delay = 222; const unsigned int max_Drink_delay = 5500; //-------- 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); //------- 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(byte Menu) { lcd.clear(); lcd.setCursor(3, 0); lcd.print(F("НАЛИВАТОР+")); lcd.setCursor(0, 1); lcd.print(F(">")); lcd.setCursor(15, 1); lcd.print(F("<")); switch (Menu) { case 0: lcd.setCursor(6, 1); lcd.print(F("АВТО")); break; case 1: lcd.setCursor(2, 1); lcd.print(F("РУЧНОЙ РЕЖИМ")); break; case 2: lcd.setCursor(4, 1); lcd.print(F("ПРОМЫВКА")); break; } } // выводит строчку по чуть чуть, в самый раз и тд. Передается номер строки, на которой выводить сообщение void DrinkInfo(byte pos) { Serial.println(F("INFO_DRINK")); lcd.setCursor(0, 1); if (Drink < 15) { // lcd.setCursor(0, 1); lcd.print(F(" НИ О ЧЕМ ")); } else if (Drink < 28) { // lcd.setCursor(0, 1); lcd.print(F(" ПО ЧУТЬ - ЧУТЬ ")); } else if (Drink < 38) { // lcd.setCursor(0, 1); lcd.print(F(" В САМЫЙ РАЗ ")); } else if (Drink < 48) { // lcd.setCursor(0, 1); lcd.print(F(" ПО ПОЛНОЙ ")); } else { // lcd.setCursor(0, 1); lcd.print(F(" ДО КРАЕВ ")); } } // Меню Авто режим void oled_auto(int Drink) { Serial.println(F("MENU_AUTO")); lcd.clear(); lcd.setCursor(0, 0); lcd.print(F("HАЛИТЬ ПО")); lcd.setCursor(10, 0); lcd.print(Drink); Serial.println(Drink); lcd.setCursor(13, 0); lcd.print(F("мЛ?")); DrinkInfo(57); } // Меню Ручной режим void oled_manual(int DrinkCount, int Drink) { Serial.println(F("MENU_RUCHN")); lcd.clear(); lcd.setCursor(0, 0); lcd.print(F("HАЛИТЬ ПО")); lcd.setCursor(10, 0); lcd.print(Drink); lcd.setCursor(13, 0); lcd.print(F("мЛ?")); Serial.println(Drink); lcd.setCursor(0, 1); lcd.print(F(" В РЮМ")); lcd.setCursor(5, 1); lcd.print(DrinkCount); Serial.println(DrinkCount); if (DrinkCount == 1) { lcd.setCursor(10, 1); lcd.print(F("КУ ")); } else if (DrinkCount <= 4 ) { lcd.setCursor(10, 1); lcd.print(F("КИ ")); } else { lcd.setCursor(10, 1); lcd.print(F("ОК ")); } } // Меню налива void oled_naliv(int MenuFlag, int Drink, int DrinkCount) { Serial.println(F("NALIVAIU")); lcd.clear(); lcd.setCursor(0, 0); lcd.print(F("НАЛИВАЮ ПО")); lcd.setCursor(11, 0); lcd.print(Drink); Serial.println(Drink); lcd.setCursor(14, 0); lcd.print(F("мЛ")); lcd.setCursor(0, 1); lcd.print(F(" В")); lcd.setCursor(5, 1); lcd.print(DrinkCount); Serial.println(DrinkCount); lcd.setCursor(7, 1); lcd.print(F("РЮМ")); if (DrinkCount == 1) { lcd.setCursor(10, 1); lcd.print(F("КУ ")); } else if (DrinkCount <= 4 ) { lcd.setCursor(10, 1); lcd.print(F("КИ ")); } else { lcd.setCursor(10, 1); lcd.print(F("ОК ")); } } // Меню налито void oled_nalito(int MenuFlag, int Nalito, int Drink) { Serial.println(F("NALITO")); lcd.clear(); lcd.setCursor(0, 0); lcd.print(F("HАЛИТО ПО")); lcd.setCursor(11, 0); lcd.print(Drink); Serial.println(Drink); lcd.setCursor(14, 0); lcd.print(F("мЛ")); lcd.setCursor(0, 1); lcd.print(F(" В")); lcd.setCursor(5, 1); lcd.print(Nalito); lcd.setCursor(7, 1); lcd.print(F("РЮМ")); Serial.println(Nalito); if (Nalito == 1) { lcd.setCursor(10, 1); lcd.print(F("КУ ")); } else if (Nalito <= 4 ) { lcd.setCursor(10, 1); lcd.print(F("КИ ")); } else { lcd.setCursor(10, 1); lcd.print(F("ОК ")); } } void Tost() { randomSeed(currentTime); //Рандом - 1 lcd.clear(); switch (random(20)) { // 0...19 case 0: //ЗА ВСТРЕЧУ! lcd.setCursor(7, 0); lcd.print(F("НУ,")); lcd.setCursor(2, 1); lcd.print(F("ЗА ВСТРЕЧУ!")); mp3_play (2); // Проигрываем "mp3/0002.mp3" delay(100); case 1: //ЗА КРАСОТУ! lcd.setCursor(7, 0); lcd.print(F("НУ,")); lcd.setCursor(2, 1); lcd.print(F("ЗА КРАСОТУ!")); mp3_play (3); // Проигрываем "mp3/0003.mp3" delay(100); case 2: //"ЗА ДРУЖБУ!" lcd.setCursor(7, 0); lcd.print(F("НУ,"));// lcd.setCursor(3, 1); lcd.print(F("ЗА ДРУЖБУ!")); mp3_play (4); // Проигрываем "mp3/0004.mp3" delay(100); case 3: //"ЗА БРАТСТВО! lcd.setCursor(7, 0); lcd.print(F("НУ,")); lcd.setCursor(2, 1); lcd.print(F("ЗА БРАТСТВО!")); mp3_play (5); // Проигрываем "mp3/0005.mp3" delay(100); case 4: //ЗА СПРАВЕДЛИВОСТЬ! lcd.setCursor(5, 0); lcd.print(F("НУ, ЗА")); lcd.setCursor(1, 1); lcd.print(F("СПРАВЕДЛИВОСТЬ!")); mp3_play (6); // Проигрываем "mp3/0006.mp3"11 delay(100); case 5: //ЗА РЫБАЛКУ! lcd.setCursor(7, 0); lcd.print(F("НУ,")); lcd.setCursor(3, 1); lcd.print(F("ЗА РЫБАЛКУ!")); mp3_play (7); // Проигрываем "mp3/0007.mp3" delay(100); case 6: //ЗА ИСКУССТВО! lcd.setCursor(7, 0); lcd.print(F("НУ,")); lcd.setCursor(2, 1); lcd.print(F("ЗА ИСКУССТВО!")); mp3_play (8); // Проигрываем "mp3/0008.mp3" delay(100); case 7: //ЗА РАЗУМ! lcd.setCursor(7, 0); lcd.print(F("НУ,")); lcd.setCursor(3, 1); lcd.print(F("ЗА РАЗУМ!")); mp3_play (9); // Проигрываем "mp3/0009.mp3" delay(100); break; case 8: //ЗА ИСТИННЫХ ЖЕНЩИН! lcd.setCursor(5, 0); lcd.print(F("НУ, ЗА")); lcd.setCursor(0, 1); lcd.print(F("ИСТИННЫХ ЖЕНЩИН!!")); mp3_play (10); // Проигрываем "mp3/0010.mp3" delay(100); break; case 9: //ЗА ПОНИМАНИЕ! lcd.setCursor(7, 0); lcd.print(F("НУ,")); lcd.setCursor(2, 1); lcd.print(F("ЗА ПОНИМАНИЕ!")); mp3_play (11); // Проигрываем "mp3/0011.mp3" delay(100); break; case 10: //ЗА ЕДИНЕНИЕ! lcd.setCursor(7, 0); lcd.print(F("НУ,")); lcd.setCursor(2, 1); lcd.print(F("ЗА ЕДИНЕНИЕ!")); mp3_play (13); // Проигрываем "mp3/0013.mp3" delay(100); break; case 11: //ЗА ПОБЕДУ! lcd.setCursor(7, 0); lcd.print(F("НУ,")); lcd.setCursor(3, 1); lcd.print(F("ЗА ПОБЕДУ!")); mp3_play (16); // Проигрываем "mp3/0016.mp3" delay(100); break; case 12: //ЗА РОДИНУ! lcd.setCursor(7, 0); lcd.print(F("НУ,")); lcd.setCursor(3, 1); lcd.print(F("ЗА РОДИНУ!")); mp3_play (21); // Проигрываем "mp3/0021.mp3" delay(100); break; case 13: //ЧТОБ ГОЛОВА НЕ ТРЕЩАЛА! lcd.setCursor(0, 0); lcd.print(F("НУ, ЧТОБ ГОЛОВА")); lcd.setCursor(2, 1); lcd.print(F("НЕ ТРЕЩАЛА!")); mp3_play (17); // Проигрываем "mp3/0017.mp3" delay(100); break; case 14: //ЗА СОЛИДНОЕ МУЖСКОЕ МОЛЧАНИЕ lcd.setCursor(0, 0); lcd.print(F("НУ, ЗА СОЛИДНОЕ"));//НУ, lcd.setCursor(0, 1); lcd.print(F("МУЖСКОЕ МОЛЧАНИЕ!")); mp3_play (12); // Проигрываем "mp3/0012.mp3" delay(100); break; case 15: //ЧТОБ МОРЩИЛО НАС МЕНЬШЕ! lcd.setCursor(0, 0); lcd.print(F("НУ,ЧТОБЫ МОРЩИЛО")); lcd.setCursor(2, 1); lcd.print(F("НАС МЕНЬШЕ ЧЕМ")); mp3_play (18); // Проигрываем "mp3/0018.mp3" delay(100); break; case 16: //ЧТОБ В СТОРОНУ НЕ ВИЛЬНУЛО! lcd.setCursor(0, 0); lcd.print(F("НУ,ЧТОБ В СТОРО-")); lcd.setCursor(0, 1); lcd.print(F("НУ НЕ ВИЛЬНУЛО!")); mp3_play (19); // Проигрываем "mp3/0019.mp3" delay(100); break; case 17: //НУ ВЫ БЛИН ДАЁТЕ! lcd.setCursor(2, 0); lcd.print(F("НУ ВЫ БЛИН")); lcd.setCursor(5, 1); lcd.print(F("ДАЁТЕ!")); mp3_play (20); // Проигрываем "mp3/0020.mp3" delay(100); break; case 18: //ЗА МИР ВО ВСЕМ МИРЕ lcd.setCursor(5, 0); lcd.print(F("ЗА МИР")); lcd.setCursor(2, 1); lcd.print(F("ВО ВСЕМ МИРЕ")); delay(2000); lcd.clear(); lcd.setCursor(0, 0); lcd.print(F("И БОЛЬШИЕ СИСЬКИ")); lcd.setCursor(5, 1); lcd.print("!!!!"); break; case 19: //ЗА НАС С ВАМИ lcd.setCursor(1, 0); lcd.print(F("ЗА НАС С ВАМИ")); lcd.setCursor(1, 1); lcd.print(F("И ХРЕН С НИМИ")); delay(100); break; } //mp3_stop(); delay(3000); //lcd.clear(); } 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 setup() { Serial.begin(9600);// //устанавливаем Serial порт МП3 плейера если вывод в монитор TX(D0) и RX(D1)не нужен mp3_set_serial (Serial);//инициализируем Serial порт МП3 плейера /* при необходимости создаем програмный порт для управдения МП3 плейером, если вывод в монитор TX(D0) RX(D1) необходим SoftwareSerial mySoftwareSerial(10, 11); // RX, TX обозначаем програмный порт как mySoftwareSerial //плейер подключаем D10 D11 mySoftwareSerial.begin(9600);//инициализируем програмный Serial порт mp3_set_serial (mySoftwareSerial);// указываем програмный порт для МП3 плейера //инициализируем Serial с скоростью 115200, если вывод в монитор TX(D0) RX(D1) необходим Serial.begin(115200); */ delay (100);//Между двумя командами необходимо делать задержку 100 миллисекунд, в противном случае некоторые команды могут работать не стабильно. mp3_set_volume (25);// устанвливаем громкость 25 delay (100); mp3_play (1); // Проигрываем "mp3/0001.mp3"(0001_get started!.mp3) delay (100); // Volume=EEPROM.read(0); lcd.init();// initialize the lcd lcd.backlight(); 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--; // Уменьшаем кол-во милилитров в рюмку 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++; oled_auto(Drink); } else if (MenuFlag == 2) { (Drink >= max_Drink ) ? Drink = min_Drink : Drink++; 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(); // Включаем насос lcd.clear(); lcd.setCursor(0, 0); lcd.print(F("П Р О М Ы В К А")); lcd.setCursor(2, 1); lcd.print(">>>>>>>>>>>>"); } } //После отпускания кнопки , обрабатываем 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 ) { //Начинается автоматический разлив Serial.println("AUTO"); //Начало автоматического разлива oled_naliv(MenuFlag, Drink, DrinkCount); // Выводим на экран наливаем ... 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, Drink ); ServoParking(); delay(1000); Tost(); CvetoMuzik(); oled_auto(Drink); } else { lcd.setCursor(7, 1); lcd.print(F("НЕТ РЮМОК!")); delay(2000); 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 ) { //Начинается ручной разлив Serial.println("RUCHNOY" + String(DrinkCount)); oled_naliv(MenuFlag, Drink, DrinkCount); // Выводим на экран наливаем ... 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, Drink ); // Выводим на экран налито ... 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; } }