CCNET для CashCode

Консультации специалистов «Crane Payment Innovation»
Гость

Сообщение Гость » 13 дек 2010, 06:43

sergkhar писал(а):Во, велосипедисты :). Чем родная TestCCNET не устроила?


На прилагаемом рисунке не змена стандартной TestCCNET, а лиш тестовая программа проверяющая работу объекта - который может быть использован в любом приложении, написаном на Delphi.

Заголовок объекта:

Код: Выделить всё

TCashCodeBillValidatorCCNET = class(TObject)
    constructor Create();
    destructor Destroy(); override;
  private
    FComFile  : THandle;  // Указатель на com порт
    FProcessMesage:TProcessMessage;
    FPolingBill:TPollingBill;
    FCanPollingLoop:Boolean; // Признак цикла опроса
    FNamberComPort:Byte;
    FComConnected:Boolean;
    FCommand:Array[0..255] of Byte; //Команда
    FLengthCommand:Byte;
    FAnswer:Array[0..255] of Byte;  //Ответ
    FLengthAnswer:Byte;
    FData:Array[0..255] of Byte;    //Данные ответа
    FLengthData:Byte;
    procedure ProcessMessage(CodeMess:integer;Mess:string);
    procedure PolingBill(Nominal:word;var CanLoop:boolean);
    //Выполнение сформированной команды
    procedure ProcessComand();
    // Формирование команды
    procedure SendPacket(Command:Byte;Data:Array of Byte);
    //Разбор команды
    procedure ParseAnswer();
    // Очистка команды
    procedure ClearCommand();
    // Очистка ответа
    procedure ClearAnswer();
    // Очистка данных
    procedure ClearData();
  public
    //Инициализация com порта
    function OpenComPort:Boolean;
    // Закрываем ком порт
    procedure CloseComPort();

    // Основные команды валидатора
    function Reset():Boolean; // Сброс купюро-приемника
    function Identification(var Name,Namber:string):Boolean;   //Номер и название купюроприемника
    function GetStatus(var Nominal,Security:TNominal):Boolean; //Получение списка принимаемых купюр
    function EnableBillTypes(Nominal:TNominal):Boolean;        //Установка прнимаемых купюр
    function SetSecurity(Nominal:TNominal):Boolean;            //Установка повышенного контроля для определенных купюр
    function Stack():Boolean;                                  //Принимаем купюру ESCROW режим
    function Return():Boolean;                                 //Возврат купюры   ESCROW режим
    function SendASC():Boolean;                                //Подтверждаем получение
    function SendNSC():Boolean;                                //Не подтверждааем получение
    function Poll():boolean;                                   //Опрос устройства
    function PollingLoop(Sum:word;TimeLoop:LongWord):Word;

    // Свойство для установки номера ком порта
    property NamberComPort:Byte read FNamberComPort write FNamberComPort;
    // Событие при любых сообщениях
    property OnProcessMessage:TProcessMessage read FProcessMesage write FProcessMesage;
    // Признак установки соединения с ком портом
    property ComConnected:Boolean read FComConnected;
    // Событие возникающее при приеме купюры, через переменную CanLoop можем прервать работу
    property OnPolingBill:TPollingBill read FPolingBill write FPolingBill;
    // Свойство проверяющее/устанавливающее цикл опроса
    property CanPollingLoop:Boolean read FCanPollingLoop write FCanPollingLoop;
  end;

Гость

Сообщение Гость » 13 дек 2010, 06:54

SpbPlat писал(а):Не, не, молодцы! Так держать, хотя на C++ видел уже модули работы с CCNet.


В один из дней при решении задачи подружить CashCode, обнаружил что в сети практически нет реализаций под Delphi дабы исправить данную несправедливость и решил создать сей релиз.

SpbPlat писал(а):Под ФР не хотите написать? (Под все, ну или большинство - Pay,Ярус,Искра,Штрих), да так, чтобы можно было с буфером Z работать, выдергивать отчеты оттуда в эл. виде?


Пока такая задача не ставится, но в будующем возможно.
Гость

Сообщение Гость » 10 янв 2011, 06:29

