Наверное многие уже видели автомойки самообслуживания. Можно ли создать такой аппарат на Arduino?


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

Как это работает


  1. Клиент приезжает на мойку
  2. Вносит деньги через купюроприёмник (на табло отображается сумма)
  3. Нажимает кнопку необходимого оборудования
  4. Клиент самостоятельно моет машину
  5. При желании нажимает стоп, либо выбирает другое оборудование
  6. Табло отсчитывает сумму за услуги (в зависимости от включенного оборудования)
  7. При обнулении оборудование выключается
  8. При необходимости повторить с п.2

При этом сетевые возможности аппарата позволяют:

  • Видеть все внесённые платежи
  • Менять настройки цен за услуги
  • Включать/выключать оборудование
  • Вести лог операций и ошибок на сервере

Состав оборудования


  • Arduino Uno R3
  • Матричный модуль типа MAX7219 на 4 знака
  • Ethernet шилд W5100
  • Модуль на 8 реле
  • Кнопки
  • Резисторы
  • Провода
  • Купюроприёмник Cashcode SM
  • Щит электрический (степень защиты чем больше, тем лучше)

Всё закуплено на Aliexpress (кроме купюроприёмника и щита).

Схема сборки


Сетевой шилд просто втыкается сверху. Далее всё собирается через него.

Arduino — Cashcode
A0 — 11 (TxD TTL)
A1 — 16 (RxD TTL)
GND — 4 (GND)

Arduino — MAX7219
A4 — CLK
A3 — CS
A2 — DIN
GND — GND
+5V — VCC

Arduino — Реле
2-7 — in1-in6
GND — GND
+5V — VCC

Кнопки собираются по схеме делителя напряжения и подключены на A5. У меня резисторы от 200Ом до 3,2КОм.



Программирование


Инициализация табло и реле:

#define DIN 16
#define CS  17   
#define CLK 18
#define max7219_reg_decodeMode  0x09
#define max7219_reg_intensity   0x0a
#define max7219_reg_scanLimit   0x0b
#define max7219_reg_shutdown    0x0c
#define max7219_reg_displayTest 0x0f
const unsigned char alf[] = {0,
  28, 34, 34, 34, 34, 34, 34, 28, 
  8, 24, 8, 8, 8, 8, 8, 28,
  28, 34, 2, 4, 8, 16, 32, 62, 
  28, 34, 2, 4, 2, 2, 34, 28, 
  34, 34, 34, 34, 62, 2, 2, 2,
  62, 32, 32, 60, 2, 2, 2, 60,
  28, 32, 32, 60, 34, 34, 34, 28,
  62, 2, 2, 4, 8, 16, 32, 32,
  28, 34, 34, 28, 34, 34, 34, 28,
  28, 34, 34, 30, 2, 2, 2, 28
};
void setup()
{    

  pinMode(DIN,OUTPUT);  pinMode(CS,OUTPUT);  pinMode(CLK,OUTPUT);  digitalWrite(CS, HIGH);
  initLed();    
  pinMode(2,  OUTPUT);  pinMode(3,  OUTPUT);  pinMode(4,  OUTPUT);  pinMode(5,  OUTPUT);  pinMode(6,  OUTPUT);  pinMode(7,  OUTPUT);   
    
  pinMode (A5, INPUT);
}

void setCommand(byte command, byte value)
{
  digitalWrite(CS, LOW);    
  for (int i=0; i<4; i++)   {    shiftOut(DIN,CLK, MSBFIRST, command);    shiftOut(DIN,CLK, MSBFIRST, value);  }
  digitalWrite(CS, HIGH);
}

void initLed()
{
  setCommand(max7219_reg_scanLimit, 0x07);      
  setCommand(max7219_reg_decodeMode, 0x00);  
  setCommand(max7219_reg_shutdown, 0x01);   
  setCommand(max7219_reg_displayTest, 0x00); 
  setCommand(max7219_reg_intensity, 1);  
}

Отображение числа на табло (текущее значение на случай отключения питания хранится в ячейках EEPROM 10 и 11):

int printNumber(int add)
{
  int n=EEPROM.read(10)+EEPROM.read(11)*256;
  if(add!=0) { n+=add; EEPROM.write(10, n%256); EEPROM.write(11, n>>8);   }
  int k;
  for (char i=1; i<=8; i++)
  {
   digitalWrite(CS, LOW);    
   for (char j=3; j>=0; j--) { k=n/pow(10,j);  shiftOut(DIN,CLK, MSBFIRST,i);   shiftOut(DIN,CLK, MSBFIRST,alf[i+(k%10)*8]); }   
   digitalWrite(CS, HIGH);
  }
  return n;
}

Считывание кнопки (keydown отслеживает возврат кнопок в исходное для исключения дребезга реле, числа в условиях подбираются опытным путём):

int key = analogRead (5);
  if(keydown && key<100) keydown=0;
  if((EEPROM.read(10)>0 || EEPROM.read(11)>0) && !keydown)
  {
    if(key>910 && key<980) setRele(1);
    if(key>810 && key<880) setRele(2);
    if(key>710 && key<760) setRele(3);
    if(key>550 && key<690) setRele(4);
    if(key>400 && key<500) setRele(5);
    if(key>330 && key<400) setRele(0);
  }    

