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

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

Скетч с сообщения 889 откуда?

строк сверху не жватает

#include <OLED_I2C.h>
#include <Servo.h>
#include "Adafruit_NeoPixel.h"

 

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

У меня такие же датчики и так же работают коряво. Мне помог инвертор на выходе, хотя потом переделал так, как пнули тут http://arduino.ru/forum/proekty/nalivator-avtomatizirovannaya-mashina-ko... И пофиг что подключено к D, главное что работают. Поменяй знаки в скетче и будет тебе радость.

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

Wadzim пишет:
А если вообще не подключать их. Как должен реагировать скетч? У меня сервопривод все равно вращается

Поподробнее пожалуйста, какой скетч, что не подключать, тип сервы?

При включении серва дергается и тут же паркуется в положение где первая рюмка, т.е. в 0 градусов.

const byte Rumka_pos[] = {0, 50, 98, 145, 179};

 

alania_07
Offline
Зарегистрирован: 04.10.2019

Forthomo пишет:

Проверь датчики скетчем serial_print_tab на Ядиске есть.

не заливает выдает ошибку 

Sketch uses 2 718 bytes (8%) of program storage space. Maximum is 30 720 bytes.
Global variables use 260 bytes (12%) of dynamic memory, leaving 1 788 bytes for local variables. Maximum is 2 048 bytes.
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xe0
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xe0
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xe0
 
Wadzim
Offline
Зарегистрирован: 29.10.2019

#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;

  }
}

 

Wadzim
Offline
Зарегистрирован: 29.10.2019

Концевые выключатели не подключал.

Сервопривод SG90, дергается и паркуется

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

Wadzim пишет:

Концевые выключатели не подключал.

Сервопривод SG90, дергается и паркуется

Код мой. Реально рабочий.

А здесь почитай на робототехнике откуда взялось 300.

Можно также сделать подключение кнопок к аналоговому входу Ардуино. Принципиальное отличие данной схемы — это использование аналогового порта на микроконтроллере. Для включения и выключения светодиода будем также использовать встроенный светодиод на плате Ардуино, подключенный к 13 порту. Скачать готовый скетч можно с Google Диск по ссылке здесь.

void {
   pinMode(13, OUTPUT); // объявляем пин 13 как выход
   pinMode(A1, INPUT); // объявляем пин A1 как вход
}

void loop() {
   if (analogRead(A1) > 300) // когда аналоговая кнопка нажата
   {
      digitalWrite(13, HIGH); // зажигаем светодиод
   }

   if (analogRead(A1) < 300) // когда аналоговая кнопка отпущена
   {
      digitalWrite(13, LOW); // выключаем светодиод
   }
}

Пояснения к коду:

  1. в данном скетче мы используем функцию analogReadдля считывания значений с аналогового входа A1, при этом порт можно использовать, как цифровой;
  2. значения на аналоговом входе могут отличаться (все зависит от сопротивления резистора в схеме) и могут принимать значения в диапазоне от 0 до 1023.
Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

alania_07,  какая версия Ардуино ИДЕ, попробуй другую, выбери другой программатор, я же это уже писал.

Wadzim
Offline
Зарегистрирован: 29.10.2019

поставил 300 и если не подключен то пишет нет рюмок.
но например подключаю к  А2. нажимаю на концевик - пишет в 1 рюмку но наливает в 2
например подключаю к А3 - пишет в 1 рюмку, а наливает в 4

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

Я не смог это победить.

Wadzim
Offline
Зарегистрирован: 29.10.2019

А вот такая закономерность.
В ручном режиме выбираю например 3 рюмки. Наливает.
Перехожу в авто режим, рюмки не ставлю, и пишет - в 3 нет рюмок.
Если в ручном выбрать 5, то в авто напишет - в 5 нет рюмок.

Wadzim
Offline
Зарегистрирован: 29.10.2019

Forthomo пишет:

Я не смог это победить.

А если подключу все концевики, то такого не будет?

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

Остальные входа в воздухе висели, там на них непоймиче происходило. когда концевик с резистором подключен не входе гарантированно низкое напряжение близкое к нулю , АЦП будет выдавать 0,2, 5,10,12, когда контакт замыкаешь на входе появляется напряжение питания 5В, АЦП выдаст 1024. а резистор нужен чтобы ток ограничить.

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

