Наливатор своими руками пошаговая инструкция форум

  • #1

Здравствуйте!
Решил опубликовать свой вариант аппарата который активно используется в жизни.
Эту часть текста я уже публиковал, но придётся повторится.
По-порядку.
Наливатор.

Немного о моём наливаторе.

В феврале 2022 года решил построить свой вариант аппарата.
Очень понравился РВСН-8 и Железный капут. Золотые руки мастера. Но т.к. живу в отдалении от всяких-разных фабрик-заводов, на которых можно было-бы реализовать многие узлы и детали пришлось думать, как изготовить «железяки» и самое главное, как написать программу.
Я немного программировал в AVR-Basic. Подойдя к решению проблемы программирования я понял, что шансов мало. Отсутствовали библиотеки которые мне нужны были, а писать алгоритмы из даташитов не хватает умения и терпения. Я, то и «читатель» плохинький, не говоря о «писателе».

Решил так, к двадцать третьему февраля 2023 года я должен изготовить наливатор и написать программу в Arduino IDE (изучив, на сколько можно язык программирования).
В крайнем случае, к Дню красной армии и ВМФ, сделаю механическую часть и сделаю примитивное управление, кнопку нажал – повернул каретку, кнопку нажал – налил.

Упёрся. Начал изучать Си и делать эксперименты с железом. Делал узел, писал алгоритм, проверял, и т.д.

И вот, 23 февраля 2023 года аппарат был торжественно продемонстрирован моим коллегам.
Корпус изготовил из фанеры и обклеил шпоном красного дерева и какого-то там дуба.
Наливатор позволяет налить от одной до шести рюмок одним выбранным объёмом от 15 до 50 мл.
Рюмки можно ставить как угодно, подряд, через одну, или вообще не ставить. В пустые места напиток не нальётся. Прокутит все шесть позиций и перейдёт в готовность снова налить.
Говорит тосты. Проигрывает музыку как из основного DF плеера, так и из второго MP3 плеера.
Показывать температуру напитка. И предупреждать, что напиток сильно согрелся. Так же от температуры зависит цвет подсветки под бутылкой, от синего до красного.
В «ручную» можно прокачивать напиток, как для заполнения трубочек, так и для их опорожнения.
Напиток качает перистальтический насос. Этот не пропускает напиток самотёком.

Аппарат состоит из:
Blue Pill (STM32F103C8T6) 128 КБ
Arduino Nano
HW134 (драйвер шагового мотора поворота каретки)
Шаговый мотор со старого дисковода типа NEMA.
DFPlayer (здесь тосты и несколько любимых песен)
BA6219(драйвер коллекторного мотора перистальтического насоса)
Перистальтический насос – это такой какими качают кровь.
ST7735 (дисплей)
LV53LOX (модуль лазерного дальномера)
DS18B20 (датчик температуры)
Оптрон с внешним каналом (снял со старой ККМ Samsung ER-250RF).
Ещё один «оптрон» изготовил из фотодиода и лазерного модуля от лазерной указки.
Модуль встраиваемого MP3, BT, FM, AUX плеера с ПДУ купленного на Aliexpress.
Модуль УНЧ 2х15 класса F(так написано) купленного там же.
74HC4053 (аналоговый коммутатор для озвучивания от DFPlayer или от встроенного)
WS2812 16 светодиодов для «умной» подсветки.
Кнопки, энкодер, готовый блок питания 12 Вольт 3 Ампера в корпусе с дырочками от китайцев.
Стабилизатор на 5 Вольт сделал сам.
Динамик, чтобы встроить во внутрь.
Два сдвоенных пружинных клеммных зажима для подключения внешней акустики.
Ещё, для реализации задуманного потребовался 3D-принтер. Но он уже был у меня.
Изначально, разрабатывая печатную плату, я в основном разместил модули и основные соединения. В процессе «допиливания» некоторые соединения менялись, некоторые создавались. ПП похожа на монтажку с проволочными соединениями.
Сейчас решил «закультурить» ПП и все соединения с нею.

Ещё предстоит довести до ума трубопровод.

Продолжение следует…

  • 53.4 KB
    Просмотры: 200

  • #2

Выкладываю несколько фотографий.

  • 111.4 KB
    Просмотры: 179

  • 50.8 KB
    Просмотры: 184

  • 135.8 KB
    Просмотры: 178

  • 112.3 KB
    Просмотры: 140

  • #3

