У меня много друзей. Молодые парни, мужчины средних лет и конечно дамы всех возрастов. Наверное всех. Трудно определить возраст современной женщины. Да и не очень хочется.
Так вот. Детей моих друзей и знакомых в силу своих возможностей я увлекаю электроникой. Строим маленьких роботов, жучков светлячков всяких и даже световые мечи. У детей почти всегда всё получается и они, конечно, бегут хвастаться ожившей электроникой родителям. И так раз за разом. Но однажды одна из моих знакомых, глядя на очередной всплеск гордости у своей дочери, говорит – я тоже хочу вникнуть в эту электронику, и программирование, и может даже что-то спаять. Не вопрос. Давай покажу, как собрать робота на колесной платформе. Будет ездить по полоске на полу. Или игру сделаем, питона например, или просто поморгаем светодиодами, или … Перебрали множество примеров. Получается если для начинающих, то всё какое-то детское, а если не детское, то совсем уже не для начинающих. Что-то не так! Нужны уроки для НАЧИНАЮЩИХ, ВЗРОСЛЫХ электронщиков. Пусть это будет – цифровой бармен или машина для смешивания коктейлей.

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



А это схема в стиле Arduino проектов.



Теперь конструкция и логика работы. По схеме и фото.

В четыре бутылки опущены принимающие трубки четырех микронасосов. Эти микронасосы подключены к четырем ключам собранных на полевых транзисторах MOSFET. Ключи в свою очередь подключены к выводам 3,5,6,9 любой Ардуины (дальше если написано к выводу **, это значит вывод Ардуины). Это исполнительная часть. Логика работы исполнительной части задается пятью потенциометрами. По порядку: самым левым потенциометром, подключенным к выводу A4, выставляем объем бокала, в котором будем готовить коктейль. Над ним вы видите шкалу из 16-ти RGB светодиодов с так называемой пиксельной адресацией WS2812b. Когда мы крутим первый потенциометр на шкале последовательно зажигаются светодиоды, условно показывающие объем бокала. Эта шкала подключена к выводу 11.

Следующими четырьмя ползунковыми потенциометрами (подключенными к выводам A0, A1, A2, A3) устанавливаем ту пропорцию от общего объема напитка, который нам нужно налить из конкретной бутылки. Над ползунками маленькие шкалы из 8 светодиодов каждая (подключены последовательно к длинной). Двигая потенциометрами, выбираем пропорцию и маленькие шкалы, снизу вверх, закрашиваются каждая своим цветом. Одновременно левая длинная шкала, вернее её первоначально зажженная часть раскрашивается в эти же цвета пропорционально маленьким.

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

В скетче можно настроить:

1. Активные цвета всех шкал, их фоновую подсветку.
2. Скорость работы помп, путем широтно-импульсной модуляции. Поэтому насосы включают не реле, а транзисторные ключи. Это нужно если вы, например, будете использовать автомобильную помпу омывателя стекла. Она очень производительная.
3. Максимальный физический объем бокала. По умолчанию 750 мл.
4. Время подсоса жидкости до включения отсчета и индикации. Это для того чтобы заполнить опустевшую трубку во время паузы.
5. Паузу перед подачей из следующей бутылки.
6. Размер шкал в светодиодах. По умолчанию установлено 16 светодиодов в большой шкале и по восемь светодиодов в маленьких. Можно изменить, как хотите. Будет красиво.
Как-то так.

Это ролик с демонстрацией.



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

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

Хороших выходных!

А в заключении также как и в ролике, я порошу сделать замечания и предложения. Я учту это в продолжении и в реально действующем проекте.

Код (скетч) можно скачать здесь. Или посмотреть:

Понадобится Adafruit_NeoPixel.h — библиотека для светодиодов и PinChangeInt.h — библиотека для прерываний.

