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

Алексин
Offline
Зарегистрирован: 04.05.2020

серво работает отлично. по меню тоже нет вопросов все супер. вавгат не использую ибо много брака у них.    плата  чип atmel328p нано 3.0 NANO 328P-MCU
 https://aliexpress.ru/item/32855188188.html?spm=a2g0s.9042311.0.0.264d33edaAHfCg

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

У меня к стати на нано прошит загрузчик optibut 8.0, но я не думаю что в этом проблема. Ардуино иде версии 1.8.12  и ядро avr в менеджере плат 1.8.2 у меня.

Алексин
Offline
Зарегистрирован: 04.05.2020

 а у меня ядро 1.8.1 . в менеджере вроде последняя. ардуино также версии 1.8.12 ,а у вас ссылочки нет на ядро 1.8.2?

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

Это штатное ядро ардуино и должно само обновляться , попробовать выбрать версию 1.8.2, может есть в выборе и обновить

Алексин
Offline
Зарегистрирован: 04.05.2020

обновил до 1.8.2  . Был глюк при обновлении среды ардуино иде проблема с плеером и лед лентой не ушла.

Алексин
Offline
Зарегистрирован: 04.05.2020

 optibut 8.0 занимает меньше места? я вот склоняюсь к тому что скетч съедает много памяти и отсюда глюки с работой прошивки. Скетч использует 25262 байт (82%) памяти устройства.

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

Да optiboot 8.0  занимает меньше места. Сейчас проверил последний выложенный мной скетч

 

Скетч использует 25264 байт (82%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 943 байт (46%) динамической памяти, оставляя 1105 байт для локальных переменных. Максимум: 2048 байт.

Да я ещё позавчера перезалил архив со скетчем, поправил мелкие косяки, но и так всё работает. Вы заливаете прошивку через old bootloader?

Питание не просаживается, фильтр по питанию нормальный?

Алексин
Offline
Зарегистрирован: 04.05.2020

загружал через  old bootloader. ссылку на optiboot 8.0 не нашел прошил 6.2 но проблема пока осталась

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

Алексин пишет:

ссылку на optiboot 8.0 не нашел прошил 6.2 но проблема пока осталась

https://github.com/Optiboot/optiboot/releases

Алексин
Offline
Зарегистрирован: 04.05.2020

нашел косяк!!! оказывается я ̶м̶у̶д̶а̶к̶ дурак заливал прошивку в подпаленный контроллер. светодиоды на новом заработали. буду попробовать запустить плеер. с плеером также разобрался причина оказалась банальная. в названиях файлов лишний нолик как в папке мп3 которую я вообще не создал. спаибо за помощь и разъяснения по скетчу.

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

Привет. Опять я :)) 

Рулетка 

      // Рулетка
    else if (Rezim == 2 && MenuFlag == 1 && pause_sw < 10) { //вход в рулетку
          MenuFlag = 6;
          oled_rul(DrinkCount, Drink);
    } else if (MenuFlag == 6 && pause_sw > 20) { //Выход из меню рулетки в режимы
          MenuFlag = 1;
          oled_rezim(2);
    } else if (MenuFlag == 6 ) {  // запуск рулетки

          myDFPlayer.volume(vol_tost); 
          delay (100);
          myDFPlayer.playFolder (1, 105); 
          delay (1000);
          CvetoMuzik();
          delay (2000);
      for (int y = 0; y <= 4; y++) {
          strip.setPixelColor(y, strip.Color(255, 0, 0)); // Подствечиваем красным цветом все рюмки
          strip.show();
}
          servo.attach(PIN_SERVO);// серва туды сюды
      for (int pos = servo.read(); pos <= 180; pos += 1) {
          servo.write(pos);   
          delay(servo_speed); 
}
      for (int pos = servo.read();  pos >= 0; pos -= 1) {
          servo.write(pos);   
          delay(servo_speed); 
}

     int r = random(0, 5);       //рюмка в которую не нальёт
      for (int y = 0; y < 5; y++) {
        if (y != r) {
          ServoNaliv(y); // Перемещяемся к рюмке
          delay (300); //Задержка перед наливом после поворота к рюмке
          pump_timer(Drink, Optics[y]); // Налив.
          delay(1000);
          strip.setPixelColor(y, strip.Color(0, 255, 0)); // Налито.
          strip.show();
          delay(500);
  }
        else { (y=r);
 }
}
         
          servo.detach();
          ServoParking();
          myDFPlayer.volume(vol_tost);  
          delay (100);
          myDFPlayer.playFolder (1, 102);
          delay (3000);
          Tost();
          CvetoMuzik();
          oled_rul(DrinkCount, Drink);
    }

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