Здравствуйте testmode. Использую ваш модуль работы с купюроприемником CashCode. У меня возникли некоторые проблемы с его использованием.
Вот исходный код юнита производящего работу с модулем.

Код: Выделить всё

?unit Unit1;

interface

uses Windows, Classes, Graphics, Forms, Controls, Menus,
  Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, ImgList, StdActns,
  ActnList, ToolWin,UCashCode, Spin, SysUtils;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    cash:TCashCodeBillValidatorCCNET;
    procedure MessagessFormCC(CodeMess:integer;mess:string);
    procedure PolingBillCC(Nominal:word;var CanLoop:boolean);
    { Private declarations }
  public
    FSum:Word;
    procedure RefreshSum();
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
   cash:=TCashCodeBillValidatorCCNET.Create;
   cash.OnProcessMessage:=MessagessFormCC;
   cash.OnPolingBill:=PolingBillCC;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
        cash.NamberComPort:=1;
        if cash.OpenComPort then Memo1.Lines.Add('COM port opened');
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Sum:Word;
  Nominal:TNominal;
begin
  FSum:=0;
  RefreshSum();
  cash.Reset;

  // Установим принимаемые купюры
  Nominal.B10   :=   true;
  Nominal.B50   :=   true;
  Nominal.B100  :=   true;
  Nominal.B500  :=   true;
  Nominal.B1000 :=   true;
  Nominal.B5000 :=   true;

  cash.EnableBillTypes(Nominal);

  Sum:=cash.PollingLoop(10,200);
  Memo1.Lines.Add('Всего приняли : '+IntToStr(Sum));

  cash.Reset;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
        Name,Namber:string;
begin
  if cash.Identification(Name,Namber)
  then Memo1.Lines.Add('Номер : '+Namber+', Название : '+Name);
end;

procedure TForm1.MessagessFormCC(CodeMess: integer; mess: string);
begin
  if (CodeMess>100) and (CodeMess<=199)
  then Memo1.Lines.Add('Ошибка : '+inttostr(CodeMess)+' : '+mess)
  else Memo1.Lines.Add(inttostr(CodeMess)+' : '+mess);
  Application.ProcessMessages; // чтоб не залипала форма
end;

procedure TForm1.PolingBillCC(Nominal: word; var CanLoop: boolean);
begin
  FSum:=FSum+Nominal;
  Memo1.Lines.Add('Приняли '+intToStr(Nominal)+' рублей');
  RefreshSum();
  Application.ProcessMessages; // чтоб не залипала форма
end;
procedure TForm1.RefreshSum;
begin
  Memo1.Lines.Add(IntToStr(FSum));
end;

end.

Проблема заключается в следующем:
При скармливании купюры валидатору, программа возвращает ошибку "Не полный ответ".
Подскажите пожалуйста! Спасибо!
P.S. Модуль не изменялся и взят с версии 02.
P.P.S В текста исходника, при вставке в сообщение, почему-то апострофы обрамляющие строку заменились звёздочкой.
Гость

Сообщение Гость » 10 янв 2011, 11:29

TaiGel писал(а):Здравствуйте testmode. Использую ваш модуль работы с купюроприемником CashCode. У меня возникли некоторые проблемы с его использованием.
Вот исходный код юнита производящего работу с модулем.
Проблема заключается в следующем:
....
При скармливании купюры валидатору, программа возвращает ошибку "Не полный ответ".
Подскажите пожалуйста! Спасибо!
P.S. Модуль не изменялся и взят с версии 02.
P.P.S В текста исходника, при вставке в сообщение, почему-то апострофы обрамляющие строку заменились звёздочкой.


Дабы исключить "железные" заморочки (прошивку, ком порт) попробуйте следующее :

1. Проверьте не прошит ли куп под ID003
2. Стандартной утилитой от cashcode (либо демо примером, не пересобирая) проверьте работоспособность, ну хотябы ответ о серийнике и моделе.

П.С. Не полный ответ говорит о том что на посылку последовательности байт не получен ответ, либо он меньше 6 байтов (минимум для CCNET)... а значит либо прошивка под ID003 (и она не понимает чего от неё хотят) либо проблемы с ком портом (не исправен, куп не на том порте), но это я так забигая вперед.
Гость