#include <Adafruit_NeoPixel.h>
#include <PinChangeInt.h>
#define   START_PIN            7
#define   LEDS_PIN             11
#define   VOLUME_1_PIN         A0
#define   VOLUME_2_PIN         A1
#define   VOLUME_3_PIN         A2
#define   VOLUME_4_PIN         A3
#define   TOTAL_VOLUME_PIN     A4
#define   ACT_1_PIN            3
#define   ACT_2_PIN            5
#define   ACT_3_PIN            6
#define   ACT_4_PIN            9
#define   DRINKS_NUM           4
#define   PIXEL_IN_STICK       8
#define   PIXEL_IN_DRINK       PIXEL_IN_STICK
#define   PIXEL_IN_VOLUME      (2 * PIXEL_IN_STICK)
#define   PIXEL_NUM            (DRINKS_NUM * PIXEL_IN_DRINK + PIXEL_IN_VOLUME)

#define   VOLUME_START_PIXEL        0
#define   DRINKS_START_PIXEL        (VOLUME_START_PIXEL + PIXEL_IN_VOLUME)
#define   DRINK_START_PIXEL(DRINK)  (DRINKS_START_PIXEL + DRINK * PIXEL_IN_DRINK)

#define   BACKGROUND_COLOUR      ((uint32_t) 0x000001)
#define   SHADOW_1_COLOUR        ((uint32_t) 0x000100)
#define   SHADOW_2_COLOUR        ((uint32_t) 0x000100)
#define   SHADOW_3_COLOUR        ((uint32_t) 0x000100)
#define   SHADOW_4_COLOUR        ((uint32_t) 0x000100)
#define   PROCESS_1_COLOUR       ((uint32_t) 0xFF0000)
#define   PROCESS_2_COLOUR       ((uint32_t) 0x0100ff)
#define   PROCESS_3_COLOUR       ((uint32_t) 0x111100)
#define   PROCESS_4_COLOUR       ((uint32_t) 0xFF00FF)
#define   VOLUME_PROCESS_COLOUR  ((uint32_t) 0x888888)



#define   DataThreshold        ((uint16_t) (1024/PIXEL_IN_DRINK))
#define   DataThresholdVol     ((uint16_t) (1024/PIXEL_IN_VOLUME))

#define   PROCESS              (1 << 0)

#define   mlToTimeCoef         10 //время на подачу 1 мл жидксти, мс
#define   MIN_VOLUME           1 //минимальный учитываемый объем, мл
#define   MAX_VOLUME           ((uint32_t) 750) //мл
#define   mlForLED             ((float)((float)MAX_VOLUME / (float)PIXEL_IN_VOLUME))

#define   PREPROCESS_DELAY     ((uint32_t) 2000) //мс
#define   PUMP_POWER           ((uint16_t) 255) //от 0 (выключен) до 255 (максимум)


#define   WaitShowDelay        ((uint16_t) 300) //2 * WaitShowDelay - период моргания ожидающей жидкости
#define   WaitCycle            3 //циклы ожидания время ожидания = WaitCycle * 2 * WaitShowDelay
#define   EndDelay            ((uint16_t) 2500) //пауза в конце

typedef struct
{
  uint8_t  VolPin;
  uint8_t  ActPin;
  uint16_t Volume; //показания АЦП
  uint32_t ProcColour;
  uint32_t ShadColour;
  float    mlVol; //мл в зависимости от общего объема и доли напитка
  uint8_t  LEDsNum;
  uint8_t  LEDsPos;
  
}  DrinkType;

Adafruit_NeoPixel LEDS = Adafruit_NeoPixel(PIXEL_NUM, LEDS_PIN, NEO_GRB + NEO_KHZ800);
uint8_t State = 0;
uint16_t TotalVolume = 0;
float TotalVolml = 0;
uint8_t TotVolActLEDs = 0;
bool ColourMix = false;
uint32_t NewColour = 0;
bool SystemChange = false;


DrinkType Drinks[DRINKS_NUM];

