Конференция "WinAPI" » Купюроприемник CashCode, протокол ccnet [D7, WinXP]
 
  • Darth Avenger (01.03.07 10:34) [0]
    Приветствую мастеров!

    Кто-нибудь разбирался с протоколом ccnet (купюроприемник cashcode sm)? Если да, то можно поделиться исходником для изучения?

    P.S. Единственное, что я пока добился от купюроприёмника - это его soft reset - в com-порт тупо кидается последовательность #02#03#06#48#65#179#13. И это, вроде, работает.
  • Алексей666 (01.03.07 10:51) [1]
  • Darth Avenger (01.03.07 11:36) [2]
    Мануал хороший, спасибо. Но не сильно он меня вразумил. Может всё-же исходник найдётся? :)
  • Алексей_666 (01.03.07 11:44) [3]
    Исходников у меня нет. Но надо следить, чтобы режим
    работы ком порта совпадал с режимом принтера.
    Еще там можгут быть разные командные режимы
    Циклический и обычный.
  • Darth Avenger (02.03.07 10:37) [4]
    Спасибо всем сочувствующим :) Разобрался сам. Теперь могу поделиться исходником - делает ресет, затем инициализирует, ждёт купюру, выдаёт номинал купюры.
  • Rouse_ © (02.03.07 11:27) [5]
    А деньгу она выдает? :) Если да, то делись ;)
  • Darth Avenger (02.03.07 13:53) [6]
    Не, не выдаёт :) Оффтоп: да и купюроприёмник CashCode SM не рассчитан на выдачу сдачи, хотя это и нарушает права потребителя. Короче - если мы пишем софт для платежных терминалах, то указывать, что "терминал сдачу не даёт" обязательно! :)
  • tesseract © (02.03.07 13:57) [7]

    >  "терминал сдачу не даёт"


    Тогда терминал может получить сдачи :-)  

    Естественно купюроприёмник сдачу не выдаёт - нужен купюропередатчик :-)
  • Германн © (02.03.07 14:26) [8]
    Сдачу пусть выдает Хоппер. 5-ти рублевыми монетами. :)
  • selivan (13.03.07 20:39) [9]
    Darth Avenger , если не сложно, вышлите на мыло мне примерчик-то :)
    vis[at]nip.ru
  • AGaupsher (02.04.07 11:37) [10]
    Можно и мне исходник на alexey@maximedia.ru
    запарился уже разбираться - не читает из порта и все. Посмотрю хоть как у людей. Буду очень признателен.
  • SlOPS © (02.04.07 15:20) [11]
    И мне slavchick@mail.ru
  • tesseract © (03.04.07 10:50) [12]
    И такие люди делают банкоматы!

    А вы ещё справшиваете, чего они постоянно не работают и сдачу не выдают.......
  • Алекс_ТК (04.04.07 15:20) [13]
    Если можно и мне.... очень нужно.... Alma_15@mail.ru
  • Just-a-man © (06.04.07 18:42) [14]
    Можно и мне? just-a-man@bk.ru
    Пожалуйста!
  • Германн © (07.04.07 02:00) [15]

    > tesseract ©   (03.04.07 10:50) [12]
    >
    > И такие люди делают банкоматы!
    >

    И эти люди запрещают мне ковырятся в носу! :)

    И не говори. Вопрос платёжных терминалов и торговых автоматов и ... (лень продолжать) сейчас очень актуален. И, имхо, повторяется ситуация с "Компьютерными клубами"! Никто не хочет покупать "готовые решения". Все предпочитают нанять за грошИ студента!
  • tesseract © (07.04.07 11:58) [16]

    > И не говори. Вопрос платёжных терминалов и торговых автоматов
    > и ... (лень продолжать) сейчас очень актуален.


    Да я сам на "типо того" работал, щас ушёл - не ценят там труд.
  • Just-a-man © (09.04.07 17:00) [17]
    Здравствуйте!

    Кто-нибудь получил исходник от Darth Avenger??
    Если да, пришлите, пожалуйста на just-a-man@bk.ru
  • Алекс_ТК (10.04.07 09:47) [18]
    Пока ни чего не получал... Да и не надеюсь... Как говорится пока сам не сделаешь, ни кто не сделает. А на счет производителя оборудования, то здесь все как обычно - мы тут штуковину сделали, а дальше как хотите... Хреновый суппорт, почти не навязчивый сервис...
  • ПРОСТО СТРАННИК © (17.04.07 13:36) [19]
    То что надо!!! Мне бы тоже не помешало на сей чудо посмотреть... Если можно - incdo@mail.ru
  • Алекс_ТК (18.04.07 15:45) [20]
    Млин, в основном все вроде понятно, только никак разбудить его не могу после включения компа.... в чем собака порылась...
  • SteepeWolf (19.04.07 05:58) [21]
    Подскажите как деактивировать прибор после получения купюр.
  • Алекс_ТК (19.04.07 19:00) [22]
    По кнопочке, или по таймауту...
  • SteepeWolf (20.04.07 05:07) [23]
    И то и другое если можно
  • Алекс_ТК (20.04.07 09:34) [24]
    По кнопочке: для запуска POLL-цикла используем отдельный поток, тормозим кнопочкой, запускаем команду reset.
    По таймауту: делать пока .... то-то
  • SteepeWolf (20.04.07 10:13) [25]
    Спасибо.
    Уже сам разобрался
  • xazan © (20.04.07 16:11) [26]
    Приветствую мастеров! У кого есть исходник, могли бы мне кинуть. xazan@bk.ru. Буду очень признателен
  • xazan © (21.04.07 11:40) [27]
    Мастера ну скиньте пожалуйста! очень нужно.  xazan@bk.ru
  • AsTroT (27.04.07 16:09) [28]
    Скинь и мне плиззз astrot1988 [at] gmail.com
  • Stimo (30.04.07 14:35) [29]
    Выложите прямо тут - никому не помешает. Выкладывайте все, кто чего-то добился в этом вопросе, и кому не жалко
  • Алекс_ТК (03.05.07 13:21) [30]
    //Профи! Не смейтесь, написал как смог...//
    program CashCode_SM1;

    uses
     Forms,
     Unit1 in '..\Test_CachCode\Unit1.pas' {Form1},
     Unit2 in '..\Test_CachCode\Unit2.pas';

    {$R *.res}

    begin
     Application.Initialize;
     Application.CreateForm(TForm1, Form1);
     Application.Run;
    end.
  • Алекс_ТК (03.05.07 13:22) [31]
    //форма
    object Form1: TForm1
     Left = 323
     Top = 183
     BiDiMode = bdLeftToRight
     BorderStyle = bsSingle
     Caption = 'Программа тестирования CashCode-SM'
     ClientHeight = 415
     ClientWidth = 702
     Color = clMedGray
     Font.Charset = DEFAULT_CHARSET
     Font.Color = clWindowText
     Font.Height = -11
     Font.Name = 'MS Sans Serif'
     Font.Style = []
     OldCreateOrder = False
     ParentBiDiMode = False
     Position = poDefault
     Visible = True
     OnActivate = FormActivate
     PixelsPerInch = 96
     TextHeight = 13
     object Label1: TLabel
       Left = 96
       Top = 16
       Width = 79
       Height = 13
       Caption = '№ серийный:'
       Font.Charset = DEFAULT_CHARSET
       Font.Color = clWindowText
       Font.Height = -11
       Font.Name = 'MS Sans Serif'
       Font.Style = [fsBold]
       ParentFont = False
     end
     object Label3: TLabel
       Left = 8
       Top = 16
       Width = 62
       Height = 13
       Caption = '№ партии:'
       Font.Charset = DEFAULT_CHARSET
       Font.Color = clWindowText
       Font.Height = -11
       Font.Name = 'MS Sans Serif'
       Font.Style = [fsBold]
       ParentFont = False
     end
     object Label2: TLabel
       Left = 192
       Top = 16
       Width = 123
       Height = 13
       Caption = 'Достоинство купюр:'
       Font.Charset = DEFAULT_CHARSET
       Font.Color = clWindowText
       Font.Height = -11
       Font.Name = 'MS Sans Serif'
       Font.Style = [fsBold]
       ParentFont = False
     end
     object Label4: TLabel
       Left = 512
       Top = 224
       Width = 177
       Height = 49
       Alignment = taRightJustify
       AutoSize = False
       BiDiMode = bdLeftToRight
       Caption = '0.00'
       Font.Charset = RUSSIAN_CHARSET
       Font.Color = clWindowText
       Font.Height = -48
       Font.Name = 'Times New Roman'
       Font.Style = [fsBold]
       ParentBiDiMode = False
       ParentFont = False
       Layout = tlCenter
     end
     object Label5: TLabel
       Left = 585
       Top = 288
       Width = 105
       Height = 49
       Alignment = taRightJustify
       AutoSize = False
       Caption = '0'
       Font.Charset = RUSSIAN_CHARSET
       Font.Color = clWindowText
       Font.Height = -48
       Font.Name = 'Times New Roman'
       Font.Style = [fsBold]
       ParentFont = False
       Layout = tlCenter
     end
     object Label6: TLabel
       Left = 376
       Top = 227
       Width = 121
       Height = 46
       Alignment = taRightJustify
       AutoSize = False
       BiDiMode = bdLeftToRight
       Caption = 'Сумма:'
       Font.Charset = RUSSIAN_CHARSET
       Font.Color = clWindowText
       Font.Height = -32
       Font.Name = 'Times New Roman'
       Font.Style = [fsBold]
       ParentBiDiMode = False
       ParentFont = False
       Layout = tlCenter
     end
     object Label7: TLabel
       Left = 218
       Top = 296
       Width = 281
       Height = 41
       Alignment = taRightJustify
       AutoSize = False
       BiDiMode = bdLeftToRight
       Caption = 'Количество купюр:'
       Font.Charset = RUSSIAN_CHARSET
       Font.Color = clWindowText
       Font.Height = -32
       Font.Name = 'Times New Roman'
       Font.Style = [fsBold]
       ParentBiDiMode = False
       ParentFont = False
       Layout = tlCenter
     end
     object Label8: TLabel
       Left = 586
       Top = 351
       Width = 105
       Height = 50
       Alignment = taRightJustify
       AutoSize = False
       Caption = '0'
       Font.Charset = RUSSIAN_CHARSET
       Font.Color = clWindowText
       Font.Height = -48
       Font.Name = 'Times New Roman'
       Font.Style = [fsBold]
       ParentFont = False
       Layout = tlCenter
     end
     object Label9: TLabel
       Left = 221
       Top = 356
       Width = 281
       Height = 45
       Alignment = taRightJustify
       AutoSize = False
       BiDiMode = bdLeftToRight
       Caption = 'Номинал купюры:'
       Font.Charset = RUSSIAN_CHARSET
       Font.Color = clWindowText
       Font.Height = -32
       Font.Name = 'Times New Roman'
       Font.Style = [fsBold]
       ParentBiDiMode = False
       ParentFont = False
       Layout = tlCenter
     end
     object Label10: TLabel
       Left = 376
       Top = 16
       Width = 143
       Height = 13
       Caption = 'Трассировка запросов:'
       Font.Charset = DEFAULT_CHARSET
       Font.Color = clWindowText
       Font.Height = -11
       Font.Name = 'MS Sans Serif'
       Font.Style = [fsBold]
       ParentFont = False
     end
     object Button3: TButton
       Left = 192
       Top = 64
       Width = 177
       Height = 25
       Caption = 'Принимаемые купюры'
       TabOrder = 0
       OnClick = Button3Click
     end
     object Button4: TButton
       Left = 8
       Top = 128
       Width = 177
       Height = 25
       Caption = 'Получить статус'
       TabOrder = 1
       OnClick = Button4Click
     end
     object Button5: TButton
       Left = 192
       Top = 160
       Width = 177
       Height = 25
       Caption = 'Выключение'
       TabOrder = 2
       OnClick = Button5Click
     end
     object Button6: TButton
       Left = 192
       Top = 96
       Width = 177
       Height = 25
       Caption = 'Старт POLL'
       TabOrder = 3
       OnClick = Button6Click
     end
     object Memo1: TMemo
       Left = 376
       Top = 32
       Width = 313
       Height = 185
       ScrollBars = ssVertical
       TabOrder = 4
     end
     object Button7: TButton
       Left = 192
       Top = 128
       Width = 177
       Height = 25
       Caption = 'Стоп POLL'
       TabOrder = 5
       OnClick = Button7Click
     end
     object Button8: TButton
       Left = 8
       Top = 96
       Width = 177
       Height = 25
       Caption = 'Перезагрузка'
       TabOrder = 6
       OnClick = Button8Click
     end
     object Button9: TButton
       Left = 8
       Top = 64
       Width = 177
       Height = 25
       Caption = 'Инициализация'
       TabOrder = 7
       OnClick = Button9Click
     end
     object Edit6: TEdit
       Left = 8
       Top = 32
       Width = 81
       Height = 21
       BevelOuter = bvNone
       BiDiMode = bdLeftToRight
       Color = clScrollBar
       Font.Charset = DEFAULT_CHARSET
       Font.Color = clWindowFrame
       Font.Height = -11
       Font.Name = 'MS Sans Serif'
       Font.Pitch = fpFixed
       Font.Style = [fsBold]
       ParentBiDiMode = False
       ParentFont = False
       TabOrder = 9
     end
     object Edit7: TEdit
       Left = 96
       Top = 32
       Width = 89
       Height = 21
       BevelOuter = bvSpace
       BiDiMode = bdLeftToRight
       Color = clScrollBar
       Ctl3D = True
       Font.Charset = DEFAULT_CHARSET
       Font.Color = clWindowText
       Font.Height = -11
       Font.Name = 'MS Sans Serif'
       Font.Style = [fsBold]
       ParentBiDiMode = False
       ParentCtl3D = False
       ParentFont = False
       TabOrder = 8
     end
     object Button10: TButton
       Left = 8
       Top = 160
       Width = 177
       Height = 25
       Caption = 'Режим ожидания купюры'
       TabOrder = 10
       OnClick = Button10Click
     end
     object Edit8: TEdit
       Left = 192
       Top = 32
       Width = 177
       Height = 21
       BiDiMode = bdLeftToRight
       CharCase = ecLowerCase
       Color = clScrollBar
       Ctl3D = True
       Font.Charset = DEFAULT_CHARSET
       Font.Color = clWindowText
       Font.Height = -11
       Font.Name = 'MS Sans Serif'
       Font.Style = [fsBold]
       ParentBiDiMode = False
       ParentCtl3D = False
       ParentFont = False
       TabOrder = 11
     end
     object ComboBox1: TComboBox
       Left = 8
       Top = 192
       Width = 177
       Height = 21
       Style = csDropDownList
       ItemHeight = 13
       ItemIndex = 0
       TabOrder = 12
       Text = 'Com1:'
       OnChange = ComboBox1Change
       Items.Strings = (
         'Com1:'
         'Com2:'
         'Com3:'
         'Com4:'
         'Com5:'
         'Com6:'
         'Com7:')
     end
    end
  • Алекс_ТК (03.05.07 13:24) [32]
    unit Unit1;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls, Unit2;

    type
     TForm1 = class(TForm)
       Button3: TButton;
       Button4: TButton;
       Button5: TButton;
       Button6: TButton;
       Button7: TButton;
       Button8: TButton;
       Button9: TButton;
       Edit6: TEdit;
       Edit7: TEdit;
       Label1: TLabel;
       Label3: TLabel;
       Button10: TButton;
       Memo1: TMemo;
       Edit8: TEdit;
       Label2: TLabel;
       Label4: TLabel;
       Label5: TLabel;
       Label6: TLabel;
       Label7: TLabel;
       Label8: TLabel;
       Label9: TLabel;
       Label10: TLabel;
       ComboBox1: TComboBox;
       procedure Button3Click(Sender: TObject);
       procedure Button4Click(Sender: TObject);
       procedure Button5Click(Sender: TObject);
       procedure Button6Click(Sender: TObject);
       procedure Button7Click(Sender: TObject);
       procedure Button8Click(Sender: TObject);
       procedure Button9Click(Sender: TObject);
       procedure Button10Click(Sender: TObject);
       procedure FormActivate(Sender: TObject);
       procedure ComboBox1Change(Sender: TObject);

     private
       { Private declarations }
     public
       { Public declarations }
        TPotok : Potok;
        procedure UpdateSumm;
     end;
     // объява длл функций
     //procedure PDConnect(Var ComPortss : String);   StdCall;
     //procedure PDDisConnect;                        StdCall;
     //procedure PDPoll;                              StdCall;
     //procedure PDStopPoll(var StopPolle : Boolean); StdCall;
     //function  LastSumm:integer;                    StdCall;
    const
    ConReACK : array[1..6] of Byte = ($02,$03,$06,$00,$C2,$82);
    ConReset : array[1..6] of Byte = ($02,$03,$06,$30,$41,$B3);
    ConGetSt : array[1..6] of Byte = ($02,$03,$06,$31,$C8,$A2);
    ConStPoll: array[1..6] of Byte = ($02,$03,$06,$33,$DA,$81);
    ConIdent : array[1..6] of Byte = ($02,$03,$06,$37,$FE,$C7);
    ConGetBT : array[1..6] of Byte = ($02,$03,$06,$41,$4F,$D1);
    ConStack : array[1..6] of Byte = ($02,$03,$06,$35,$EC,$E4);
    ConReturn: array[1..6] of Byte = ($02,$03,$06,$36,$77,$D6);
    ConHold  : array[1..6] of Byte = ($02,$03,$06,$38,$09,$3F);
    ConExtBD : array[1..6] of Byte = ($02,$03,$06,$3A,$1B,$1C);
    ConReqSt : array[1..6] of Byte = ($02,$03,$06,$60,$C4,$E1);
    ConEnBT  : array[1..12] of Byte = ($02,$03,$0C,$34,$FF,$FF,$FF,$00,$00,$00,$B5,$C1);
    ConDiBT  : array[1..12] of Byte = ($02,$03,$0C,$34,$00,$00,$00,$00,$00,$00,$17,$0C);

    var
     Form1    : TForm1;
     ComPorts : string;
     ComFile  : THandle;
     ReadAr   : array[1..255] of byte;
     BytesWritten: DWORD;
     BytesRead   : DWORD;

    function ArrInStr(InDtn: array of byte; DatLng: dword) : string;
    // блок длл функций
    //procedure PDConnect;    external 'CashCodeSM.dll' name 'PDConnect';
    //procedure PDDisConnect; external 'CashCodeSM.dll' name 'PDDisConnect';
    //procedure PDPoll;       external 'CashCodeSM.dll' name 'PDPoll';
    //procedure PDStopPoll;   external 'CashCodeSM.dll' name 'PDStopPoll';
    //function  LastSumm;     external 'CashCodeSM.dll' name 'LastSumm';
    //
    implementation

    {$R *.dfm}

    // Массив в строку
    function ArrInStr(InDtn: array of byte; DatLng: dword) : string;
    var
    s: integer;
    begin
    Result := '';
    for s:=0 to (DatLng-1) do
    Result := Result+IntToStr(InDtn[s])+' ';
    end;

    //Раскладка в строку
    function ASCIIToStr(AsciiString: string): string;
    var
    I, X, L, Lastpos: Integer;
    CurDIGChar, CurrAddChar, RS: string;

    begin
    RESULT := '';
    L := Length(AsciiString);
    if L = 0 then
      Exit;
    X := 0;
    LASTPOS := 1;
    repeat
      I := X;
      CurDIGChar := '';
      repeat
        I := I + 1;
        if AsciiString[I] <> '#' then
          CurDIGChar := CurDIGChar + AsciiString[I];
      until (AsciiString[I] = '#') or (i = l);
      X := I;
      if CurDIGChar <> '' then
      begin
        try
          CurrAddChar := CHR(STRTOINT(CurDIGChar));
        except CurrAddChar := '';
        end;
        Insert(CurrAddChar, RS, lastpos);
        LastPos := LastPos + Length(CurrAddChar);
      end;
    until (X >= L) or (I >= L);
    Result := RS;
    end;

    // OpenCOMPort
    function OpenCOMPort: Boolean;
    var
    DeviceName: array[0..80] of Char;
    begin
    StrPCopy(DeviceName, ComPorts);
    ComFile := CreateFile(DeviceName, GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if ComFile = INVALID_HANDLE_VALUE then
      Result := False
    else
      Result := True;
    end;

    // SetupCOMPort
    function SetupCOMPort: Boolean;
    const
    RxBufferSize = 256;
    TxBufferSize = 256;
    var
    DCB: TDCB;
    CommTimeouts: TCommTimeouts;

    begin
    Result := True;
    if not SetupComm(ComFile, RxBufferSize, TxBufferSize) then
      Result := False;
    if not GetCommState(ComFile, DCB) then
      Result := False;
      DCB.BaudRate:=9600;
      DCB.ByteSize:=8;
      DCB.Parity:=noparity;
      DCB.StopBits:=ONESTOPBIT;
      DCB.Flags:=DTR_CONTROL_ENABLE;
    if not SetCommState(ComFile, DCB) then
      Result := False;
    with CommTimeouts do

    begin
      ReadIntervalTimeout         := 400;
      ReadTotalTimeoutMultiplier  := 0;
      ReadTotalTimeoutConstant    := 400;
      WriteTotalTimeoutMultiplier := 0;
      WriteTotalTimeoutConstant   := 400;
    end;

    if not SetCommTimeouts(ComFile, CommTimeouts) then
      Result := False;
    end;

    // продолжение следует...
  • Алекс_ТК (03.05.07 13:25) [33]
    // продолжение...
    function ReadText: string;
    var
    i: integer;
    begin
    if ComFile = INVALID_HANDLE_VALUE then
      raise Exception.Create('Не открыта запись в Com порт');
    if ReadFile(ComFile, ReadAr, SizeOf(ReadAr), BytesRead, nil) then
    begin
     for i := 1 to BytesRead do
      Result := Result+IntToStr(ReadAr[i])+' ';
    end
    else
      raise Exception.Create('Ошибка приема данных:');
    end;

    // CloseCOMPort
    procedure CloseCOMPort;
    begin
    CloseHandle(ComFile);
    end;

    // Перезагрузка
    procedure GetReset;
    begin
    WriteFile(ComFile, ConReset, SizeOf(ConReset), BytesWritten, nil);
    ReadFile(ComFile, ReadAr, SizeOf(ReadAr), BytesRead, nil);
    end;

    // Инициализация
    procedure GetInisialise;
    var
    p: integer;
    ResP1 : string;
    ResP2 : string;
    ResP3 : string;
    ResP4 : string;
    begin
    WriteFile(ComFile, ConIdent, SizeOf(ConIdent), BytesWritten, nil);
    ReadFile(ComFile, ReadAr, SizeOf(ReadAr), BytesRead, nil);
    for p := 1 to BytesRead do
      begin
        if (p > 3) and (p < 15) then
           begin
             ResP1 := ResP1 + IntToStr(ReadAr[p])+'#';
             ResP2 := ASCIIToStr(ResP1);
        end;
        if (p > 18) and (p < 31) then
           begin
             ResP3 := ResP3 + IntToStr(ReadAr[p])+'#';
             ResP4 := ASCIIToStr(ResP3);
        end;
      end;
    Form1.Edit6.Text := ResP2;
    Form1.Edit7.Text := ResP4;
    Sleep(100);
    end;

    // Получим номиналы купюр которые принимаем
    procedure GetNominal;
    var
    p: integer;
    ResP1, ResP2, ResP3, ResP4, ResP5, ResP6 : string;
    begin

    WriteFile(ComFile, ConGetBT, SizeOf(ConGetBT), BytesWritten, nil);
    ReadFile(ComFile, ReadAr, SizeOf(ReadAr), BytesRead, nil);
    for p := 1 to BytesRead do
      begin
        if (p > 13) and (p < 19) then ResP1 := '10';
        if (p > 18) and (p < 24) then ResP2 := '50';
        if (p > 23) and (p < 29) then ResP3 := '100';
        if (p > 28) and (p < 34) then ResP4 := '500';
        if (p > 33) and (p < 39) then ResP5 := '1000';
        if (p > 38) and (p < 44) then ResP6 := '5000';
      end;
      Form1.Edit8.Text := ResP1 + ', ' + ResP2 + ', ' + ResP3 + ', ' + ResP4 + ', ' + ResP5 + ', ' + ResP6 ;
    end;

    // Вход в режим опроса
    procedure GetPollStatys;
    begin
    WriteFile(ComFile, ConStPoll, SizeOf(ConStPoll), BytesWritten, nil);
    end;

    // Выключение
    procedure GetShatDone;
    begin
    //PDDisConnect; // типа дял длл
    //работа без длл
    GetPollStatys;
    Sleep(10);
    WriteFile(ComFile, ConEnBT, SizeOf(ConEnBT), BytesWritten, nil);
    Sleep(10);
    ReadFile(ComFile, ReadAr, SizeOf(ReadAr), BytesRead, nil);
    Sleep(10);
    WriteFile(ComFile, ConDiBT, SizeOf(ConDiBT), BytesWritten, nil);
    Sleep(10);
    ReadFile(ComFile, ReadAr, SizeOf(ReadAr), BytesRead, nil);
    Sleep(10);
    end;

    procedure TForm1.Button3Click(Sender: TObject);
    begin
    GetNominal;
    end;

    procedure TForm1.Button4Click(Sender: TObject);
    begin
    GetPollStatys;
    end;

    procedure TForm1.Button5Click(Sender: TObject);
    begin
    GetShatDone;
    end;

    procedure TForm1.Button7Click(Sender: TObject);
    begin
    TPotok.Terminate;        // добавил корректный тормоз потока
    //PDStopPoll(StopPoll);  // длл
    WriteFile(ComFile, ConDiBT, SizeOf(ConDiBT), BytesWritten, nil);
    end;

    procedure TForm1.UpdateSumm;   // синхрониз
    begin
     Label4.Caption := IntToStr(SumBill)+'.00';
     Label5.Caption := IntToStr(KolBill);
     Label8.Caption := IntToStr(LastBill);
    end;

    procedure TForm1.Button6Click(Sender: TObject);
    begin
    //PDPoll;  //для длл
    // стартуем поток по умному
      TPotok := Potok.Create(True);
      TPotok.FreeOnTerminate := True;
      TPotok.Priority        := tpLower;
      TPotok.Resume;
    end;

    procedure TForm1.Button8Click(Sender: TObject);
    begin
    GetReset;
    end;

    procedure TForm1.Button9Click(Sender: TObject);
    begin
    GetInisialise;
    end;

    // Режим ожидания купюры
    procedure TForm1.Button10Click(Sender: TObject);
    begin
    GetPollStatys;
    sleep(10);
    WriteFile(ComFile, ConEnBT, SizeOf(ConEnBT), BytesWritten, nil);
    end;

    procedure TForm1.ComboBox1Change(Sender: TObject);
    begin
    CloseCOMPort;
    ComPorts := ComboBox1.Items.Strings[ComboBox1.ItemIndex];
    OpenCOMPort;
    SetupCOMPort;
    GetReset;
    GetInisialise;
    GetNominal;
    end;

    // При открытии формы Активируем порт и его установки
    procedure TForm1.FormActivate(Sender: TObject);
    begin
    ComPorts := ComboBox1.Items.Strings[0];
    //PDConnect(ComPorts); // длл
    // работа без длл
    OpenCOMPort;
    SetupCOMPort;
    GetReset;
    GetInisialise;
    GetNominal;
    end;

    end.
  • Алекс_ТК (03.05.07 13:25) [34]
    //Юнит-поток
    unit Unit2;

    interface

    uses
     Classes;
    type
     Potok = class(TThread)
     private
       { Private declarations }
     protected
       procedure Execute; override;
     end;
    var

    SumBill  : Integer;
    KolBill  : Integer;
    LastBill : Integer;

    implementation

    uses Windows, SysUtils, Unit1;

    { Important: Methods and properties of objects in visual components can only be
     used in a method called using Synchronize, for example,
          Synchronize(UpdateCaption);
     and UpdateCaption could look like,
       procedure Potok.UpdateCaption;
       begin
         Form1.Caption := 'Updated in a thread';
       end; }

    { Potok }

    procedure Potok.Execute;
    var
    i: integer;
    s: integer;
    p: integer;
    n: integer;
    ResP : string;
    begin

    WriteFile(ComFile, ConIdent, SizeOf(ConIdent), BytesWritten, nil);
    Sleep(10);
    ReadFile(ComFile, ReadAr, SizeOf(ReadAr), BytesRead, nil);
    Sleep(10);
    i := 0;
    s := 0;
    n := 0;

    repeat
    WriteFile(ComFile, ConReACK, SizeOf(ConReACK), BytesWritten, nil);
    Sleep(10);
    WriteFile(ComFile, ConStPoll, SizeOf(ConStPoll), BytesWritten, nil);
    Sleep(10);
    ReadFile(ComFile, ReadAr, SizeOf(ReadAr), BytesRead, nil);
     Form1.Memo1.Lines.Add('<-- '+ArrInStr(ReadAr, BytesRead));
     if ReadAr[4] = 19 then Form1.Memo1.Lines.Add('** Инициализация **');
     if ReadAr[4] = 25 then
      begin
      Form1.Memo1.Lines.Add('** Ожидаю купюру **');
      WriteFile(ComFile, ConEnBT , SizeOf(ConEnBT) , BytesWritten, nil);
      Sleep(10);
      ReadFile (ComFile, ReadAr  , SizeOf(ReadAr)  , BytesRead   , nil);
      Sleep(10);
      end;
     if ReadAr[4] = 21 then Form1.Memo1.Lines.Add('****** Акцепт *****');
     if ReadAr[4] = 23 then Form1.Memo1.Lines.Add('******* Стэк ******');
     for p := 1 to 5 do
      ResP := ResP+IntToStr(ReadAr[p]);
      if ResP = '2371292'  then
      begin
       Form1.Memo1.Lines.Add('10 рублей');
       i := i + 1;
       s := s + 10;
       n := 10;
      end;
      if ResP = '2371293'  then
      begin
       Form1.Memo1.Lines.Add('50 рублей');
       i := i + 1;
       s := s + 50;
       n := 50;
      end;
      if ResP = '2371294'  then
      begin
       Form1.Memo1.Lines.Add('100 рублей');
       i := i + 1;
       s := s + 100;
       n := 100;
      end;
      if ResP = '2371295'  then
      begin
       Form1.Memo1.Lines.Add('500 рублей');
       i := i + 1;
       s := s + 500;
       n := 500;
      end;
      if ResP = '2371296'  then
      begin
       Form1.Memo1.Lines.Add('1000 рублей');
       i := i + 1;
       s := s + 1000;
       n := 1000;
      end;
      if ResP = '2371297'  then
      begin
       Form1.Memo1.Lines.Add('5000 рублей');
       i := i + 1;
       s := s + 5000;
       n := 5000;
      end;
      if ResP = '23728101' then Form1.Memo1.Lines.Add('Не съедобно');
      if ResP = '23728108' then Form1.Memo1.Lines.Add('Тоже не съедобно');
      if ResP = '23728100' then Form1.Memo1.Lines.Add('Разверни бамажку');
      Form1.Memo1.Lines.Add('<-- '+ResP);
      ResP := '';
      SumBill  := s;
      KolBill  := i;
      LastBill := n;
      Synchronize(Form1.UpdateSumm);
    until Terminated;

    Form1.Memo1.Lines.Add('** Тормозимся **');

    WriteFile(ComFile, ConDiBT, SizeOf(ConDiBT), BytesWritten, nil);
    Form1.Memo1.Lines.Add('--> '+ArrInStr(ConDiBT, BytesWritten));
    ReadFile(ComFile, ReadAr, SizeOf(ReadAr), BytesRead, nil);
    Form1.Memo1.Lines.Add('<-- '+ArrInStr(ReadAr, BytesRead));

    WriteFile(ComFile, ConReACK, SizeOf(ConReACK), BytesWritten, nil);
    Form1.Memo1.Lines.Add('--> '+ArrInStr(ConReACK, SizeOf(ConReACK)));

    WriteFile(ComFile, ConStPoll, SizeOf(ConStPoll), BytesWritten, nil);
    Form1.Memo1.Lines.Add('--> '+ArrInStr(ConStPoll, SizeOf(ConStPoll)));
    ReadFile(ComFile, ReadAr, SizeOf(ReadAr), BytesRead, nil);
    Form1.Memo1.Lines.Add('<-- '+ArrInStr(ReadAr, BytesRead));
    end;

    end.
  • Алекс_ТК (03.05.07 13:26) [35]
    Вот...
  • ПРОСТО СТРАННИК © (03.05.07 13:30) [36]
    Алекс_ТК .
    Что то не понятно тут с кодами, может выложешь куда нибудь архивчмк с программой, например на ifolder.ru, иль  будь добр на fullsux@mail.ru... В долгу не останусь... расчёты через Яндекс-деньги.
  • Алекс_ТК (04.05.07 08:48) [37]
    Вопрос для профи: как теперь вогнать вышеизложенное в длл...
    Столкнулся с проблемой извлечения значений переменных из потока...
  • technocode (04.05.07 14:41) [38]
    Вот полные исходники для всех купюрников и принтеров..
    только ковырятся надо:
    Полные исхоники программы Ciberplat
    http://www.technocode.ru/techno.html
    пароль по запросу на ridall@mail.ru
  • Vinbudya (18.06.07 10:56) [39]
    Есть C++ API и несколько примеров от производителя. Я писал на cachcode.com запрос и мне выслали исходники библиотеки (несколько исходных файлов, не собранных в проект) и хелп. Кому надо - мыльте, я перешлю.

    А вообще я на .NET за пол дня весь протокол сделал. Ихний API имеет универсальный характер для всех типов устройств и очень накрученный. Надо его собирать в либу, потом делать враппер на .NET. Короче легкий путь споймать кучу багов :) Поэтому я не использовал.  У кого проект на плюсах можете сразу в проект вставлять исходники библиотеки и наслаждаться :)
  • имя (26.06.07 23:33) [40]
    Удалено модератором
  • malor (04.07.07 11:23) [41]
    Несколько вопросов по "Описанию протокола CCNET", как переводятся слова/фразы:
    Bill-to-Bill unit
    Coin Changer
    escrow
    Cassete
    recycling
  • anonym (19.10.07 18:00) [42]
    Алекс_ТК синхронизация для потока нужна
  • Alexccc (30.10.07 12:10) [43]
    Товарищи подскажите пожайлуста, что делать, купюрник не хочет брать денюжку-выплёвывает, а если надовить сверху то берет (иногда), и время от времени пишит "зажевана купюра" CashCode PartNo: MSM-3005KZ2101
  • Felan (06.12.07 09:05) [44]
    Может кто сталкивался и может объяснить пару моментов с купюрником SM-2073RU1615.

    1 Чем отличается в команде ENEBLE_BILL_TYPES разрешенные купюры и купюры разрешенные для ESCROW;

    2 Почему при установки повышенного уровня защиты для типов купюр командой SET_SECURITY получаем ответ ACK.
    Т.е. команда выполнена, но при попытки прочитать эти данные командой GET_STATUS получаем, что у всех купюр обычный уровень защиты.

    На всякий случай вот полный лог обмена:

    [TBillValidatorAPI] Окрыт порт 1
    [TBillValidatorAPI] Отправка команды TBillValidatorAPICMD_GET_STATUS
    [TBillValidatorAPICMD_GET_STATUS] Создана команда TBillValidatorAPICMD_GET_STATUS <02 03 06 31 C8 A2>
    [TBillValidatorAPI] Получен первый блок <02 03 0B>
    [TBillValidatorAPI] Получен второй блок <00 00 00 00 00 00 A8 67>
    [TBillValidatorAPICMD_GET_STATUS] Парсинг ответа TBillValidatorAPICMD_GET_STATUS <02 03 0B 00 00 00 00 00 00 A8 67>
    [TBillValidatorAPI] Отправка команды TBillValidatorAPICMD_ACK
    [TBillValidatorAPI] ACK/NAK Timeout <200>

    >>> Здесь получили, что у купюрника не установлены биты повышенной защиты

    [TBillValidatorAPI] Отправка команды TBillValidatorAPICMD_SET_SECURITY
    [TBillValidatorAPICMD_SET_SECURITY] Создана команда TBillValidatorAPICMD_SET_SECURITY <02 03 09 32 80 00 FC 29 2E>
    [TBillValidatorAPI] Получен первый блок <02 03 06>
    [TBillValidatorAPI] Получен второй блок <00 C2 82>
    [TBillValidatorAPICMD_SET_SECURITY] Парсинг ответа TBillValidatorAPICMD_SET_SECURITY <02 03 06 00 C2 82>

    >>> Установли повышенную защиту для всех купюр кроме купонов.

    [TBillValidatorAPI] Отправка команды TBillValidatorAPICMD_GET_STATUS
    [TBillValidatorAPICMD_GET_STATUS] Создана команда TBillValidatorAPICMD_GET_STATUS <02 03 06 31 C8 A2>
    [TBillValidatorAPI] Получен первый блок <02 03 0B>
    [TBillValidatorAPI] Получен второй блок <00 00 00 00 00 00 A8 67>
    [TBillValidatorAPICMD_GET_STATUS] Парсинг ответа TBillValidatorAPICMD_GET_STATUS <02 03 0B 00 00 00 00 00 00 A8 67>
    [TBillValidatorAPI] Отправка команды TBillValidatorAPICMD_ACK
    [TBillValidatorAPI] ACK/NAK Timeout <200>

    >>> А здесь нам говорят, что нифига не установлено...

    Может я чего делаю не так???
  • Ravenlord (29.05.08 18:46) [45]
    Реализую независимый от Кешкодовской ДДЛки модуль работы с купюроприемником Cashckode. Тип протокола ID003.
    Возникла проблема при нахождении контрольной суммы пакета

    В тех. мануале описана функция нахождения СRC как P(x)=x^14+x^12+x^5+1… Вот только не понятно.. что такое X  в условии формата пакета [FCh][LNG][DATA Bytes][CRC]
  • Ravenlord (30.05.08 17:26) [46]
    После расспроса тех. поддержки - получил версию функции на С.
    Привожу вариант, адаптированный под Delphi

    var
    inter_crc_l:byte;
    inter_crc_h:byte;

    const polinom:integer = $8408;

    procedure calc_crc(b:byte)
    var
    i,c:byte;
    temp_crc:uint;
    begin
    inter_crc_l := inter_crc_l xor b;
    temp_crc := inter_crc_h;
    temp_crc := temp_crc shl 8;
    temp_crc := temp_crc or inter_crc_l;
    for i:=0 to 7 do begin
     c := temp_crc and $01;
     temp_crc := temp_crc shr 1;
     if c>0 then temp_crc := temp_crc xor polinom;
    end;
    inter_crc_h := temp_crc shr 8;
    inter_crc_l := temp_crc;
    end;
  • iVor © (07.06.08 15:14) [47]
    Работаю с купюроприемником CashCode Bill-to-Bill по протоколу CCNet, за основу взял опубликованный здесь исходник с потоками. Спасибо за него кстати. В благодарность готов поделиться решениями некоторых проблем, вставших в процессе разработки. На данный момент программа завершена на 90%. К сожалению, поделиться не могу, так как это коммерческий продукт.

    по поводу ЦРЦ - в мануале по протоколу, который выложен на сайте кэшкода, есть исходник на дельфи. работает 100%
  • Gbp (18.06.08 17:47) [48]
    Здравствуйте. Поделитесь пожалуйста dll'кой, которая испльзуется в коде на второй странице. Мне очень нужно быстро разобраться с купюроприемником, горит проект!
  • Gbp (18.06.08 17:48) [49]
    Она называется CashCodeSM.dll
  • Tonich (20.06.08 18:34) [50]
    не считаю себя профи конечно, но не дай бог воспользоваться кодом который приведен выше... ) ни синхронизации ни обработок ошибок ни черта ...  
    Выкачав  описание протокола, реализовал его за сутки.  правда на с++ под линукс, но это не так уж и важно..
  • tesseract © (20.06.08 18:42) [51]

    > не считаю себя профи конечно, но не дай бог воспользоваться
    > кодом который приведен выше... )


    Я видел какие люди этими автоматами разбираються, и изнутри их. С тех пор не пользуюсь, виснут примерно 2-3 раза в неделю  ( у нас который под боком). Сдачи не дают и тд. Система - явно хакнутая винда, до линухов мальчикам-мажорам котрые под него софт пишут, рости и рости.
  • Gbp (26.06.08 22:28) [52]
    Здравствуйте.
    Не подскажите ли, как можно уменьшить степень "требовательности"
    купюроприемника к качеству купюр?

    Я работаю с протоколом CCNET. Нужно использовать команду SET_STATUS?
    Не подскажите как ей пользоваться, какие передавать параметры, чтобы купюроприемник принимал бОльшее число купюр
  • Gbp (26.06.08 22:29) [53]
    Тьфу, то есть команду SET_SECURITY.
  • Tonich (27.06.08 12:57) [54]
    SYNC - 0x02
    ADR   - 0x03
    LNG   - 0x09
    CMD  - 0x32
    DATA - 3 байта в которых ответствующим образом выставленные биты (0x00 0x00 0x00)
    CRC   -  

    то есть там всего 24 канала(у устройства) и выставляя биты в DATA соответствующим образом в этих 3 байтах ты скажешь указать какой канал проверять с high security level а какой нет

    то есть в твоем случаи опусти все биты

    после этого устройство должно ответить ..
  • Gbp (28.06.08 14:36) [55]
    Спасибо большое за информацию.
    А CRC нужно рассчитывать?
  • Gbp (28.06.08 14:46) [56]
    Если нужно, то как его считать?
  • Gbp (30.06.08 10:40) [57]
    все, нашел код

    const _CR_CCNET_CRC_POLY = $08408

    function GetCRC16(InData: array of byte; DataLng: word): word;
    var i,TmpCRC: word;
       j: byte;
    begin
    result:=0;
    for i:=0 to (DataLng-1) do
    begin
     TmpCRC:=result xor InData[i];
     for j:=0 to 7 do
      begin
       if (TmpCRC and $0001)<>0 then
        begin
         TmpCRC:=TmpCRC shr 1;
         TmpCRC:=TmpCRC xor _CR_CCNET_CRC_POLY;
        end
            else
        TmpCRC:=TmpCRC shr 1;
      end;
     result:=TmpCRC;
    end;
    end;
  • имя (15.07.08 20:31) [58]
    Удалено модератором
  • имя (15.07.08 23:22) [59]
    Удалено модератором
  • имя (23.07.08 19:05) [60]
    Удалено модератором
  • tesseract © (23.07.08 20:37) [61]
    Удалено модератором
  • antoxa (03.08.08 14:36) [62]
    А можно исходничек на annews@mail.primorye.ru ?
  • Мистер М (12.09.08 12:55) [63]
    TO Darth Avenger
    А можно и мне исходник? reid@tut.by
    Или просто последовательность сообщений, которой можно инициализировать хоть какой-то режим работы CashCode.
    Заранее благодарен!
  • thoth (19.11.08 19:20) [64]
    Алекс_ТК
    спасибо за рабочий код. выручили.
  • имя (09.01.09 01:24) [65]
    Удалено модератором
  • имя (09.01.09 01:25) [66]
    Удалено модератором
  • имя (07.02.09 19:22) [67]
    Удалено модератором
 
Конференция "WinAPI" » Купюроприемник CashCode, протокол ccnet [D7, WinXP]
Есть новые Нет новых   [118456   +4][b:0.001][p:0.002]