Сообщение Гость » 11 янв 2011, 06:50

testmode писал(а):
TaiGel писал(а):Здравствуйте testmode. Использую ваш модуль работы с купюроприемником CashCode. У меня возникли некоторые проблемы с его использованием.
Вот исходный код юнита производящего работу с модулем.
....
Проблема заключается в следующем:
При скармливании купюры валидатору, программа возвращает ошибку "Не полный ответ".
Подскажите пожалуйста! Спасибо!
P.S. Модуль не изменялся и взят с версии 02.
P.P.S В текста исходника, при вставке в сообщение, почему-то апострофы обрамляющие строку заменились звёздочкой.


Дабы исключить "железные" заморочки (прошивку, ком порт) попробуйте следующее :

1. Проверьте не прошит ли куп под ID003
2. Стандартной утилитой от cashcode (либо демо примером, не пересобирая) проверьте работоспособность, ну хотябы ответ о серийнике и моделе.

П.С. Не полный ответ говорит о том что на посылку последовательности байт не получен ответ, либо он меньше 6 байтов (минимум для CCNET)... а значит либо прошивка под ID003 (и она не понимает чего от неё хотят) либо проблемы с ком портом (не исправен, куп не на том порте), но это я так забигая вперед.


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

Сообщение Гость » 11 янв 2011, 19:13

Проверил твой пример, итог куп отлично схавал 10 рублей... даже и не знаю что предположить,
как вариант попробуй увеличить таймаут между опросами в модуле объекта со 100 милискунд например до 500 мс..

Код: Выделить всё

function TCashCodeBillValidatorCCNET.PollingLoop(Sum: word;TimeLoop: LongWord): Word;
begin
...
      Sleep(100); // тут поменяй на 500
    end;

    if SecondsBetween(Now(),StartTime)> TimeLoop then
    begin
      FCanPollingLoop:=false;
      ProcessMessage(249,'Завершаем работу по таймауту приема купюры');
    end;
  end;
end;
Гость

Сообщение Гость » 12 янв 2011, 09:17

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

Сообщение Гость » 12 янв 2011, 09:46

testmode писал(а):Проверил твой пример, итог куп отлично схавал 10 рублей... даже и не знаю что предположить,
как вариант попробуй увеличить таймаут между опросами в модуле объекта со 100 милискунд например до 500 мс..

Код: Выделить всё

function TCashCodeBillValidatorCCNET.PollingLoop(Sum: word;TimeLoop: LongWord): Word;
begin
...
      Sleep(100); // тут поменяй на 500
    end;

    if SecondsBetween(Now(),StartTime)> TimeLoop then
    begin
      FCanPollingLoop:=false;
      ProcessMessage(249,'Завершаем работу по таймауту приема купюры');
    end;
  end;
end;



Попробовал изменить время, никаких изменений.
З.Ы. также ошибка "Не полный ответ" возникает при выполнении функции SendASC().
З.З.Ы. Определил что ошибку вызывал SendASC(). Убрал его, теперь куп отказывается принимать вторую купюру.
З.З.З.Ы Ошибка в компиляции, только что скомпилировал твой проект, при отправке ACK возвращается неполный ответ. А если запускать твой exeшник, то ACK нормально отправляется.
Гость

Сообщение Гость » 12 янв 2011, 11:11

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


Код: Выделить всё

procedure TFMain.PolingBillCC(Nominal: word; var CanLoop: boolean);
begin
//сдесь определяй условие по которому пора заканчивать клянчить деньги и если оно выполняется то CanLoop:=false;
end;

CashCodeBillValidatorCCNET.OnPolingBill:=PolingBillCC;




Как вариант, пытайся принять огромную сумму 10000000 RUR с периодом ожиания 10000000 секунд PollingLoop(10000000,10000000);
), и в нужный момент через событие OnPolingBill прекращай (в функцию события каждый раз возвращается принятая купюра, а через переменную CanLoop можно прервать работу) по моему то что нужно.
Гость

Сообщение Гость » 12 янв 2011, 11:23