Если делать так, по аналогии с авто разливом, то да, льет в только поставленные, но не выбирает из них, а думает что их пять. Где я туплю?

byte drink_count = 0;
     int r = random(0, 5);       //рюмка в которую не нальёт
      for (int y = 0; y < 5; y++) {
        if (analogRead(Optics[y]) < Optics_porog[y] ) {
        if (y != r) {
          ServoNaliv(y); // Перемещяемся к рюмке
          delay (300); //Задержка перед наливом после поворота к рюмке
          pump_timer(Drink, Optics[y]); // Налив.
          delay(1000);
          strip.setPixelColor(y, strip.Color(0, 255, 0)); // Налито.
          strip.show();
          drink_count++;
          delay(500);
  }
        else { (y=r);
  }
 }
}

 

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

Acket пишет:

Acket пишет:

Заказал тут https://aliexpress.ru/item/33020496400.html должны на днях прийти. Проверю - отпишусь.

Получил, перепаял - те же яйца, только в профиль... такие же микросхемы, похоже...

Купил тут https://aliexpress.ru/item/33013050574.html?spm=2114.13010708.0.0.6d8b33edKr4uLR работают без проблем, уже час не выключает сигнал https://cloud.mail.ru/public/FuHU/5P4intbPp

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

Да вообще... день разочарований - получил долгожданную посылку из Китая, там автономные драйверы шаговиков с ручной регулировкой оборотов пуск/реверс и ещё интересные функции - промучился с nema 17 ни в какую - дёргаются, пару раз на вращение вывел, а так засада - срыв по питанию после 7-ми вольт, примерно... а набрал десяток, а стоят по три сотни... короче создал спор - предложили вернуть, буду отправлять. Микросхемы на кнопках-датчиках поменять хотел - пришли, но ровно такое же уг как и то, что стоит на сенсорах... Дальше - пришло несколько штук на 16 кнопок модулей, думал попробовать по аналогии, как тут пробегала схемка подключения, организовать... Не получилось - не видит стопку, на руку с 5 см реагирует, на стеклянный флакон с жидкостью тоже более ли менее, а на стопку пиливать хотел... То есть и эти датчики не зашли... Там ещё огорчения с поставкой, но это уже не для этой темы точно... в общем из мелких досадных случаев настроение опустилось напрочь. Заказал по ссылкам, что ребята писали, микросхем и вот тех красных датчиков... боюсь, что старые партии микросхем закончатся и будут сплошь только фэйки...

 

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

yrbasik пишет:

https://drive.google.com/file/d/1-yhT4qGs0VFRnEace2SGBz5DEfNawKp2/view?usp=sharing -первый запуск с жидкостью

А чего он наливает, как украл? побольше напруги дай ему

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

Acket пишет:

Да вообще... день разочарований -

Я вчера наконец-то получил кольца переходные на фотоаппарат. Китаяц, блин, вместо никона положил на кэнон, хотя в заказе как надо все. У них, видимо, так совпало, повсеместный капец...

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

yrbasik пишет:

https://drive.google.com/file/d/1-yhT4qGs0VFRnEace2SGBz5DEfNawKp2/view?usp=sharing -первый запуск с жидкостью

Это чей скетч у тебя? Датчики под стопками какие?

yrbasik
Offline
Зарегистрирован: 22.04.2020

Gridzilla пишет:

yrbasik пишет:

https://drive.google.com/file/d/1-yhT4qGs0VFRnEace2SGBz5DEfNawKp2/view?usp=sharing -первый запуск с жидкостью

Это чей скетч у тебя? Датчики под стопками какие?

Скетч от raven78,датчики TTP-223 с перепаянными микросхемами, пока только настраиваю,как всё закончу выложу видео.

Skobar
Offline
Зарегистрирован: 06.05.2020

Павел , если использовать в качестве датчиков такой вариант? И отверстия сверлить не надо. https://s.click.aliexpress.com/e/_dXYepUZ

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