Wadzim пишет:
А вот такая закономерность. В ручном режиме выбираю например 3 рюмки. Наливает. Перехожу в авто режим, рюмки не ставлю, и пишет - в 3 нет рюмок. Если в ручном выбрать 5, то в авто напишет - в 5 нет рюмок.

понаблюдаю вечером, как раз "Тундра северная морошка" в магазине появилась :)

alania_07
Offline
Зарегистрирован: 04.10.2019

Помимо этих долбаных датчиков(в крайнем случае концевеки поставлю) у меня тост не проигрывается. После разлива как будто хочет начать и отрубает

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

В скетче что ты показал НЕТ МП3 плеера.

alania_07
Offline
Зарегистрирован: 04.10.2019

на другом пробывал.

Сейчас твой заливать буду (набор схем скетчей и т.п  от  Forthomo)

AlexMik
Offline
Зарегистрирован: 15.09.2019

Дядьки, уже практически дописал свой скетч.

И в процессе отладки задолбало дерганье SERVO при старте.

Это неизбежно?

ЗЫ: Прошу прощения если обсуждалось. ))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

alania_07 пишет:

Помимо этих долбаных датчиков(в крайнем случае концевеки поставлю) у меня тост не проигрывается. После разлива как будто хочет начать и отрубает

не мудрено - харам )))

yct9
Offline
Зарегистрирован: 27.11.2015

AlexMik пишет:

Дядьки, уже практически дописал свой скетч.

И в процессе отладки задолбало дерганье SERVO при старте.

Это неизбежно?

ЗЫ: Прошу прощения если обсуждалось. ))

Я писал как это исправить, почитайте пожалуйста 778-779 сообщение

alania_07
Offline
Зарегистрирован: 04.10.2019

ua6em пишет:

alania_07 пишет:

Помимо этих долбаных датчиков(в крайнем случае концевеки поставлю) у меня тост не проигрывается. После разлива как будто хочет начать и отрубает

не мудрено - харам )))

Я не для себя собираю))))

yct9
Offline
Зарегистрирован: 27.11.2015

alania_07 пишет:

ua6em пишет:

alania_07 пишет:

Помимо этих долбаных датчиков(в крайнем случае концевеки поставлю) у меня тост не проигрывается. После разлива как будто хочет начать и отрубает

не мудрено - харам )))

Я не для себя собираю))))

как Вы собираете для других, если сами не знаете?)

alania_07
Offline
Зарегистрирован: 04.10.2019

yct9 пишет:

alania_07 пишет:

ua6em пишет:

alania_07 пишет:

Помимо этих долбаных датчиков(в крайнем случае концевеки поставлю) у меня тост не проигрывается. После разлива как будто хочет начать и отрубает

не мудрено - харам )))

Я не для себя собираю))))

как Вы собираете для других, если сами не знаете?)

Собираю как и все-руками

alania_07
Offline
Зарегистрирован: 04.10.2019

Залил твои библиотеки, твой скетч.Тосты стал озвучивать а вот датчики прийдется кидать все таки через инвертор 

alania_07
Offline
Зарегистрирован: 04.10.2019

И кстати может кому поможет когда нибудь. У меня заливал на 5-20 раз скетч. Дело было в мп3 плеере. С подключенными rx tx. Отключаю их и заливает все с первого раза.

Wadzim
Offline
Зарегистрирован: 29.10.2019

Я читал такое, только не про mp3 а про esp модули

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

alania_07 пишет:

а вот датчики прийдется кидать все таки через инвертор 

Да это просто жесть.  А ведь достаточно просто посмотреть что говорит Serial.println(val) после analogRead

 

 

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

Всем недоинженерам, не умеющим читать, торопыгам  и просто ленивым: только что промониторил срабатывание микриков, скетчем для настройки датчиков. Результат выкладываю ,следующий глупый вопрос приведет к удалению ВСЕЙ! моей папки с Я-диска. Файлы будут выдаваться через личку после сдачи зачета по прочтению всей темы постранично. Экак меня "Тундра" торкнула и просветила :).

