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

RW3
RW3 аватар
Offline
Зарегистрирован: 07.08.2019

Схему можно поправить. Пока нет всей комплектации до конца все нюансы не предусмотрел. Схему рисовал по скетчу из верхних постов

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

Все правильно нарисовал! Плюс в карму. Плеер потребляет больше ампера!

RW3
RW3 аватар
Offline
Зарегистрирован: 07.08.2019

Forthomo пишет:

Все правильно нарисовал! Плюс в карму. Плеер потребляет больше ампера!

Странно, чему там столько потреблять?! Даже не подозревал......

RW3
RW3 аватар
Offline
Зарегистрирован: 07.08.2019

А динамик все же подключается через землю.там два канала и скорее всего посадить его на оба сразу не получится. Возможно ещё и дополнительно придется усилитель ставить. Где-то читал что это выход на наушники

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Forthomo пишет:

Плеер потребляет больше ампера!

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

RW3 пишет:
А динамик все же подключается через землю.там два канала и скорее всего посадить его на оба сразу не получится. Возможно ещё и дополнительно придется усилитель ставить. Где-то читал что это выход на наушники

Там линейный выход отдельно -  DAC_R (4), DAC_L(5) & GND(7) -> на усилитель ( у меня такие остались: AIYIMA 5 шт. 3 Вт 8002 плата одноканального усилителя мини-аудио усилитель модуль питания для 3-5 в 4-8ом динамик DIY).

Штатный Моно до 3W на аналогичной микросхеме.

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

710 мА  в штатном режиме. См. даташит  https://yadi.sk/i/Lc3kluDO1kW5jQ

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Forthomo пишет:

Все правильно нарисовал! Плюс в карму. Плеер потребляет больше ампера!

вот я и думаю, мошт единицы измерения поменяли, мошт с утра 700 мА  стало больше ампера. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Просмотрел всю бумашку, на которую ты ссылку дал, нашол тока Standby current 20mA, 710мА нигде не нашол.  Тыкни носом. 

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

3W/4.2V=?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ясна, спасибо.

Ирокез
Offline
Зарегистрирован: 27.08.2019

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

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

Подробная схема

Подробная схема

RW3
RW3 аватар
Offline
Зарегистрирован: 07.08.2019

Класс!!! Я бы даже сказал через чур подробная . Теперь у всех дела попрут !

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

Если почта шустрее работать будет.

RW3
RW3 аватар
Offline
Зарегистрирован: 07.08.2019

Это да.... тоже ни как не дождусь посылку.китаец наверно пешком идет ;)

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

А можно схему в лучшем качестве? Спасибо.

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019
Viblis
Offline
Зарегистрирован: 04.11.2016

А в чем схему риовали ?

Viblis
Offline
Зарегистрирован: 04.11.2016

А в чем схему риcовали ?

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

Splan70.

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

Forthomo пишет:

Splan70.

ну так а чего же выкладываете JPG?

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

500kБ *.jpg - против 6,1 МБ *.spl7

Ирокез
Offline
Зарегистрирован: 27.08.2019

RW3 пишет:
Класс!!! Я бы даже сказал через чур подробная . Теперь у всех дела попрут !
А подробная через кого-то схема – это вообще как?

Viblis
Offline
Зарегистрирован: 04.11.2016

Спасибо, за одно и  Splan70 изучил, установил, закачал разные библиотеки

moder
Offline
Зарегистрирован: 30.08.2019

А полный скетч можно ? А то на прошлой странице пытался залить,но что-то не получается((

Lerik-Co
Offline
Зарегистрирован: 30.08.2019

Моя схема в сплане. Гляньте, плз, нигде не накосячил?

https://yadi.sk/d/djoBs3zv7IZkwg

Только выключатель питания надо будет еще воткнуть, и рюмок у меня будет 6, а не 5.

Ах, да, еще у меня АрдуиноНано, а не Мини.

RW3
RW3 аватар
Offline
Зарегистрирован: 07.08.2019

Надо с вашим скетчем сопоставить, тогда будет понятно

smart_pic
Offline
Зарегистрирован: 17.04.2016

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

Logik
Offline
Зарегистрирован: 05.08.2014

Народ, вот вы тут насосиками по трубочкам как бы крепкий алкоголь гоняете. А оно все пластиковое. Не всякий пластик для такого годен! Спирт из него вымывает химию. А это не всем употребляющим организмам на пользу. Учитывая что между наливами спиртное долго контактирует с трубами и насосом то все это не пренебрежимо. ИМХО для излива идеальна медь. Диаметром 6-8мм ищите у кондиционерщиков. Годно силикон, если не подделка.

Вобще к теме наливатора я не равнодушен, но боюсь  что из отладки тока скорая вытянет ))) Но если уж делать - по взрослому, чтоб видел стоящие рюмки и бутылку, брал бутыль и наливал.

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

