Продолжаем рассмотрение применения Arduino для автомойки самообслуживания. Рассмотрим работу по сети и общение с купюроприёмником Cashcode. Начало см. тут.

Интернет-клиент


Активируем сразу клиент и сервер:

#include <Ethernet.h>

EthernetServer server(80);
byte mac[] = { 0xDE, 0x23, 0xBE, 0xEF, 0xFE, 0xED };
  IPAddress ip(192, 168, 1, 100);
  Ethernet.begin(mac, ip);
 server.begin();

Посылаем на сервер информацию, например о принятой купюре:

int sendInfo(string pay)
{
EthernetClient client;
   
  if (client.connect(domenip, 80) )
  {    
    client.println("GET /get_money.php?pay="+pay+" HTTP/1.1");  
    client.println("Host: www.domen.ru");
    client.println("Connection: keep-alive");
    client.println();
  } else  { Serial.println("connection failed"); return 0; }

  delay(100);

  char c;  
  while (client.available())
  {
    c=client.read();
  }
  client.stop();
  
  return (1);
}

Сервер


Активировали в предыдущем разделе. Проверяем наличие запросов.

for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
    EthernetClient sclient = server.available_(sock);
    myserver(sclient);
  }

Выполняем запрос. В ответе выводим текущее значение стоимости минуты оборудования (таймеры).

void myserver(EthernetClient client)
{
  if (!client) return;
  char clientline[100]; 
  int index = 0;
  while (client.available()) {
      char c = client.read();
      if(index<99) clientline[index] = c;
      index++;
  }
      
  if(strstr(clientline, "water")!=NULL) digitalWrite(2, LOW); //вода
  if(strstr(clientline, "pena")!=NULL) digitalWrite(3, LOW); //пена
  if(strstr(clientline, "vosk")!=NULL) digitalWrite(4, LOW); //воск

  client.println("HTTP/1.1 200 OK");  client.println("Content-Type: text/html");  client.println("Connection: close"); client.println();
  client.println("<!DOCTYPE HTML>"); client.println("<html>");
  for (int j = 1; j < 6; j++) {
         client.print("timer "); client.print(j);  client.print(" is "); client.print(EEPROM.read(j));  client.println("<br />");
        }          
  client.println("</html>");
  delay(100);
  client.stop();  
}

Купюроприёмник Cashcode


Работает через последовательный порт на уровнях TTL с помощью библиотеки SoftwareSerial.

SoftwareSerial mySerial(14, 15); // RX, TX
uint8_t poll[] = {0x02, 0x03, 0x06, 0x33, 0xDA, 0x81};
uint8_t ack[] = {0x02, 0x03, 0x06, 0x00, 0x0C2, 0x82};

Как уже сказано у меня Cashcode работает по протоколу CCNET. Возможны варианты, надо уточнять у продавца. Суть протокола в том, что система периодически (несколько раз в секунду достаточно) спрашивает у купюроприёмника его состояние (команда POOL). Тот отвечает. Если в ответе есть информация, нужно подтвердить её получение соответствующей командой (ACK).

Формат команды: SYNC ADR LNG CMD DATA CRC

SYNC: 1 byte код [02H]
ADR: 1 byte адрес купюроприёмника
LNG: 1 byte* длина данных
CMD: 1 byte команда
DATA 0 to 250 bytes Данные
CRC: 2 bytes контрольная сумма

Посылаем команду.

void sendCCNET(uint8_t *com)
{
  for(char i=0; i<com[2]; i++) mySerial.write(com[i]);
}

Если купюроприёмник прислал нам в ответе команду 0x81, значит он принял купюру. В данных содержится номинал. У меня это: 2=10 рублей, 3=50 рублей, 4=100 рублей, 5=500 рублей, 6=1000 рублей, 7=5000 рублей. Возможны варианты, зависит от прошивки.
Поделиться с друзьями
-->

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


  1. AllexIn
    04.02.2017 12:23
    +3

    if(strstr(clientline, «water»)!=NULL) digitalWrite(2, LOW); //вода
    if(strstr(clientline, «pena»)!=NULL) digitalWrite(3, LOW); //пена

    Не надо так.
    Либо уж везде транслит, либо везде английский.


    1. paul_155
      04.02.2017 16:29
      +1

      Вопросов много пришлось решать, некогда вспоминать как «пена» по-английски. Да и заказчик тоже наверное не знает.


      1. stifff
        05.02.2017 00:09

        а заказчик разве должен это знать?


        1. paul_155
          05.02.2017 10:16

          Разные бывают заказчики. Некоторые хотят знать.


  1. vvmk
    04.02.2017 14:12
    +1

    Если купюроприёмник прислал нам в ответе команду 0x81, значит он принял купюру. В данных содержится номинал. У меня это: 2=10 рублей, 3=50 рублей, 4=100 рублей, 5=500 рублей, 6=1000 рублей, 7=5000 рублей. Возможны варианты, зависит от прошивки.

    А тут гадать нечего, по команде GET BILL TABLE 0x41 купюроприёмник выдает таблицу соответсвия между своим «номером» купюры ее номиналом.
    Если вам попадется курюроприемник с другой версией firmware и номерами купюр, придется переписывать код вашего автомата?
    Не проще ли получать актуальные данные от самого аппарата?


    1. paul_155
      04.02.2017 16:30

      Да получаю актуальные данные.


    1. AllexIn
      04.02.2017 18:18

      Не проще. :)
      Встречал ssp устройства, которые отдавали ересь по запросу на список номиналов.


  1. lenz1986
    12.02.2017 20:46

    Приветствую. Может мне кто нибудь дать подглядеть рабочий кусок кода по обработке данных с кэшкода :) Нашел у себя в хламе купюрник и после прочтения статьи стало интересно его подцепить к ардуинке. С инициализацией купюрника я разобрался, а вот корректно с него данные забрать не могу.
    P.S> заранее благодарю


    1. vvmk
      14.02.2017 10:21

      Вы добились зеленой индикации на отверстии для купюр? Или дали reset и получили жужжание механики? Если так то этого не достаточно.
      Готовый код вам скорее всего никто не даст.
      Кое-что можете почитать тут и тут
      А вообще есть файл от производителя под названием CashCode One Validator — Programming for CCNET.pdf
      Файл тут
      Там полное описание всех команд, а в конце правильные алгоритмы инициализации, приема купюр, и т.д.