не надо

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

Alex_samodelkin][quote=VICLER пишет:

цифрами обозначенны входы, зелёным перемычки. Площадки 40х40мм из текстолитовой платы с медным слоем (наверное 35мкм). Конденсаторы с платы снаты для повышения чувствительности. Под 3мм двп работает отлично без ложных срабатываний. 

 

 

Не понимаю зачем перемычки там? Не могу что-то справиться с такой же штукой. проверяю без текстолита, взял просто медную фольгу на липкой основе, прилепил снизу фанеры, к ней припаялся. не видит пустых стопок ни с кондёрами, ни без... если с жидкостью, то срабатывает. палец вообще за 5см видит... не пойму, как у Вас всё получилось...

 

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

Парни подскажите плиз,как выйти из режимов в главное меню,из промывки выходит из остальных не могу без перезагрузки.скетч от Алексея -крайний lsd1602 5.1.5+ плюс режимы казино.

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

Парни подскажите плиз,как выйти из режимов в главное меню,из промывки выходит из остальных не могу без перезагрузки.скетч от Алексея -крайний lsd1602 5.1.5+ плюс режимы казино.

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

Парни подскажите плиз,как выйти из режимов в главное меню,из промывки выходит из остальных не могу без перезагрузки.скетч от Алексея -крайний lsd1602 5.1.5+ плюс режимы казино.

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

sarsab пишет:

Парни подскажите плиз,как выйти из режимов в главное меню,из промывки выходит из остальных не могу без перезагрузки.скетч от Алексея -крайний lsd1602 5.1.5+ плюс режимы казино.


На скетч бы глянуть. Возможно не прописал что по длинному нажатию выход.

yrbasik
Offline
Зарегистрирован: 22.04.2020

У меня с ТТР-229 то же не получилось,много ложных срабатываний.

yrbasik
Offline
Зарегистрирован: 22.04.2020

Acket]</p> <p>[quote=Alex_samodelkin пишет:
VICLER пишет:

цифрами обозначенны входы, зелёным перемычки. Площадки 40х40мм из текстолитовой платы с медным слоем (наверное 35мкм). Конденсаторы с платы снаты для повышения чувствительности. Под 3мм двп работает отлично без ложных срабатываний. 

 

 

Не понимаю зачем перемычки там? Не могу что-то справиться с такой же штукой. проверяю без текстолита, взял просто медную фольгу на липкой основе, прилепил снизу фанеры, к ней припаялся. не видит пустых стопок ни с кондёрами, ни без... если с жидкостью, то срабатывает. палец вообще за 5см видит... не пойму, как у Вас всё получилось...

 

yrbasik
Offline
Зарегистрирован: 22.04.2020

Попробовал последний скетч от raven78,почему то не проигрывает тосты,точнее  проигрывает но не все,заменил в скетче tost от 20 версии,всё заиграло.

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

спасибо за наводку, что-то не поискал сразу... вот статейку накопал как раз https://radiolaba.ru/microcotrollers/modul-sensornoy-klaviaturyi-ttp229.html

тогда можно ещё  JP7 замкнуть

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

yrbasik пишет:

Попробовал последний скетч от raven78,почему то не проигрывает тосты,точнее  проигрывает но не все,заменил в скетче tost от 20 версии,всё заиграло.

Странно конечно, но изменения минимальные, которые не должны были привести к такому. По подробней, бы. Ещё я заметил, если всё таки обозвать файлы не правильно, они иногда воспроизводятся, но не так как хотелось бы.

yrbasik
Offline
Зарегистрирован: 22.04.2020

20 версия прошивки работает на отлично,структуру флешки не менял,только заменил папку  mp3.После подмены  tost  в 21 прошивке,всё работает,озвучивает если убрал рюмку во время налива и когда нет рюмок, что ещё должно озвучивать пока не разобрался.

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

Ещё если во время налива нажать на кнопку энкодера, будет отмена и воспроизведётся звук. Пока всё, можно ещё подумать на какие события звуки поставить))).  В папку MP3 я добавил звуков на будущее и пока не придумал где их использовать, по итогу задействованы только первые 4 трека. Да и ещё, если играет плеер, то все допзвуки не воспроизводятся.

yrbasik
Offline
Зарегистрирован: 22.04.2020

Кина не будет )))