Вот скетч с крайними изменениями от stpavel  сообщения 115 ,129 (низкий ему поклон). Изделие работает отмечал ДР 28.08, удивить не удалось, академики блин... . Калибровка насоса #139, калибровка датчиков #116. Схема #163,#168.

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

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[] = {50,50,100,100,50};
//Серво
const int PIN_SERVO = 9;
Servo servo;
//Позиция каждой рюмки 
const byte Rumka_pos[] = {0,50,98,145,179}; //12 - 48 - 90 - 135 - 174 (7,6-48,8-90,0-132,0-173,00 или 165/4=41)
const byte servo_speed=15; // Скорость поворота серво,  10 - норм, 20 медленно, 30 очень медленно
byte  Menu = 0;
byte MenuFlag = 0; // Здесь храниться уровень меню. 0 находимся в  Главном меню. 1 Вошли в меню Авто, 2 вошли в  Ручное управление
byte  Drink = 25; // По умолчанию в рюмку наливаем  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 = 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);
//-------



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("Y F K B D F N J H"), CENTER, 0);//Н А Л И В А Т О Р
  myOLED.print(F("F D N J"), CENTER, 15);//А В Т О
  myOLED.print(F("H E X Y J Q "), CENTER, 30);//Р У Ч Н О Й 
  myOLED.print(F("G H J V S D R F"), CENTER, 45);//П Р О М Ы В К А
  myOLED.setFont(SmallFont);
  myOLED.print(F(">"), LEFT, (Menu * 15) + 15);
  myOLED.print(F("<"), RIGHT, (Menu * 15) + 15);
  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.setFont(RusFont);
  myOLED.print(F("DSGMTV"), CENTER, 20); //Выпьем
  // Рандом - 1
  switch (random(11)) {
    case 0:
      myOLED.print(F("PF LHEPTQ!"), CENTER, 40); //За друзей
      break;
    case 1:
      myOLED.print(F("PF VBKS{ LFV!"), CENTER, 40); //За милых дам
      break;
    case 2:
      myOLED.print(F("PF PLJHJDMT!"), CENTER, 40); //За здоровье
      break;
    case 3:
      myOLED.print(F("PF ELFXE!"), CENTER, 40); //За удачу
      break;
    case 4:
      myOLED.print(F("PF VBH DJ DCTV VBHT!"), CENTER, 40); //За мир во всем мире
      break;
    case 5:
      myOLED.print(F("PF NT{ RNJ D VJHT!"), CENTER, 40); //За тех кто в море
      break;
    case 6:
      myOLED.print(F("PF K><JDM !"), CENTER, 40); //За любовь !
      break;
    case 7:
      myOLED.print(F("PF RHFCJNE !"), CENTER, 40); //За красоту !
      break;
    case 8:
      myOLED.print(F("PF DTPTYBT !"), CENTER, 40); //За везение !
      break;
    case 9:
      myOLED.print(F("PF HJLBYE !"), CENTER, 40); //За родину !
      break;
    case 10:
      myOLED.print(F("PF YFC C DFVB"), CENTER, 38); //За нас с вами
      myOLED.print(F("B {HTY C YBVB !"), CENTER, 55); //И хрен с ними
      break;

  }
  myOLED.update();

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

}

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

  myOLED.clrScr();
  myOLED.setFont(RusFont);
  myOLED.print(F("F D N J"), CENTER, 0);
  myOLED.print(F("VK   "), RIGHT, 27);
  DrinkInfo(57);
  //  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.setFont(RusFont);
  myOLED.print(F("H E X Y J Q"), CENTER, 0); //Р У Ч Н О Й 
  DrinkInfo(57);
  // 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.setFont(RusFont);
  myOLED.print((MenuFlag == 1) ? F("F D N J") : F("H E X Y J Q") , CENTER, 0); // А В Т О    Р У Ч Н О Й 

  myOLED.print(F("Y F K B D F > "), CENTER, 27); //Н А Л И В А Ю
  DrinkInfo(47);
  myOLED.update();
}