Ещё три.

  • 111.7 KB
    Просмотры: 78

  • 130.9 KB
    Просмотры: 85

  • 117.8 KB
    Просмотры: 74

  • #4

И ещё.

  • 132.6 KB
    Просмотры: 62

  • 44.1 KB
    Просмотры: 74

  • 48.6 KB
    Просмотры: 70

  • #5

Это файл схемы .spl7
Пришлось упаковать.
Схема почти полная. Не показаны некоторые разъёмы. Также не показаны объединённые в плату узлы. (ОУ, коммутатор, подстроечные резисторы).

  • 34.1 KB
    Просмотры: 82

  • #6

Почему два процессора!?

Потому что не смог реализовать одновременное отслеживание за рюмками и управление ШД. (не хватило таланта в программировании. Изготавливал наливатор и изучал программирование одновременно).

Хочу отметить, что в упомянутом выше РВСН-8 и Железном капуте использовалось, по крайней мере, 11 реле. И программа одна и та же. По моим данным программу на тот момент написал школьник из СПб. В моём аппарате реле нет.

Arduino Nano отвечает за шаговый мотор, измерение температуры в бутылке, наличие-отсутствие рюмок с помощью лазерного дальномера.

STM32 отвечает за всё остальное. За энкодер, дисплей, кнопки, оптроны, DFPlayer(тосты и музыка) , коммутатор звуков, управление помпой, «пылающей» подсветкой WS2812. Так же выдаёт что нужно на Nano (управление ШД), и получает оттуда что можно(температуру, наличие рюмки).

На одной плате по размерам как УНЧ разместил 2 ОУ, коммутатор 74HC4053, подстроечные резисторы, преобразователь +5 в -5 Вольт для питания коммутатора.

Я установил ещё один плеер который воспроизводит независимо от DF плеера. Для удобства.

Изменено:

  • #7

Динамик DF Плеера установил в крышке в дне наливатора. На боковую стенку прикрутил два разъёма с пружинными зажимами для подключения проводов внешней акустики.

Ещё на боковую сторону прикрепил держатель ПДУ плеера. В этом держателе можно хранить штуцер для наливания при транспортировке.

  • #8

Работа наливатора, как обычно, начинается с включения тумблера.

Каретка поворачивается и так называемое исходное положение. Для этого в каретке имеется отверстие для «лазерного» оптрона. Каретка будет вращаться пока не лазер не засветит фотодиод.

Не знаю, может это лишнее, но мне нравится.

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

Энкодером, вращая в одну сторону, можно выбрать по кругу количество рюмок, от одной до шести. А при вращении в противоположную сторону – объём напитка в рюмке, от 15 до 50 мл с шагом 5 мл. Коротким нажатием энкодера подтверждаем свои намерения.

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

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

Если стоят не все «заявленные» рюмки, то аппарат прокрутит все шесть позиций, наливая в имеющиеся рюмки, и перейдёт в режим ожидания, простив отсутствующие рюмки.

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

После очередного наливания прозвучит следующий тост. Не понравился формат представления MP3 файлов этом плеере. Ну да куда деваться.

При включении аппарата сразу начинает «звучать» второй MP3 плеер. На время тоста или воспроизведения музыки из DF плеера коммутатор переключается на DF плеер. Этим занимается вывод BUSY DF плеера.

Постоянно происходит контроль за температурой напитка. Значение температуры отображается на дисплее, а также происходит визуализация в виде «полыхающего» огня от синего до красного цвета в подставке под бутылку реализованной на светодиодах WS2812 в виде трёх лучей.
При достижении температуры 23° С подсветка начинает полыхать пурпурным цветом и каждые три минуты звучит предупреждающий звук и на дисплее отображается предупреждение.

Изменено:

  • #9

Конструкция.

Корпус из фанеры. Каретка, шестерни, рычаги, держатель лазерного дальномера, штуцерный узел (громко сказано), лазерный оптрон исходной позиции, опоры, держатель насоса, передняя панель, держатель наливного штуцера и ПДУ, ножки, погружаемый в бутылку цилиндр со всасывающим штуцером и датчиком температуры, подставка под бутылку вместе со светодиодной подсветкой создал во FreeCAD и напечатал на 3D принтере.

  • #10