Hello, Arduino Master
// нет рюмок
Port #	Value
A0		0
A1		0
A2		0
A3		0
A6		0
--------
//1я на месте
Port #	Value
A0		1023
A1		0
A2		0
A3		0
A6		0
--------
//2я на месте
Port #	Value
A0		0
A1		1023
A2		0
A3		0
A6		0
--------
//3я на месте
Port #	Value
A0		0
A1		0
A2		1023
A3		0
A6		0
--------
//4я на месте
Port #	Value
A0		0
A1		0
A2		0
A3		1023
A6		0
--------
//5я на месте
Port #	Value
A0		0
A1		0
A2		0
A3		0
A6		1023
--------
//все рюмки на местах
Port #		Value
A0		1023
A1		1023
A2		1023
A3		1023
A6		1023
--------
// нет рюмок
Port #		Value
A0		0
A1		0
A2		0
A3		0
A6		0
--------

ПС. Коллега kvirin1 рекомендую "Тундра.Северная морошка"

AlexMik
Offline
Зарегистрирован: 15.09.2019

Forthomo пишет:

 Экак меня "Тундра" торкнула и просветила :).

Сколько тостов успел прослушать? ))

Пока "ТУНДРА" торкнула и просветила.

Для статистики. ))

AlexMik
Offline
Зарегистрирован: 15.09.2019

Forthomo пишет:

 Экак меня "Тундра" торкнула и просветила :).

Сколько тостов успел прослушать? ))

Пока "ТУНДРА" торкнула и просветила.

Для статистики. ))

yct9
Offline
Зарегистрирован: 27.11.2015

Forthomo пишет:

Всем недоинженерам, не умеющим читать, торопыгам  и просто ленивым: только что промониторил срабатывание микриков, скетчем для настройки датчиков. Результат выкладываю ,следующий глупый вопрос приведет к удалению ВСЕЙ! моей папки с Я-диска. Файлы будут выдаваться через личку после сдачи зачета по прочтению всей темы постранично. Экак меня "Тундра" торкнула и просветила :).

Hello, Arduino Master
// нет рюмок
Port #	Value
A0		0
A1		0
A2		0
A3		0
A6		0
--------
//1я на месте
Port #	Value
A0		1023
A1		0
A2		0
A3		0
A6		0
--------
//2я на месте
Port #	Value
A0		0
A1		1023
A2		0
A3		0
A6		0
--------
//3я на месте
Port #	Value
A0		0
A1		0
A2		1023
A3		0
A6		0
--------
//4я на месте
Port #	Value
A0		0
A1		0
A2		0
A3		1023
A6		0
--------
//5я на месте
Port #	Value
A0		0
A1		0
A2		0
A3		0
A6		1023
--------
//все рюмки на местах
Port #		Value
A0		1023
A1		1023
A2		1023
A3		1023
A6		1023
--------
// нет рюмок
Port #		Value
A0		0
A1		0
A2		0
A3		0
A6		0
--------

ПС. Коллега kvirin1 рекомендую "Тундра.Северная морошка"

на вашем месте , я бы уже закрыл Ядиск

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

На сколько заряда лития хватило, коллега...

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

Я потом еще скетч загрузил,  схему собрал и все запротоколировал.

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

yct9 пишет:

на вашем месте , я бы уже закрыл Ядиск

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

Nikolaj666
Nikolaj666 аватар
Offline
Зарегистрирован: 19.01.2017

а кстати. какой реальный вес выдерживает серва ? та которая MG90S .

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

Где то в инете читал сравнение SG90, MG90S (200гр вроде поднимала) и кажись 996 даже с видео, поищи хорошая статья...

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

Forthomo пишет:

 Пусть балуются...

Еще бы хоть немного  думали перед тем как вопросы задавать , и вообще было бы хорошо. )) 

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

stpavel пишет:

Forthomo пишет:

 Пусть балуются...

Еще бы хоть немного  думали перед тем как вопросы задавать , и вообще было бы хорошо. )) 

Пусть хотя бы все прочитают, все же написано и гугл у всех есть.

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

Nikolaj666 пишет:
а кстати. какой реальный вес выдерживает серва ? та которая MG90S .

https://youtu.be/yk9gb_0irfo

kvirin1
Offline
Зарегистрирован: 14.09.2019

Forthomo пишет:

Всем недоинженерам, не умеющим читать, торопыгам  и просто ленивым: только что промониторил срабатывание микриков, скетчем для настройки датчиков. Результат выкладываю ,следующий глупый вопрос приведет к удалению ВСЕЙ! моей папки с Я-диска. Файлы будут выдаваться через личку после сдачи зачета по прочтению всей темы постранично. Экак меня "Тундра" торкнула и просветила :).