void oled_nalito(int MenuFlag, int Nalito) {
  myOLED.clrScr();
  myOLED.setFont(RusFont);
  myOLED.print((MenuFlag == 1) ? F("F D N J") : F("H E X Y J Q") , CENTER, 0);
  myOLED.print(F("Y F K B N J"), CENTER, 20); //Н А Л И Т О
  if (Nalito == 1) {
    myOLED.print(F("H > V R F"), CENTER, 55); //РЮМКА
  } else if (Nalito <= 4 ) {
    myOLED.print(F("H > V R B"), CENTER, 55); //РЮМКИ
  } else {
    myOLED.print(F("H > V J R"), 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 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);
  myOLED.begin(); // Инициализация дисплея
  // выводим привествие после включения перед наливом
  myOLED.clrScr();  
  myOLED.setFont(RusFont);
  myOLED.print(F("Ye? yfxfkb!"), CENTER, 50);// Ну, начали!
  myOLED.update(); 
  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(); // Включаем насос
          myOLED.clrScr();
          myOLED.setFont(RusFont);
          myOLED.print(F("G H J V S D R F"), 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 ) { //Начинается автоматический разлив
          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.setFont(RusFont);
            myOLED.print(F("YTN H>VJR !"), CENTER, 25); //НЕТ РЮМОК !
            myOLED.update();
            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("Начало ручного разлива " + String(DrinkCount));
          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;

  }
}

Звук не пробовал, не на чем пока.

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

Logik пишет:

Народ, вот вы тут насосиками по трубочкам как бы крепкий алкоголь гоняете. А оно все пластиковое. Не всякий пластик для такого годен! Спирт из него вымывает химию. А это не всем употребляющим организмам на пользу. Учитывая что между наливами спиртное долго контактирует с трубами и насосом то все это не пренебрежимо. ИМХО для излива идеальна медь. Диаметром 6-8мм ищите у кондиционерщиков. Годно силикон, если не подделка.

Вобще к теме наливатора я не равнодушен, но боюсь  что из отладки тока скорая вытянет ))) Но если уж делать - по взрослому, чтоб видел стоящие рюмки и бутылку, брал бутыль и наливал.

"Рояль" в 90х в пластике шел, многие ишо живы.

Logik
Offline
Зарегистрирован: 05.08.2014

пластик разный бывает. есть годный до 50-60 оборотов. есть годный для 96. Но есть и вообще не годный.

Думаю полезно будет http://forum.homedistiller.ru/index.php?board=139.0 http://forum.homedistiller.ru/index.php?board=139.0 

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

Lerik-Co пишет:

Моя схема в сплане. Гляньте, плз, нигде не накосячил?

https://yadi.sk/d/djoBs3zv7IZkwg

Только выключатель питания надо будет еще воткнуть, и рюмок у меня будет 6, а не 5.

Ах, да, еще у меня АрдуиноНано, а не Мини.

Диод на помпе кондером 0,1 мкф зашунтируй, при работе фонит.А так все верно, какие углы на серве? И еще за столом нечетное количество должно находиться, это суеверие, но как то неуютно....

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

Logik пишет:

пластик разный бывает. есть годный до 50-60 оборотов. есть годный для 96. Но есть и вообще не годный.

Думаю полезно будет http://forum.homedistiller.ru/index.php?board=139.0 http://forum.homedistiller.ru/index.php?board=139.0 

Тоже верно, в следующем изделии планирую бак из луженой жести 750 мЛ спаять с лейкой/воронкой, внешняя трубка несколько не эстетично смотриться.

Logik
Offline
Зарегистрирован: 05.08.2014

Так внешнюю трубку можна любой, если внутрь её просунуть медную или силиконовую ;) Там почитайте, просто сокровищница по поиску и нецелевому применению разных медных и нержавеющих вещей.

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

Коллеги, нужна помощь в корректировке скетча под дисплей LCD1602 I2C. Ни в какую не хотят переменные отображаться на дисплее, в мониторе все прописывается. Выкладываю как есть, с наладкой. Все работает, для наладки менюшек требуется ардуинка , дисплей , энкодер и светодиод последовательно с сопротивлением 1 ком на 12 нодку (помпа).