О насосе.

Изначально я купил такой насос с моторчиком, который применяется в термопотах. Но оказалось, что в случае, если бутылка стоит так, что уровень жидкости выше уровня наливного штуцера, происходит самотёк. Капелька в несколько секунд на каретку. Пришлось покупать перистальтический насос. В нём отсутствует самотёк. Но и цена была раз в пять-шесть больше.
В качестве трубопроводов использовал силиконовые трубочки от капельницы и латунные трубки от телескопических антенн. Латунь паял чистым оловом.


  • #11

Доброго времени суток. А скетчи будут ?

stpavel

Offline

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

Исправленная версия. 

Появилась переменная 

//Позиция каждой рюмки 
const byte Rumka_pos[] = {0,40,75,105,140};

Сюда забиваем свои значения угла серво для каждой рюмки. 

Краткое описание, три пункта меню, Авто, Ручной и Промывка . Управление одним энкодером. 

Вращаяем влево/вправо — перемещаемся по меню. Нажатие на энкодер вход в меню. Долгое нажатие энкодера — выход в главное меню. 

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

Меню авто — тут все понятно. наличие рюмок по оптическим датчикам. 

Меню ручной — Вращаем вправо энкодер — увеличиваем милилитры в рюмку по кругу, вращая в левую сторону меняем количество рюмок. 

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

OLED  myOLED(SDA, SCL, 8); //Подключение экрана А4, А5
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 int PIN_SERVO = 9;
Servo servo;
//Позиция каждой рюмки 
const byte Rumka_pos[] = {0,40,75,105,140};
//-------------------------
byte  Menu = 0;
byte MenuFlag = 0; // Здесь храниться уровень меню. 0 находимся в  Главном меню. 1 Вошли в меню Авто, 2 вошли в  Ручное управление
byte  Drink = 25; // По умолчанию в рюмку наливаем  20 мл.
const byte  max_Drink = 50; // Максимум в рюмку - 50 мл.
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, 2, 50, 300, 4000));
  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 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(10); // ждем 15 миллисекунд, пока ротор сервы выйдет в заданную позицию
  }
  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(10); // ждем 15 миллисекунд, пока ротор сервы выйдет в заданную позицию
  }
  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);
  //  servo.attach(PIN_SERVO);
  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;
  //   Volume=EEPROM.read(0);
  myOLED.begin();
  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 <= 2 ) ? 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 = 2 : Drink++;
          oled_auto(Drink);
        } else if (MenuFlag == 2) {
          (Drink >= max_Drink ) ? Drink = 2 : 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]) > 1000 ) {
              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 > 1000) {
          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;

  }
}

Привет всем. Наконец то доделан проект под названием «Наливатор. Сообразим на четверых». В данной статье будет рассказана примерная хронология разработки и изготовления устройства опираясь на те фото, что сохранились. Итак начнем.

Вначале было слово. Нет, это не мой случай. Вначале было видео.

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

Итак начнем. Первым делом было собран макет из 2-х досок и трубки, вырезанной из старой советской коляски. Использованы датчики наличия стакана, собранные на фото+свето диодах с длинной волны 940нм. Ардуино уно. Вспомогательных плат нет, все датчики подключены к макетке. Вспыхивание красного светодиода символизирует налив рюмки.
Фото не осталось, так что прикладываю видос:

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

Выбор объема налива осуществлялся на дисплее 20х4. Управление тактовыми кнопками. Кнопка вверх/вниз/пуск. Подключение дисплея-8 бит данных+управление. Опять ворох проводов и пинов стало не хватать у контроллера.

Далее дисплей заменен на 16х2 с управлением по шине i2c. Особенность данного способа подключения-всего 2 провода данных и 2 провода питания. Крайне удобно и практично.

Для удобства сборки всей электроники изготовлены 3 платы:
1)Плата сенсоров-устанавливается на верхней части и обрабатывает все сигналы управления и индикации.\
2)Плата контроллера-установлен МК+ минимально необходимая обвязка
3)Плата драйверов-Стабилизаторы питания, драйвера шаговых двигателей

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

Параллельно с поиском нового насоса начал рисовать проект в Компасе 3D.