void setup()
{
  digitalWrite(START_PIN, HIGH);
  
  uint8_t VolPINs[DRINKS_NUM] = {VOLUME_1_PIN, VOLUME_2_PIN, VOLUME_3_PIN, VOLUME_4_PIN};
  uint8_t ActPINs[DRINKS_NUM] = {ACT_1_PIN, ACT_2_PIN, ACT_3_PIN, ACT_4_PIN};
  uint32_t ProcCOLOURs[DRINKS_NUM] = {PROCESS_1_COLOUR, PROCESS_2_COLOUR, PROCESS_3_COLOUR, PROCESS_4_COLOUR};
  uint32_t ShadCOLOURs[DRINKS_NUM] = {SHADOW_1_COLOUR, SHADOW_2_COLOUR, SHADOW_3_COLOUR, SHADOW_4_COLOUR};  
  
  for(uint8_t i = 0; i < DRINKS_NUM; i++)
  {
    Drinks[i].VolPin = VolPINs[i];
    Drinks[i].ActPin = ActPINs[i];
    pinMode(Drinks[i].ActPin, OUTPUT);
    digitalWrite(Drinks[i].ActPin, LOW);
    Drinks[i].Volume = 0;
    Drinks[i].ProcColour = ProcCOLOURs[i];
    Drinks[i].ShadColour = ShadCOLOURs[i];
    Drinks[i].LEDsPos = 0;
  }

  PCintPort::attachInterrupt(START_PIN, &START_ISR, FALLING);
  
  LEDS.begin();
  for(byte i=0; i < PIXEL_NUM; i++)
      LEDS.setPixelColor(i, BACKGROUND_COLOUR);
  LEDS.show();
}
//----------------------------------------
void loop()
{
  if ((State & PROCESS) != PROCESS)
  {
    uint16_t Data;
    
    for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
    {
      Data = analogRead(Drinks[cup].VolPin);
    
      if (abs(Data - Drinks[cup].Volume) >= DataThreshold)
      {
        Drinks[cup].Volume = Data;
       
        if (Drinks[cup].Volume > 975)
          Drinks[cup].Volume = 1024;

        uint8_t StartPixel = DRINK_START_PIXEL(cup);
        
        for(byte i = StartPixel; i < (StartPixel + PIXEL_IN_DRINK); i++)
          LEDS.setPixelColor(i, Drinks[cup].ShadColour);
        for(byte i = StartPixel; i < (StartPixel + (Drinks[cup].Volume / DataThreshold)); i++)
          LEDS.setPixelColor(i, Drinks[cup].ProcColour);
        
        SystemChange = true;
      }
    }

    Data = analogRead(TOTAL_VOLUME_PIN);
    
    if (abs(Data - TotalVolume) >= DataThresholdVol)
    {
      TotalVolume = Data;
       
      if (TotalVolume > 975)
        TotalVolume = 1024;

      TotVolActLEDs = TotalVolume / DataThresholdVol;

      for(byte i = VOLUME_START_PIXEL; i < (VOLUME_START_PIXEL + PIXEL_IN_VOLUME); i++)
        LEDS.setPixelColor(i, BACKGROUND_COLOUR);

      SystemChange = true;
    }

    if (SystemChange)
    {
      TotalVolml = (float)((TotalVolume * MAX_VOLUME) / 1024);

    uint16_t MinVol = 1025;
    for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
    {
      if ((Drinks[cup].Volume < MinVol) && (Drinks[cup].Volume != 0))
        MinVol = Drinks[cup].Volume;
    }
        
    float OnePartVol = 0;
    for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
    {
      Drinks[cup].mlVol = (float)Drinks[cup].Volume / (float)MinVol;
      OnePartVol += Drinks[cup].mlVol;
    }

    OnePartVol = TotalVolml / OnePartVol;
    for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
    {
      Drinks[cup].mlVol *= OnePartVol;
      Drinks[cup].LEDsNum = Drinks[cup].mlVol / mlForLED;
      if ((Drinks[cup].mlVol > 0) && (Drinks[cup].LEDsNum < 1))
        Drinks[cup].LEDsNum = 1;
    }

    uint8_t LEDsSum = 0;
    for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
      LEDsSum += Drinks[cup].LEDsNum;

    if ((LEDsSum > 0) && (LEDsSum <= TotVolActLEDs))
    {
      uint8_t LedsNumMAX = Drinks[0].LEDsNum;
      uint8_t LedsNumMAXPos = 0;
        for(uint8_t cup = 1; cup < DRINKS_NUM; cup++)
        {
          if (Drinks[cup].LEDsNum > LedsNumMAX)
          {
            LedsNumMAX = Drinks[cup].LEDsNum;
            LedsNumMAXPos = cup;
          }
        }

      Drinks[LedsNumMAXPos].LEDsNum += TotVolActLEDs - LEDsSum;

      Drinks[0].LEDsPos = VOLUME_START_PIXEL;
      for(uint8_t cup = 1; cup < DRINKS_NUM; cup++)
        Drinks[cup].LEDsPos = Drinks[cup - 1].LEDsPos + Drinks[cup - 1].LEDsNum;

      ColourMix = false;
    }
    
    else if (LEDsSum > TotVolActLEDs)
    {
      for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
      {
        Drinks[cup].LEDsNum = TotVolActLEDs;
        Drinks[cup].LEDsPos = VOLUME_START_PIXEL;
      }

      ColourMix = true;

      NewColour = 0;
      for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
        NewColour |= Drinks[cup].ProcColour;
    }

    bool EmptyCup = true;
    for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
    {
      if (Drinks[cup].LEDsNum != 0)
      {
        EmptyCup = false;
        break;
      } 
    }
    
    if (EmptyCup)
    {
      for(byte i = VOLUME_START_PIXEL; i < (VOLUME_START_PIXEL + TotVolActLEDs); i++)
        LEDS.setPixelColor(i, VOLUME_PROCESS_COLOUR);
    }

    else
    {
      if (ColourMix)
      {
        for(byte i = VOLUME_START_PIXEL; i < (VOLUME_START_PIXEL + TotVolActLEDs); i++)
          LEDS.setPixelColor(i, NewColour);
      }

      else
      {
        for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
        {
          if (Drinks[cup].LEDsNum != 0)
          {
            for(byte i = Drinks[cup].LEDsPos; i < (Drinks[cup].LEDsPos + Drinks[cup].LEDsNum); i++)
              LEDS.setPixelColor(i, Drinks[cup].ProcColour);
          }
        }
      }
    }
      SystemChange = false;
    }

    LEDS.show();
  }

  else
  {
    uint8_t LEDSPos[DRINKS_NUM];
    uint8_t LEDSNum[DRINKS_NUM];
    
    for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
    {
      LEDSPos[cup] = Drinks[cup].LEDsPos;
      LEDSNum[cup] = Drinks[cup].LEDsNum;
    }

    for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
    {
      if (Drinks[cup].LEDsNum != 0)
      {
      float Volume = Drinks[cup].mlVol;
      uint16_t VolCnt = 0;
      uint16_t mlPerLEDCoef = Volume / LEDSNum[cup];

      analogWrite(Drinks[cup].ActPin, PUMP_POWER);//вкл
      delay(PREPROCESS_DELAY);
    
      while (Volume >= MIN_VOLUME)
      {
        delay(mlToTimeCoef * MIN_VOLUME);
        Volume -= MIN_VOLUME;

        VolCnt += MIN_VOLUME;
        {
          if (VolCnt >= mlPerLEDCoef)
          {
    
            if (ColourMix)
            {
              
            }

            else
            {
                            
              if (LEDSNum[cup] != 0)
              {
               
                for(byte i = VOLUME_START_PIXEL; i < (VOLUME_START_PIXEL + PIXEL_IN_VOLUME); i++)
                  LEDS.setPixelColor(i, BACKGROUND_COLOUR);

                if (LEDSNum[cup] > 0)
                  LEDSNum[cup]--;
                for(uint8_t i = 0; i < DRINKS_NUM; i++)
                {
                  if (LEDSPos[i] > 0)
                    LEDSPos[i]--;
                }

                for(uint8_t i = 0; i < DRINKS_NUM; i++)
                {
                  if (Drinks[i].LEDsNum != 0)
                  {
                    for(byte j = LEDSPos[i]; j < (LEDSPos[i] + LEDSNum[i]); j++)
                      LEDS.setPixelColor(j, Drinks[i].ProcColour);
                  }
                }
              }
            }
            
            LEDS.show();
            VolCnt = 0;
          }
        }
      }

      analogWrite(Drinks[cup].ActPin, 0);//выкл

      if (cup < (DRINKS_NUM - 1))
      {
        uint8_t StickNum = cup + 1;
                uint8_t StartPixel = DRINK_START_PIXEL(StickNum);
      for (uint8_t BlinkTime = 0; BlinkTime < WaitCycle; BlinkTime++)
      {
        for(byte i = StartPixel; i < (StartPixel + PIXEL_IN_DRINK); i++)
          LEDS.setPixelColor(i, Drinks[cup+1].ShadColour);
        LEDS.show();
        delay(WaitShowDelay);
        
        for(byte i = StartPixel; i < (StartPixel + (Drinks[cup+1].Volume / DataThreshold)); i++)
          LEDS.setPixelColor(i, Drinks[cup+1].ProcColour);
        LEDS.show();
        delay(WaitShowDelay);
      }
      }
      
    }
    }

    delay(EndDelay);
    
    if (ColourMix)
    {
      for(byte i = VOLUME_START_PIXEL; i < (VOLUME_START_PIXEL + TotVolActLEDs); i++)
        LEDS.setPixelColor(i, NewColour);
    }

    else
    {
      for(uint8_t cup = 0; cup < DRINKS_NUM; cup++)
      {
        if (Drinks[cup].LEDsNum != 0)
        {
          for(byte i = Drinks[cup].LEDsPos; i < (Drinks[cup].LEDsPos + Drinks[cup].LEDsNum); i++)
            LEDS.setPixelColor(i, Drinks[cup].ProcColour);
        }
      }
    }
    
    State &= ~PROCESS;
  }
}
//----------------------------------------
void START_ISR()
{
  State |= PROCESS;
}
Поделиться с друзьями
-->