#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 = 25; // По умолчанию в рюмку наливаем  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) {
  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("мЛ?")); 
	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) {
//  lcd.setCursor(0, 0);
    Serial.println(F("INFO_DRINK"));
  lcd.clear();
    lcd.print(F("HАЛИТЬ ПО"));
    lcd.setCursor(10, 0);
    lcd.print(Drink);
  Serial.println(Drink);
    lcd.setCursor(14, 0);
    lcd.print(F("мЛ?"));
    DrinkInfo(57);

}

// Меню Ручной режим
void oled_manual(int DrinkCount, int Drink) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(F("HАЛИТЬ ПО"));
    lcd.setCursor(11, 0);
    lcd.print(Drink);
    lcd.setCursor(14, 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("ОК     "));
  }
  
  
//  Serial.println(Drink);
//    lcd.setCursor(14, 0);
//    lcd.print(F("мЛ"));
//    DrinkInfo(57);
}
// Меню налива
void oled_naliv(int MenuFlag) {
    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);
    lcd.setCursor(7, 1);
    lcd.print(F("РЮМ"));
    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_nalito(int MenuFlag, int Nalito) {
    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); // Выводим на экран наливаем ...
          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 {
            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); // Выводим на экран наливаем ...
          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;

  }
}

Скетч использует 18592 байт (60%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 657 байт (32%) динамической памяти, оставляя 1391 байт для локальных переменных. Максимум: 2048 байт.

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

Forthomo пишет:

Коллеги, нужна помощь в корректировке скетча под дисплей LCD1602 I2C. Ни в какую не хотят переменные отображаться на дисплее, в мониторе все прописывается.

Не понял  про какие переменные идет речь 

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

Logik пишет:

Народ, вот вы тут насосиками по трубочкам как бы крепкий алкоголь гоняете. А оно все пластиковое. Не всякий пластик для такого годен! Спирт из него вымывает химию. А это не всем употребляющим организмам на пользу. Учитывая что между наливами спиртное долго контактирует с трубами и насосом то все это не пренебрежимо. ИМХО для излива идеальна медь. Диаметром 6-8мм ищите у кондиционерщиков. Годно силикон, если не подделка.

Перистальтический насос решает все проблемы. 

 

koka7777745
Offline
Зарегистрирован: 29.05.2017

Вот самодельный насос из шаговым движком. https://www.thingiverse.com/thing:3616090  https://www.thingiverse.com/thing:3445927  https://www.thingiverse.com/thing:1669172

Такой движок выйдет подключить? 

А где можно скачать нарезку мп3 файлов?

RW3
RW3 аватар
Offline
Зарегистрирован: 07.08.2019

koka7777745 пишет:

Вот самодельный насос из шаговым движком. https://www.thingiverse.com/thing:3616090  https://www.thingiverse.com/thing:3445927  https://www.thingiverse.com/thing:1669172

Такой движок выйдет подключить? 

А где можно скачать нарезку мп3 файлов?

Пишите почту,скину нарезку мр3

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

Пишите почту,скину нарезку мр3

И мне пожалуйста, aleks_raichel@mail.ru

Viblis
Offline
Зарегистрирован: 04.11.2016

Там перистальтические насосы по ссылкам рассчитаны на  движок 28BYJ-48 и трубку 3мм. Как бы производительность просчитать ? Что то мне кажется слишком медленно все это будет наливать.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Посмотрев тему сделал однозначный вывод : "Bсе у кого на аватарках кошки - потенциальные алкаши !"

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а чуваки с дуршлагами на глазах тогда хто?  :) 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

brokly пишет:

Посмотрев тему сделал однозначный вывод : "Bсе у кого на аватарках кошки - потенциальные алкаши !"

Не понял наезда?! А у меня пЫнгвин и чо, я теперь не алкаш, штоле?!!

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Видимо, ты так, балующийся время от времени. А котики постоянна синие вхлам. 

RW3
RW3 аватар
Offline
Зарегистрирован: 07.08.2019
Viblis
Offline
Зарегистрирован: 04.11.2016

Еще один перистальтический насос: https://3dtoday.ru/blogs/skyone/peristaltically-pump/

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

DetSimen пишет:

а чуваки с дуршлагами на глазах тогда хто?  :) 

Все остальные латентные алкаши, видимо.....