Hello, Arduino Master
// нет рюмок
Port #	Value
A0		0
A1		0
A2		0
A3		0
A6		0
--------
//1я на месте
Port #	Value
A0		1023
A1		0
A2		0
A3		0
A6		0
--------
//2я на месте
Port #	Value
A0		0
A1		1023
A2		0
A3		0
A6		0
--------
//3я на месте
Port #	Value
A0		0
A1		0
A2		1023
A3		0
A6		0
--------
//4я на месте
Port #	Value
A0		0
A1		0
A2		0
A3		1023
A6		0
--------
//5я на месте
Port #	Value
A0		0
A1		0
A2		0
A3		0
A6		1023
--------
//все рюмки на местах
Port #		Value
A0		1023
A1		1023
A2		1023
A3		1023
A6		1023
--------
// нет рюмок
Port #		Value
A0		0
A1		0
A2		0
A3		0
A6		0
--------

ПС. Коллега kvirin1 рекомендую "Тундра.Северная морошка"


Коллега я Вас услышал, по поводу Яндекс папки. Это наверно единственное правильное решение, чтоб читали и вникали во всю тему. По поводу морошки учту

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

Привет всем. Нужен пинок в правильную сторону. Скетч с я.диска "nalivator_v4.2_oled_dfp"

#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[] = {12,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("YE!"), CENTER, 20); //НУ!
  // Рандом - 1
  switch (random(18)) {  // case 0...17
  case 0:
      myOLED.print(F("PF DCNHTXE!"), CENTER, 40); //ЗА ВСТРЕЧУ!
      mp3_play (2);  // Проигрываем "mp3/0002.mp3"
    delay(100);
    break;
  case 1:
      myOLED.print(F("PF RHFCJNE!"), CENTER, 40); //ЗА КРАСОТУ!
      mp3_play (3);  // Проигрываем "mp3/0003.mp3"
    delay(100);
    break;
  case 2:
      myOLED.print(F("PF LHE;,E!"), CENTER, 40); //ЗА ДРУЖБУ!
      mp3_play (4);  // Проигрываем "mp3/0004.mp3"
    delay(100);
    break;
  case 3:
      myOLED.print(F("DS <KBY"), CENTER, 38); //ВЫ БЛИН
      myOLED.print(F("LFTNT!"), CENTER, 55); //ДАЕТЕ!
      mp3_play (20);  // Проигрываем "mp3/0020.mp3"
    delay(100);
	break;
  case 4:
      myOLED.print(F("PF ,HFNCNDJ!"), CENTER, 40); //ЗА БРАТСТВО!
      mp3_play (5);  // Проигрываем "mp3/0005.mp3"
    delay(100);
    break;
  case 5:
      myOLED.print(F("PF"), CENTER, 38); //за
    myOLED.print(F("CGHFDTLKBDJCNM!"), CENTER, 55); //СПРАВЕДЛИВОСТЬ!
      mp3_play (6);  // Проигрываем "mp3/0006.mp3"
    delay(100);
    break;
  case 6:
      myOLED.print(F("PF HS,FKRE!"), CENTER, 40); //ЗА РЫБАЛКУ!
      mp3_play (7);  // Проигрываем "mp3/0007.mp3"
    delay(100);
    break;
  case 7:
      myOLED.print(F("PF BCRECCNDJ!"), CENTER, 40); //ЗА ИСКУССТВО!
      mp3_play (8);  // Проигрываем "mp3/0008.mp3"
    delay(100);
    break;
  case 8:
      myOLED.print(F("PF HFPEV!"), CENTER, 40); //ЗА РАЗУМ!
      mp3_play (9);  // Проигрываем "mp3/0009.mp3"
    delay(100);
    break; 
  case 9:
      myOLED.print(F("PF BCNBYYS["), CENTER, 38); //ЗА ИСТИННЫХ
      myOLED.print(F(":TYOBY!"), CENTER, 55); //ЖЕНЩИН!
      mp3_play (10);  // Проигрываем "mp3/0010.mp3"
    delay(100);
    break;
  case 10:
      myOLED.print(F("PF GJYBVFYBT!"), CENTER, 40); //ЗА ПОНИМАНИЕ!
      mp3_play (11);  // Проигрываем "mp3/0011.mp3"
    delay(100);
    break;
  case 11:
      myOLED.print(F("PF TLBYTYBT!"), CENTER, 40); //ЗА ЕДИНЕНИЕ!
      mp3_play (13);  // Проигрываем "mp3/0013.mp3"
    delay(100);
    break;
  case 12:
      myOLED.print(F("PF GJ,TLE!"), CENTER, 40); //ЗА ПОБЕДУ!
      mp3_play (16);  // Проигрываем "mp3/0016.mp3"
    delay(100);
    break;
  case 13:
      myOLED.print(F("PF HJLBYE!"), CENTER, 40); //ЗА РОДИНУ!
      mp3_play (21);  // Проигрываем "mp3/0021.mp3"
    delay(100);
    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);
    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);
    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);
    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);
    break;      
  }
  delay(2000);
  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);// Ну, начали!
  delay (3500);
  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;

  }
}