Комментарии (36)


  1. scg
    04.05.2017 11:34

    Так можно и пианоктейль сделать, если подключить MIDI клавиатуру.


    1. tolegs
      04.05.2017 11:45

      Семь бутылок придется установить. Ух! Смесь получится


      1. Stanislavvv
        04.05.2017 13:20

        12 бутылок! Кроме белых клавиш есть ещё и черные!
        Интересно, результат вообще будет употребим?


        1. tolegs
          04.05.2017 13:31
          +1

          Будет! Назовем «ТУ-160». У него 12 боевых ракет в пусковой установке


        1. scg
          04.05.2017 21:19

          Для полутонов можно добавить еще две бутылки: со спиртом и минералкой. Так сказать, для, усиления и ослабления основного тона.


    1. Neo5
      05.05.2017 10:01

      Уже придумано: «Гэллегер играл без нот и не глядя на клавиатуру. Это было бы совершенно естественно, будь он музыкантом, но Гэллегер был изобретателем. Пьяницей и сумасбродом, но хорошим изобретателем. Он хотел быть инженером-экспериментатором, и, вероятно, достиг бы в этом выдающихся успехов, поскольку моментами его осеняло. К сожалению, на систематические исследования ему не хватало средств, поэтому Гэллегер, консерватор интеграторов по профессии, держал свою лабораторию для души. Это была самая кошмарная лаборатория во всех Штатах. Десять месяцев он провел, создавая устройство, которое назвал алкогольным органом, и теперь мог, лежа на удобном мягком диване и нажимая кнопки, вливать в свою луженую глотку напитки любого качества и в любом количестве. Только вот сделал он этот орган, пребывая в состоянии сильного алкогольного опьянения, и разумеется, теперь не помнил принцип его действия. А жаль…». Каттнер Генри, Изобретатель Гэллагер


  1. RZimin
    04.05.2017 12:55

    Нужен контроль реально прокачанной жидкости, иначе может случиться «неприятность».


    1. Mikeware
      04.05.2017 13:34

      неприятность будет наутро…


    1. tolegs
      04.05.2017 13:36
      +1

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


      1. seri0shka
        05.05.2017 10:10
        +1

        Блииин! Уже и роботы не доливают! )


  1. Tujh
    04.05.2017 14:58

    После калибровки могут не долить, но не переливают.
    Вот даже не знаю что хуже :)


  1. TeosHM
    04.05.2017 15:02

    Насос от авто для омывайки не очень годится для подобной затеи. Ну либо очень тщательно придется их промывать перед запуском. Тут самое то перистальтические насосы использовать. Но у них стоимость выше в разы и производительность ниже :(
    Так пол литровый стакан подут наливать по 10 минут.


    1. Meklon
      04.05.2017 15:08

      Мои лабораторные могут и по поллитра в минуту) Но там цена негуманная.


      1. tolegs
        04.05.2017 15:13

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


        1. Mikeware
          04.05.2017 15:19

          а смешивать можно прямо во рту…


          1. nikitos_2002
            04.05.2017 16:19

            Технический спирт.


            1. tolegs
              04.05.2017 16:30

              Из четырех канистр


              1. nikitos_2002
                04.05.2017 16:36

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


                1. tolegs
                  04.05.2017 16:41

                  С праздником, nikitos!!!


                  1. nikitos_2002
                    04.05.2017 16:47

                    С днём гика?


        1. Meklon
          04.05.2017 17:56

          У меня их как раз 6)


  1. AVKinc
    04.05.2017 16:41

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


    1. nikitos_2002
      04.05.2017 16:48

      А давайте ещё сайт на транзисторах напишем?


      1. tolegs
        04.05.2017 16:59

        жжёшь


    1. tolegs
      04.05.2017 16:57

      Без ардуины никак. Шкалы из неопикселей работают только с микроконтроллером. Они безумно эффектные, а ведь используем этого бармена на празднике. Ну и оцифровка, вычисление частей в общем объеме, калибровка в конце концов.
      С дисплеем тоже пробовал. Скучно.
      Ну и главное — дети знают эту ардуину вдоль и поперёк, нужно же родителям говорить с ними на одном языке)


  1. BOOTor
    04.05.2017 18:41

    4 — очень мало. Хотя бы 7-8. Иначе смысла нет. Вот, например, минимальный набор емкостей.


    1. tolegs
      04.05.2017 22:47

      Это уже не для начинаюших


  1. ukt
    05.05.2017 10:37

    Можно насосы от чайников-термосов использовать, производительность выше.

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


    1. tolegs
      05.05.2017 10:51

      За насосы от термосов спасибо. Тема!
      Рядом с купюроприемником баночка для чаевых. Не, не баночка — трехлитровый баллон!


    1. Mikeware
      05.05.2017 10:58
      +1

      вот она, диалектика: бармен разгружается, посетители нагружаются…


      1. ukt
        05.05.2017 13:28

        Что плохого, что пользователь сам себе делает коктейль?
        Да и с другой стороны, такая приблуда, скорее, развлечения для, не выгоды ради. Хотя я бы всё по-другому сделал.


        1. Mikeware
          05.05.2017 15:11

          а вот если несовершеннолетний себе сделает? кого наказывать-то? :-)

          но, собственно, мой комментарий был о другом: «автоматизация» и упрощение заказа приведет к неумеренности потребления (у части, конечно).


  1. Yaroslav_dbls
    05.05.2017 17:41

    У Вас в проекте перистальтические насосы? Если да, то как трубка, помещенная в емкость, откуда выкачивается напиток — опустошается? И если насосы перистальтические, то может имеет смысл после прокачки жидкости делать реверс для опустошения трубки? Хотя тогда нужно уже не мосфеты, а драйверы.



  1. Vasia529
    07.05.2017 17:11

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


    1. tolegs
      07.05.2017 20:17

      А что нужно понимать в ссылках? Просто качайте. Там только файлы