Работа реле (в ячейках EEPROM 1-9 хранятся цены услуг за минуту использования):

void setRele(char r)
{  
  rele=r;
  keydown=1;
  for(char i=1;i<6;i++) digitalWrite(i+1, HIGH); 
  if(rele) 
 {  
  digitalWrite(rele+1, LOW);
  timeRele=millis(); 
  timeAllRele=60000/EEPROM.read(rele); 
 }
}

Счетчик денег (при включенном реле и превышении счетчика милисекунд заданного значения вычитаем 1):

 if(rele>0 && rele<=5 && (millis()-timeRele)>timeAllRele) 
{
 if(printNumber(-1)==0) setRele(0);
 timeRele+=timeAllRele; 
}

Сетевые клиент и сервер взяты из стандартных библиотек Arduino. Купюроприёмник работает по протоколу CCNET.

В следующих частях более подробное описание их работы и аппарата следующего поколения на одноплатнике Orange Pi с экраном 17" и тачскрином.
Поделиться с друзьями
-->

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


  1. igor_suhorukov
    26.01.2017 00:15

    Расскажите пожалуйста про Cashcode SM, какие купюры принимает и как с ним взаимодействовать?


    1. cat_crash
      26.01.2017 00:38
      -5

      Неужели у Вас google заблокирован?
      Сходу ссылки

      • http://www.cashcode.info/cashcode-sm.html
      • https://docs.google.com/spreadsheets/d/14uJjPuvD43BancR9NXm2vzmZ6jKdXT8iPIL8AsZnFFM/pub?output=html


      1. igor_suhorukov
        26.01.2017 00:44
        +13

        Да конечно можно поискать, но ценность хабра как раз в обсуждении с автором, который практически использовал этот аппарат «вживую».


    1. vvmk
      26.01.2017 10:53

      Пишу сейчас обработчик CCNET для купюрного валидатора CASHCODE
      на PHP под Linux.
      Есть в руках живая железка.
      Список принимаемых купюр можно получить от самого валидатора. Скорее всего зависит от региональной прошивки.


    1. paul_155
      27.01.2017 00:23
      +1

      наш принимает 10, 50, 100, 500, 1000, 5000
      пока не разбирался как это прошито и как добавить 200 и 2000
      взаимодействую по CCNET
      подробности в продолжении


  1. Germanets
    26.01.2017 09:15
    +1

    Полученное устройство где-то было практически применено, или так и осталось образцом?
    Неоднократно читал(хотя сам и не сталкивался), что Arduino Uno и другие Arduino-платы, кроме топовых Arduino MEGA являются достаточно ненадёжными и могут и самопроизвольно зависать, под воздействием помех или сами по себе. Были ли какие-то проблемы, жалобы на поведение устройства? Какой-то аналог WatchDog'а был использован?


    1. intsurfer
      26.01.2017 09:41

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


    1. paul_155
      27.01.2017 00:09

      работают 8 аппаратов. ардуины работают нормально. сеть часто виснет.


  1. Kassab
    26.01.2017 10:24
    +2

    Скока денег ушло?


    1. paul_155
      27.01.2017 00:10

      с ящиком повозились. остальное можно на али посмотреть. комплектующих на 1500 и купюрник б/у 5-8000


  1. Mixalych
    26.01.2017 11:16
    +1

    Продолжение интересно почитать, а также посмотреть видео о работе (принятие купюр, циферки на экране и пр.).

    Интересно также детали по поводу «3. Нажимает кнопку необходимого оборудования». Сколько выходит себестоимость плат, ящика, купюроприемника (тут я бы даже отдельную статью почитал по подключению и настройке, протоколу...). Сколько выходит стоимость мойки, используя разное оборудование — вода, пена, воск, что еще?

    На реальной (у нас) мойке дела обстоят так: платишь в кассу 100 р. за 6 минут, вот в эти 6 минут входит все доступное оборудование (пена, воск и вода), активируется время если из «корзины» достаешь пистолет, останавливается отсчет — когда пистолет ставишь обратно (там просто кнопка срабатывает от веса пистолета), ничего вручную нажимать не надо. К тому же на самом пистолете несколько положений и режимов, что хочешь использовать в данный момент — это гораздо удобнее, чем наматывать круги вокруг машины, нажимая кнопочку на блоке.


  1. NetRat
    26.01.2017 12:19

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


  1. noonv
    26.01.2017 15:26

    Интересная реализация.
    А у нас был проект реализации общения с платёжной системой по протоколу MDB.


  1. Aleksandr_Zh
    27.01.2017 00:14

    купюроприёмник у вам с сигналами уровня ttl?
    чем обусловлен выбор этого купюрника? он старого типа, проблемы с обманом (выниманием купюры), на них уже трудно найти комплектующие для ремонта.
    Про щит: я б вас на кол посадил за такой щит! чуть вода и вам кирдык! точнее, тому кто дотронется! вы бы правила изучили, а то трупы нам не нужны…
    про заземление щита и оборудования вообще молчу!!!

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


    1. paul_155
      27.01.2017 00:16

      ttl. их много дешевых б/у. щиты собирал не я. и честно говоря видел только на фотографиях.