при заливке в ардуино, моя нано постоянно мне моргает TX диодом. Примерно раза два в секунду. Мп3, соответственно, не работает. Скетч nalivator_v5.1_lcd_dfp так не чудит с морганием, но проверить не могу, так как нет дисплея LCD. ЧЯДНТ? 

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

Надеюсь схему не удолили))) если можно мне на почту! За ранее благодарен!!!! Pilot-111@ya.ru

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

den-a2rh пишет:
У меня есть, на электронку кину

Если не затруднит можно мне схему))) за ранее спасибо @ pilot-111@ya.ru

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

den-a2rh пишет:
У меня есть, на электронку кину

Если не затруднит можно мне схему))) за ранее спасибо @ pilot-111@ya.ru

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

Gridzilla пишет:

при заливке в ардуино, моя нано постоянно мне моргает TX диодом. Примерно раза два в секунду. Мп3, соответственно, не работает. Скетч nalivator_v5.1_lcd_dfp так не чудит с морганием, но проверить не могу, так как нет дисплея LCD. ЧЯДНТ? 

Нано в наличии нет поверить не могу, на ПРО МИНИ все работает. Когда заливаете скетч  отключайте от Ардуины ленту, сервм и МП3 ПЛЕЕР ОБЯЗАТЕЛЬНО!!!!

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

Forthomo пишет:

Gridzilla пишет:

при заливке в ардуино, моя нано постоянно мне моргает TX диодом. Примерно раза два в секунду. Мп3, соответственно, не работает. Скетч nalivator_v5.1_lcd_dfp так не чудит с морганием, но проверить не могу, так как нет дисплея LCD. ЧЯДНТ? 

Нано в наличии нет поверить не могу, на ПРО МИНИ все работает. Когда заливаете скетч  отключайте от Ардуины ленту, сервм и МП3 ПЛЕЕР ОБЯЗАТЕЛЬНО!!!!

У меня нано, ничего не отключаю, вроде заливается все нормально.... Уже раз цать перезаливал скетч, вроде все хорошо.. На моргание диодов внимания не обращал (OLED дисплей, до ЛСД пока руки еще не дошли).

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

Местный глюк ардуинки. У братца взял про мини, с ней все нормально. С другой нано тоже работает. Просто не было в наличии других. Странно, но остальные скетчи работают с ней. Только этот на этой ардуине нано... Мистика.. Без 0.5 не разобраться...

П С. При прошивке все отключал.

Nikolaj666
Nikolaj666 аватар
Offline
Зарегистрирован: 19.01.2017

собрал железо на макетке. схема "ГЛАВНАЯ СХЕМА 1.1" с концевиками  , скетч  nalivator_v5.1_lcd_dfp  с изменённой строчкой 

// Значения порога срабатывания датчика для каждой рюмки
const unsigned int Optics_porog[] = {300,300,300,300,300};

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

 

yct9
Offline
Зарегистрирован: 27.11.2015

Nikolaj666 пишет:

собрал железо на макетке. схема "ГЛАВНАЯ СХЕМА 1.1" с концевиками  , скетч  nalivator_v5.1_lcd_dfp  с изменённой строчкой 

// Значения порога срабатывания датчика для каждой рюмки
const unsigned int Optics_porog[] = {300,300,300,300,300};

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

 

Для оптических датчиков, в темноте, при солнце они плохо работают. Если у вас концевики, я не вижу смысле в ручном режиме 

Nikolaj666
Nikolaj666 аватар
Offline
Зарегистрирован: 19.01.2017

нужна защита от дрожащих рук после подключения второго аккумулятора :)