TaiGel писал(а):Попробовал изменить время, никаких изменений.
З.Ы. также ошибка "Не полный ответ" возникает при выполнении функции SendASC().
З.З.Ы. Определил что ошибку вызывал SendASC(). Убрал его, теперь куп отказывается принимать вторую купюру.
З.З.З.Ы Ошибка в компиляции, только что скомпилировал твой проект, при отправке ACK возвращается неполный ответ. А если запускать твой exeшник, то ACK нормально отправляется.


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

По поводу компиляции предположу, что проблема может быть в реализации работы с com портом на конкретной версии. Под 2009,2010,XE проблем замечано небыло, насчет более ранних версий не скажу так как не пробовал. Могу посоветовать подебажить ProcessComand у объекта, при отправке команды SendASC, именно она отвечает за посыл сформированной команды и чтение ответа.
Гость

Сообщение Гость » 12 янв 2011, 11:28

testmode писал(а):
TaiGel писал(а):Попробовал изменить время, никаких изменений.
З.Ы. также ошибка "Не полный ответ" возникает при выполнении функции SendASC().
З.З.Ы. Определил что ошибку вызывал SendASC(). Убрал его, теперь куп отказывается принимать вторую купюру.
З.З.З.Ы Ошибка в компиляции, только что скомпилировал твой проект, при отправке ACK возвращается неполный ответ. А если запускать твой exeшник, то ACK нормально отправляется.


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

По поводу компиляции предположу, что проблема может быть в реализации работы с com портом на конкретной версии. Под 2009,2010,XE проблем замечано небыло, насчет более ранних версий не скажу так как не пробовал. Могу посоветовать подебажить ProcessComand у объекта, при отправке команды SendASC, именно она отвечает за посыл сформированной команды и чтение ответа.


Уже продебажил, проблемма в том что куп при посылке ACK возвращает в ответе одни нули. Ща качаю CodeGear 2009 попробую там скомпилить. Отпишусь. И проверь почту =))
Гость

Сообщение Гость » 12 янв 2011, 11:34

TaiGel писал(а): Уже продебажил, проблемма в том что куп при посылке ACK возвращает в ответе одни нули. Ща качаю CodeGear 2009 попробую там скомпилить. Отпишусь. И проверь почту =))


Имхо Лучше XE. В ней поменьше будет багов чем в 2009
Гость

Сообщение Гость » 29 янв 2011, 07:16

Скачал ваш исходник. Спасибо, помогли. Есть вопрос. Как указать список принимаемых купюр не на третьем байте, а на первом и втором например. "SendPacket($34,[0,255,255,0,0,0]);"?
Гость

Сообщение Гость » 31 янв 2011, 07:00

Verdana писал(а):Скачал ваш исходник. Спасибо, помогли. Есть вопрос. Как указать список принимаемых купюр не на третьем байте, а на первом и втором например. "SendPacket($34,[0,255,255,0,0,0]);"?


[0,255,255,0,0,0] = [X1,X2,X3,X4,X5,X6]

X1 - X6 - требуемые байты

X1 - X3 - списки принимаемых купюр
X4 - X6 - списки принимаемых купюр в особом режиме

Меняйте X1 или X2, или просто SendPacket($34,[255,255,255,0,0,0]) будет означать что принимаются все купюры из 1,2,3 байта
Гость

Сообщение Гость » 07 фев 2011, 23:22

Здравствуйте!

Большое спасибо за разработку. Подскажите пожалуйста такой вопрос: как лучше организовать прием средств - открывать порт при старте программы, а при необходимости приема средств вызывать PollingLoop, либо открытие порта делать в момент, когда собственно необходимость в приеме средств возникла?

И, соответственно, имеет ли смысл периодически опрашивать купюрник, чтобы удостовериться, что с ним все в порядке (когда программа в простое и ждет, что кто-то захочет заплатить). Если да, то с какой периодичностью посоветуете это делать?
deleted
Ваня, музыкант...
Сообщения: 1559
Зарегистрирован: 12 авг 2008, 15:00

Сообщение deleted » 08 фев 2011, 02:38