yrbasik
Offline
Зарегистрирован: 22.04.2020

Можно попробовать тройной клик по энкодеру "оставь меня старушка я в печали".

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

raven78 пишет:

Ещё если во время налива нажать на кнопку энкодера, будет отмена и воспроизведётся звук. Пока всё, можно ещё подумать на какие события звуки поставить))).  В папку MP3 я добавил звуков на будущее и пока не придумал где их использовать, по итогу задействованы только первые 4 трека. Да и ещё, если играет плеер, то все допзвуки не воспроизводятся.


Когда нет рюмок для налива я себе поставил "Хьюстон, у нас проблема" :))

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

Настроил TTP229. В общем конденсаторы все остаются, я выпаял только С0 и С1 - они отвечают за чувствительность групп выводов 0-3 и 4-7 другие конденсаторы отвечают за другие вещи. кусочка липкой фольги, размером 1,5х1см под 4мм фанерой и пластиковой подставкой 1мм толщины, хватает в самый раз.

Сенсоры калибруются во время подачи питания, всякие шевеления проводов и датчиков после включения приведут к ошибке. поэтому всё собирается, фиксируется после чего подключается, автокалибруется и работает как надо

Simafor47
Offline
Зарегистрирован: 06.03.2020

Скиньте пожалуйста, кого не затруднит архив с тостами mp3. Тему прочитал, все ранее опубликованные ссылки не рабочие. Mohtaho@mail.ru спасибо

yrbasik
Offline
Зарегистрирован: 22.04.2020

Acket пишет:

Настроил TTP229. В общем конденсаторы все остаются, я выпаял только С0 и С1 - они отвечают за чувствительность групп выводов 0-3 и 4-7 другие конденсаторы отвечают за другие вещи. кусочка липкой фольги, размером 1,5х1см под 4мм фанерой и пластиковой подставкой 1мм толщины, хватает в самый раз.

Сенсоры калибруются во время подачи питания, всякие шевеления проводов и датчиков после включения приведут к ошибке. поэтому всё собирается, фиксируется после чего подключается, автокалибруется и работает как надо

Я делал так же, но у меня со временем начинались ложные срабатывания,может потому что делал сенсоры большего размера(диаметром под дно стопки),в итоге перешел на TTP-223.

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

с 223 карма не сошлась... 3 раза заказывал и ни одного попадания в нормальную микросхему...

 

 

DAFdriver
Offline
Зарегистрирован: 12.08.2016

Доброго времени суток , с днем Победы ( правда он вчера был) . прочитал весь форум , Кто может выложить готовый скетч и схему (дисплей LCD 1602) 6 стопок . За ранее благодарен .

DAFdriver
Offline
Зарегистрирован: 12.08.2016

Сорян коллеги прошил Naluvator 21 ,пока вроде все показывает (нет корпуса и плеера) , подскажите плиз концевики подключаем нормально замкнутые или разомкнутые и если правильно понимаю общий - gnd ? спасибо .

DAFdriver
Offline
Зарегистрирован: 12.08.2016

ГЛЮЧИТ прошивка , не видит концевики , уходит в сон , буду тестить дальше .

ДедСергей
Offline
Зарегистрирован: 15.05.2020

Здравствуйте, уважаемые.

Тоже заинтересовался таким аппаратом. Но не для спиртного, а внуку маленькому сок наливать. Но не суть. В общем пообщался с хорошим человеком (спасибо большое, если читаешь) и посоветовал все-таки сделать спящий режим, чтобы отключать экран LCD при работе от АКБ. В какую сторону копнуть почитать? Просто как это видится: пара функций типо

void sleep () {
noBacklight();
noDisplay():
}

И похожую на включение. Нет? Не хватает знаний сделать таймер. Или может уже кто-нибудь реализовал подобное? Скетч такой 


#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); //Порт дисплея обычно 0x27 или 0x3F, подключение экрана А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() { //Рандом - 1
  Serial.println(F("Tost"));  
    randomSeed(currentTime);
	byte num=random(20); // 0...19
 Serial.println(num);
   mp3_set_volume (20);// устанвливаем громкость 20 (если хотите установить