Многократно переделывалась электроника. первое, что изменил — это на плате драйверов был установлен стабилизатор lm7805, но при токе 500ma и падении напряжения 12 в 5в он очень сильно грелся и пришлось заменить lm7805 на lm2576, хотя на радиатор все равно посадил всю конструкцию. Управление было изменено с такторых кнопок на энкодер-как то приличнее, что-ли, выглядеть стало)

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

Пока я развлекался с электроникой: доделывал прошивку, дорабатывал электронику, в общем отлаживал устройство, друзья напечатали корпус на 3d принтере.

Первый корпус

Сборка устройства. В таком виде оно увидело свет.

Крышка. Вся коммутация между платами и блоками устройства осуществляется шлейфами.

Естественно, испытания, испытания.

Заменил перистальтический насос на мембранную помпу. Заменил драйвер l298n на полевик IRF540N для управления мотором налива, так как необходимость шагового драйвера отпала, а лишние 150 рублей платить неинтересно. Очередной раз переделал электронику.

Первые испытания дали понять, что необходимо установка АКБ, так как розетка далеко не всегда рядом. Следом за установкой аккумуляторов выявилась необходимость в индикаторе заряда. Это здесь все легко и красиво, а по факту, вариантов проверено много, и еще больше идей продумано. Остановился на сборке 2х li-ion АКБ с балансиром 2S и повышайкой до 12в. Также с Алиэкспресс пришел индикатор заряда для 2S. Качество, кстати очень хорошее, мне понравилась сама идея индикации сегментами. Чтобы не разряжать аккумуляторы установлена кнопка включения индикации заряда. Тут логика простая — «я художник, я так вижу». Автономная работа от полностью заряженных АКБ составляет долее 15 часов при активном использовании.

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

 Всех приветствую. Очень меня затянула тема ARDUINO и 3D печати. Решил вот тоже разработать свою модель. Все метался с датчиками рюмок, остановился на герконах. Распечатал и собрал, каждый. С ИК датчиками сразу возникли проблемы, на улице уходили сразу в засвет, система пригодна только в домашних условиях. Пришли от китайцев микрики, сделал корпус под микрики, всё устраивает, но ! Но после недельной эксплуатации, каждый экземпляр вскрыл и обнаружил на шилде , что там не хило все окислилось ( хотя на работу это ни как не сказалось). Последствия пролива спиртного ( когда «принимающий уже на качерге). Зазоры в светодиодах, ик датчиках и микрухах, дали о себе знать. И тут осенило, надо поставить геркон, на рюмку сделать донышко 2мм с местом под магнит и закрыть стол, или стеклом или пленкой ПВХ ( прозрачной)

Вариант 1 ( ИК датчики) :

Авто бармен (Наливатор)

Авто бармен (Наливатор)

Может не те датчики брал, не знаю, но от этого варианта ушел.

Вариант 2 Микрухи:

Авто бармен (Наливатор)

Вертикальные перемычки на панели поддержки для чистовой печати, т.к. панель съемная, под разные виды дисплеев.

1602

Авто бармен (Наливатор)

1637

Авто бармен (Наливатор)

Авто бармен (Наливатор)

Ну и окончательный вариант, Герконы

Авто бармен (Наливатор)

На столе выбрано место под стекло или пленку, проливы в таком исполнении не страшны. Герконы отрабатывают на ура ! И к стати, отказался от датчиков с герконами ( от китайцев), поставил только сами герконы, проблем в работе не вижу совсем.

Ну и как продолжение, решил исполнить всё в мобильной версии, пока только в разработке

Авто бармен (Наливатор)

Ну и набор деталей, используемых в проектах ( меняются только датчики)

Авто бармен (Наливатор)

Версию в чумадане, хочу упаковать по полной….:)))))))))) .

Очень много почерпнул у Гайвера, Алекс ваще красава, куча благодарностей за его труды !

ЗЫ

До апреля. я вовсе не имел ( слышал вернее) понятия о , ARDUINO и  3D печать, и работу в редакторах объемного моделирования, с вилами кидался. Очень увлекло !

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Габагамма 100 мг инструкция по применению
  • Должностная инструкция начальника отдела финансового обеспечения
  • Оцифровка видеокассет своими руками на компьютере бесплатно пошаговая инструкция
  • Ваниш пятновыводитель для цветного жидкий инструкция по применению отзывы покупателей
  • Поездка в грузию на автомобиле самостоятельно пошаговая инструкция