1- 1й вариант, с падением в ошибку при фатале валидатора, ибо нет смысла без него работать
2- при старте в порядке, значит и через 5 минут простоя в порядке. лишнее.
Гость

Сообщение Гость » 08 фев 2011, 08:47

m1y писал(а):Здравствуйте!

Большое спасибо за разработку. Подскажите пожалуйста такой вопрос: как лучше организовать прием средств - открывать порт при старте программы, а при необходимости приема средств вызывать PollingLoop, либо открытие порта делать в момент, когда собственно необходимость в приеме средств возникла?

И, соответственно, имеет ли смысл периодически опрашивать купюрник, чтобы удостовериться, что с ним все в порядке (когда программа в простое и ждет, что кто-то захочет заплатить). Если да, то с какой периодичностью посоветуете это делать?


В дополннение ответа from "dex" Порт открывать один раз и не закрывать, ничего с ним не случится... при вызове PollingLoop если для события OnProcessMessage установлена процедура то в неё возвратится и неверное состояние купа если онное будет иметь место быть:

Код: Выделить всё

//коды ошибок диаазон от 100 до 199
//100 - ошибка ком порта
//101 - ошибка сброса устройства
//102 - ошибки идентификации
//103 - ошибки получения статуса
//104 - ошибки установки списка принимаемых купюр
//105 - ошибки установки секретности
//106 - ошибки приема купюры
//107 - ошибки возвртата купюры
//108 - ошибки ASC
//109 - ошибки NSC
//110 - Ошибки опроса устройства

//Коды информавционных сообщений диапазон от 200 до 299
//201 - опрос
//202 - NSC
//203 - ASC
//204 - сброс
//205 - возврат
//206 - установка принмаемых купюр
//207 - особый режим приема
//208 - укладка купюры
//209 - идентификация
//210 - статус устройства
//211 - отправка ASC
//212 - отправка NSC
//213 - Включение питания после команд
//214 - Инициализация
//215 - Ожидание приема купюры
//216 - Акцепт
//217 - Недоступен, ожидаю инициализации
//218 - Полная кассета
//219 - Кассета отсутствует
//220 - Замяло купюру
//221 - Замяло касету
//222 - КАРАУЛ !!!! ЖУЛИКИ !!!
//223 - Сбой оборудования
//224 - Stack_motor_falure
//225 - Transport_speed_motor_falure
//226 - Transport-motor_falure
//227 - Aligning_motor_falure
//228 - Initial_cassete_falure
//229 - Optical_canal_falure
//230 - Magnetical_canal_falure
//231 - Capacitance_canal_falure
//232 - Отказ от приема
//233 - Insertion_error
//234 - Dielectric_error
//235 - Previously_inserted_bill_remains_in_head
//236 - Compensation__factor_error
//237 - Bill_transport_error
//238 - Identification_error
//239 - Verification_error
//240 - Optic_sensor_error
//241 - Return_by_inhibit_error
//242 - Capacistance_error
//243 - Operation_error
//244 - Length_error
//245 - Депонет
//246 - Укладка
//247 - Набрали нужную сумму
//248 - Возврат купюры
//249 - Завершаем работу по таймауту приема купюры
deleted
Ваня, музыкант...
Сообщения: 1559
Зарегистрирован: 12 авг 2008, 15:00

Сообщение deleted » 08 фев 2011, 10:25

да
Гость

Сообщение Гость » 08 фев 2011, 13:24

Огромнейшее Вам человеческое спасибо!

Не сочтите за наглость спросить: а нет ли у Вас реализаций на другие протоколы купюроприемников? a_h
Гость

Сообщение Гость » 09 фев 2011, 08:28

m1y писал(а):Огромнейшее Вам человеческое спасибо!

Не сочтите за наглость спросить: а нет ли у Вас реализаций на другие протоколы купюроприемников? a_h


К сожалению нет, так как небыло потребности... но как уже говорил при наличии спецификации протокола и девайса для тестов это на пару дней, или просто перепрошивка купа под нужный протокол -> последнее проще :)

Вернуться в «Купюроприемники CashCode и CashCode GX»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 4 гостя