//   кнопки для регулировки громкости вручную, закоментируйте эту и с
//ледующую строчку)
   delay (100);
   lcd.clear();
    switch (num){
  //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);
	break; 
  case 1: //ЗА КРАСОТУ!
		lcd.setCursor(7, 0);
		lcd.print(F("НУ,"));
		lcd.setCursor(2, 1);
		lcd.print(F("ЗА КРАСОТУ!"));   
		mp3_play (3);  // Проигрываем "mp3/0003.mp3"
		delay(100);
	break; 		
	case 2: //"ЗА ДРУЖБУ!"
		lcd.setCursor(7, 0);
		lcd.print(F("НУ,"));//
		lcd.setCursor(3, 1);
		lcd.print(F("ЗА ДРУЖБУ!"));  
		mp3_play (4);  // Проигрываем "mp3/0004.mp3"
		delay(100);
	break;
	case 3: //"ЗА БРАТСТВО!
		lcd.setCursor(7, 0);
		lcd.print(F("НУ,"));
		lcd.setCursor(2, 1);
		lcd.print(F("ЗА БРАТСТВО!"));   
		mp3_play (5);  // Проигрываем "mp3/0005.mp3"
		delay(100);
	break;	
	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);
	break;	
  case 5: //ЗА РЫБАЛКУ!
		lcd.setCursor(7, 0);
		lcd.print(F("НУ,"));
		lcd.setCursor(3, 1);
		lcd.print(F("ЗА РЫБАЛКУ!"));
		mp3_play (7);  // Проигрываем "mp3/0007.mp3"
		delay(100);
	break;	
	case 6: //ЗА ИСКУССТВО!
		lcd.setCursor(7, 0);
		lcd.print(F("НУ,"));
		lcd.setCursor(2, 1);
		lcd.print(F("ЗА ИСКУССТВО!"));
		mp3_play (8);  // Проигрываем "mp3/0008.mp3"
		delay(100);
	break;	
	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; 	
		
  }

  delay(2000);

}


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 (30);// устанвливаем громкость 30
  delay (100);
  mp3_play (1); // Проигрываем "mp3/0001.mp3"(0001_get started!.mp3)
  delay (100);
  lcd.init();// Инициализация дисплея
  lcd.backlight();
  lcd.setCursor(7, 0);
	lcd.print(F("НУ,"));
	lcd.setCursor(1, 1);
	lcd.print(F("НАА-ЧАА-ЛИИИИ!"));
	delay (3500);
  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;

  }
}

Как в него впиндюрить сон? Или если из коммерческих побуждений не хотите огласки, то пишите на почту 2155052@inbox.ru 

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

Добавил мушкетёров в наливатор, один за всех и все за одного, думаю  понятно, ну захотелось так назвать))). Пока пробный вариант нужно тестировать и выявлять косяки. В папку mp3 добавил трек, для этого добра.

Архив с барахлом, тыц ))).

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

Супер, вообще огонь! А видео есть с новыми фишками?

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

Залил в свой обновлённую прошивку. Всё работает. Может всё-таки можно вставить туда регулировку чувствительности датчиков, вот очень нужно, ТТР ни одна не заработала, как надо, а с гиперчувствительностью оптических - прям беда...

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

Acket пишет:

Может всё-таки можно вставить туда регулировку чувствительности датчиков, вот очень нужно, ТТР ни одна не заработала, как надо, а с гиперчувствительностью оптических - прям беда...

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

Перезалил архив со скетчем, поправил незначительные косяки, добавлены звуки установки рюмок на места, в папку mp3 файлы добавил.

Ссылка

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

Понятно, буду ждать ещё датчики, по ссылкам парней... может выпадет лотерея... 

А какие косячки были? я вроде быстренько всё посмотрел и не заметил...

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

Косяки были связанные с допкнопкой и светиками в башне, если опционально включено в скетче
 

GorePayalo
Offline
Зарегистрирован: 25.11.2019

raven78 пишет:

Encoder пишет:

 А Можно еще модельку носика?

Вот два вида.  Первый вариант под стандартную качельку серво, но вроде подправить надо по аналогии со второй, но и так всё нормально, только сложно собирать будет. Вторая под другую качельку серво более массивную, у меня пришла такая новая, вот и делал второй вариант. В  трубку нужно будет просунуть шланг идущий от помпы, шланг примерно 6 мм снаружи или тоньше, как пойдёт.


Если Вас не затруднит, возможно ли поделиться исходниками трубок в stl формате?