Arduino на автомойке

в 19:25, , рубрики: arduino, DIY, IoT, автомойка, программирование микроконтроллеров, Разработка для интернета вещей

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

Arduino на автомойке - 1

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

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

  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КОм.

Arduino на автомойке - 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" и тачскрином.

Автор: paul_155

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js