Az ADDI-DATA gyártmányú APCI-1500 Digitális Input/Output vezérlőkártya programozása

 

         Engem nagyon érdekel többek között a hobbielektronika is, melyet már 18 éves korom óta kisebb nagyobb intenzitással művelek. Főleg erősítők, egyszerű rádióvevők megépítésben vannak hasznosítható tapasztalataim. Már a mikroszámítógépekkel kapcsolatban is érdekelt a gépnek és a külvilágnak hardveres kapcsolata, a valós idejű vezérlések és szabályozások megvalósítása számítógépekkel.

 

         Nemrég sikerült hozzájutnom egy, a címben említett vezérlőkártyához és a hozzá csatlakoztatható PX 901-DG LED kijelzős kapcsolati panelhez, melyen a vezetékek kapcsolódását csavarokkal oldották meg. A vezérlőkártya és a panel kapcsolatát egy 37 eres párhuzamos adatkábel biztosítja.

 

         Az APCI-1500 vezérlőkártya:

 

 

         Az adatkábel:

 

 

         A PX 901-DG panel (beépítve):

 

 

A rendszer fizikai paraméterei megtalálhatók például a http://www.teampctechnology.com/product_files/22_specpdf.pdf állományban.

 

A rendszer megépítéséhez szükség volt még:

- egy darab bútorlapra (a részek mechanikai rögzítése végett),

- három különböző méretű előlyukasztott, fóliázott szerelőlapra,

- 17 db kétállású kapcsolóra a bemenetekhez illetve a részek közötti átváltáshoz,

- két nyomógombra (start-stop funkció miatt),

- egy táp csatlakozóra,

- 4 db relére a léptetőmotor vezérléséhez,

- egy léptetőmotorra (floppy meghajtóból kiszerelve),

- 49 db különböző színű LED-re,

- 16 db 2,2 K ellenállásra (a LED-ek védelméhez),

- egy 16 V-os egyenfeszültségű tápegységre a panelhez (egy Laptop tápja volt),

- egy 5 V-os egyenfeszültségű tápegységre (a léptetőmotor működtetéséhez),

- 45 db huzalvég hüvelyre,

- 4-5 méter milliméteres, szigetelt vezetékre (meghibásodott PC tápegységből).

 

         A rendszer kínálta funkciókkal folyamatosan ismerkedtem meg. Elsőként a Digitális Input érdekelt. Ehhez egy próbapanelen 16 kapcsolót helyeztem el összekötve a DG panel Dig Input 1 – Dig Input 16 csatlakozási pontjával. A kapcsoló állásától függően a bemenetekre 0 vagy 16 V jutott. A 16 Digitális Inputot a képernyőre grafikusan leképeztem (fekete körök, illetve píros színnel feltöltött körök formájában, a panelen lévő LED-eknek megfelelően). A kapcsolókat ki-be kapcsolva a képernyőn is megjelenik a Digitális bemenet.

 

A demonstrációs program formja szerkesztő nézetben:

 

 

         A futási kép a 2., 4., 8., 9. és 12. bit (kapcsoló) bekapcsolásakor (természetesen a panelen a nekik megfelelő LED-ek is világítanak):

 

 

         A következő fázisban a kimenetet jelenítettem meg. Egy szerkesztőmezőbe beírhatjuk a kiküldendő számot decimális alakban. A program átváltja, a számot kettes számrendszerbe, és a panel Output részén a megfelelő feszültségek megjelennek, és a kontrolldiódák világítanak. Ugyanúgy ahogyan a képernyőn is a nekik megfelelő körök piros színűek lesznek. A kimenetet arra használtam még fel ebben a szakaszban, hogy 1-től indulva, a szerkesztő mezőben megadott értékig számoltattam a gépet, s közben folyamatosan megjelenítettem a kimeneten a neki megfelelő Output-ot. A futási kép megjelenített Output esetén:

 

 

         A következő lépésben számjegykijelző LED-mátrix működtetését tűztem ki célul. Először egy 3*5-ös mátrixban, melyet csak szoftveresen hoztam létre. Az alacsony számú dióda miatt nem lett volna elég élethű, főleg a 6-os, 8-as és 9-es számok felismerése nehézkes. A programban ez a szakasz is benne maradt. Mivel ezek is kimenetként jelentkeznek, az Output területen láthatjuk a megfelelő digitális LED kiosztást. A számlálás a Start feliratú nyomógombbal indítható. Nézzünk erről is egy futási képet:

 

 

         A következő számkijelző már 5*7 diódát tartalmaz. Ezen a mátrixon megjeleníteni decimális számot már nem olyan egyszerű, mint a 3*5 mátrixon. Mivel 3*5<16, egyszerű volt megmondani, hogy mely diódák világítsanak a látvány eléréséhez. Itt viszont 35 diódánk van, nem lehet mindegyikhez egy-egy bitet rendelni, mert csak 16 bitünk van. Külön Pascalban írt programmal terveztem meg a 35 dióda bekapcsolási rendszerét. Először rajzolgattam a pontmátrixokat, majd kiválasztottam az ugyanolyan működésűeket (minden számnál ugyanúgy be volt kapcsolva illetve nem). A cél az volt, hogy maximum 17 csoportot alakítsak ki. Az első 16-hoz logikailag egy-egy bit tartozott, ezekbe a csoportokba tartozó diódáknak a lábait össze kellett kötni (természetesen az egyik-egyiket, minden dióda negatív pólusát ugyanis eleve közös földre kellett kötni). A 17. csoportba azok a diódák tartoztak, melyek nem vettek részt egyetlen szám a megjelenítésében sem (azért a látvány kedvéért beforrasztottam a panelre őket is). Az animáció a Számláló start feliratú nyomógombbal indítható. A futási kép 3-nál:

 

 

         A következő már egyszerűbben megoldható feladat volt. Kedvenc témám a közúti útkereszteződés lámparendszere. Készítettem rá több programot is. Most a gyakorlati megvalósításhoz közeli feladattal találtam szembe magam. Azért, hogy a 16 bit elég legyen a vezérléshez, 4*3 lámpát használtam a gépjárműforgalom és 1*2 lámpát a gyalogos forgalom irányításához. A gyalogosoknak a lámpája az útkereszteződés közepén van, és bármely irányba mehetnek zöld jelzése esetén. A lámparendszer működését a Jelzőlámpa start feliratú nyomógombbal indíthatjuk el. A futási kép akkor, amikor a dél felől érkezőknek a lámpája piros-sárgát mutat:

 

 

         A program utolsó részében egy léptetőmotor vezérlésére került sor. A rendszerbe egy floppy meghajtóból származó, 5 V-os léptetőmotort építettem be. Ennek a léptetőmotornak négy pólusa van. A négy pólusra a következő sorrendben kell adni a feszültségeket:

 

Pólus/fázis

1. fázis

2. fázis

3. fázis

4. fázis

1

0

 

+5 V

 

2

+5 V

 

0

 

3

 

0

 

+5 V

4

 

+5 V

 

0

 

         A feszültségek kapcsolgatását négy darab kettős relével oldottam meg. Ha ellenkező irányba szeretnénk indítani a motort, akkor a cserélgetést fordított sorrendben kell végrehajtani. A motor polaritás-függő működését a benne található állandó mágnesek biztosítják. A forgásirányt kísérleti úton kell megállapítani. A léptetőmotor a tekercsek számától függően, egy impulzusra, csak egy következő stabil állapotába kerül. Az impulzusok számolásával a léptetőmotor helyzete vezérelhető. A programban külön található nyomógomb a jobbra illetve a balra forgatásra. Egy szerkesztő mezőbe írt értékkel a motornak a forgási sebességét változtathatjuk.

 

         Az 5*7-es számkijelző mátrix bekötését megadó bitmátrix meghatározását végző Pascal program listája:

 

Program Szegm5X7;
Uses NewDelay, Crt, CrtPlus;
Type TT= Array[0..10] Of Byte;
Var S: Array[0..9] Of String;
    K: Array[1..5,1..7] Of TT;
    O: Array[1..5,1..7] Of Byte;
    R: Array[1..35,1..2] Of String;
    I, J, L, M, N: Byte;
    Uj: Boolean;
    Ws: String;

Function Egyenlo(A,B: Byte): Boolean;
Var J: Byte;
    Igen: Boolean;
Begin
  Igen:= True;
  For J:= 0 To 9 Do
  If K[((A-1) Mod 5)+1,((A-1) Div 5)+1][J]<>
     K[((B-1) Mod 5)+1,((B-1) Div 5)+1][J] Then Igen:= False;
  Egyenlo:= Igen;
End;

Begin
  Szinek(1,15); ClrScr;

  S[0]:= '.000.'+
         '0...0'+
         '0...0'+
         '0...0'+
         '0...0'+
         '0...0'+
         '.000.';

  S[1]:= '....0'+
         '...00'+
         '..0.0'+
         '.0..0'+
         '....0'+
         '....0'+
         '....0';

  S[2]:= '.000.'+
         '0...0'+
         '...0.'+
         '..0..'+
         '.0...'+
         '0....'+
         '00000';

  S[3]:= '.000.'+
         '0...0'+
         '....0'+
         '..00.'+
         '....0'+
         '0...0'+
         '.000.';

  S[4]:= '....0'+
         '...0.'+
         '..0..'+
         '.0000'+
         '....0'+
         '....0'+
         '....0';

  S[5]:= '.0000'+
         '0....'+
         '0....'+
         '0000.'+
         '....0'+
         '0...0'+
         '.000.';

  S[6]:= '.000.'+
         '0...0'+
         '0....'+
         '0000.'+
         '0...0'+
         '0...0'+
         '.000.';

  S[7]:= '.0000'+
         '....0'+
         '...0.'+
         '..0..'+
         '.0...'+
         '0....'+
         '0....';

  S[8]:= '.000.'+
         '0...0'+
         '0...0'+
         '.000.'+
         '0...0'+
         '0...0'+
         '.000.';

  S[9]:= '.000.'+
         '0...0'+
         '0...0'+
         '.0000'+
         '....0'+
         '0...0'+
         '.000.';

  {számok kiírása}
  For L:= 0 To 9 Do For I:= 1 To 35 Do If S[L][I]='0' Then
  Begin
    WriteXY(((I-1) Mod 5)+2+8*L,((I-1) Div 5)+1,S[L][I]);
    Inc(O[((I-1) Mod 5)+1,((I-1) Div 5)+1]);
  End;

  {a bitmátrix előállítása, rendezése és kiírása}
  WriteLn; WriteLn;
  For M:= 0 To 9 Do For I:= 1 To 35 Do
  Begin
    If S[M][I]='.' Then
    K[((I-1) Mod 5)+1,((I-1) Div 5)+1][M]:= 0 Else
    K[((I-1) Mod 5)+1,((I-1) Div 5)+1][M]:= 1;
    K[((I-1) Mod 5)+1,((I-1) Div 5)+1][10]:= I;
  End;
  For I:= 1 To 35 Do
  Begin
    For J:= 0 To 9 Do
    Begin
      Str(K[((I-1) Mod 5)+1,((I-1) Div 5)+1][J],Ws);
      R[I,1]:= R[I,1]+Ws;
    End;
    Str(K[((I-1) Mod 5)+1,((I-1) Div 5)+1][10],Ws);
    R[I,2]:= Ws;
  End;

  For I:= 1 To 34 Do For J:= I+1 To 35 Do If R[I,1]>R[J,1] Then
  Begin
    Ws:= R[I,1]; R[I,1]:= R[J,1]; R[J,1]:= Ws;
    Ws:= R[I,2]; R[I,2]:= R[J,2]; R[J,2]:= Ws;
  End;
  For I:= 1 To 35 Do
  WriteLn(R[I,1],' ',R[I,2]);

  {az újak összeszámlálása és kiírása}
  N:= 0;
  For I:= 1 To 35 Do If O[((I-1) Mod 5)+1,((I-1) Div 5)+1]>0 Then
  Begin
    Uj:= True; For L:= 1 To I-1 Do If Egyenlo(I,L) Then Uj:= False;
    If Uj Then Inc(N);
  End;

 
 WriteLn; WriteLn(N);

  Tunj; Varj;

End.

 

         A rendszer Delphi programjának listája (mely természetesen csak az APCI-1500 kártyával és a hozzávaló DLL-el működik):

 

unit UADemo;

interface

uses
  Windows, Messages, SysUtils, Classes,

  Graphics, Controls, Forms, Dialogs, APCI1500,
  StdCtrls, ExtCtrls, ComCtrls;

type
  TfmADemo = class(TForm)
    lbInput: TLabel;
    lbOutput: TLabel;
    btKilep: TButton;
    edOKi: TEdit;
    btOKi: TButton;
    tmIdozito: TTimer;
    btSzamol: TButton;
    btTorol: TButton;
    lbSzam: TLabel;
    btStartSz: TButton;
    btStartUt: TButton;
    btStartM: TButton;
    btStartMotorJobb: TButton;
    edSeb: TEdit;
    btMotorStartBal: TButton;
    btBreak: TButton;
    Procedure IAlap;
    Procedure OAlap;
    Procedure SAlap;
    Procedure MAlap;
    Procedure UALap;
    Procedure ISet(S: Word);
    Procedure OSet(S: Word);
    Procedure SSet(S: String);
    Procedure MSet(S: String);
    Procedure USet(S: String);
    Function Konv(S: String): String;
    Procedure Ki(S: String);
    Procedure SSleep(S: Longint);
    function i_Initialisation(Var b_BoardHandle : Byte):Integer;
    procedure FormPaint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure btKilepClick(Sender: TObject);
    procedure btOKiClick(Sender: TObject);
    procedure tmIdozitoTimer(Sender: TObject);
    procedure btSzamolClick(Sender: TObject);
    procedure btTorolClick(Sender: TObject);
    procedure btStartSzClick(Sender: TObject);
    procedure btStartUtClick(Sender: TObject);
    procedure btStartMClick(Sender: TObject);
    procedure btStartMotorJobbClick(Sender: TObject);
    procedure btMotorStartBalClick(Sender: TObject);
    procedure btBreakClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var fmADemo: TfmADemo;

    i_ReturnValue: Integer;
    b_InitialisationOk: Boolean;
    b_BoardHandle: Byte;
    All, Vege: Boolean;
    Varj: Word;

Const IX=20;
      IY=80;
      OX=370;
      OY=80;
      R=10;
      Dx=20;
      Dy=30;
      SF=25;
      SL=15;
      Ko=5;
      Ss=500;
      SX=40;
      SY=200;
      SDx=20;
      SDy=20;
      MX=40;
      MY=400;
      MDx=20;
      MDy=20;

//a jelzőlámparendszer lámpáinak képernyőhelyei:

Const H: Array[1..14,1..2] Of Word= ((400,240),(400,220),(400,200),
                                     (440,280),(460,280),(480,280),
                                     (400,320),(400,340),(400,360),
                                     (360,280),(340,280),(320,280),
                                     (400,270),(400,290));

implementation

{$R *.DFM}

Function BinarisRev(S: Word): String;
Var Ws, W: String;
    B: Word;
    I: Word;
Begin
  //szám konvertálása fordított bináris stringgé (legnagyobb helyiérték a 16.)
  Ws:='';
  B:=$8000;
  While B<>0 Do
  Begin
    If B And S=0 Then Ws:=Ws+'0' Else Ws:=Ws+'1';
    B := B Shr 1;
  End;
  W:= ''; For I:= 16 DownTo 1 Do W:= W+Ws[I]; BinarisRev:= W;
End;

Function Binaris(S: Word): String;
Var Ws: String;
    B: Word;
Begin
  //szám konvertálása bináris stringgé
  Ws:='';
  B:=$8000;
  While B<>0 Do
  Begin
    If B And S=0 Then Ws:=Ws+'0' Else Ws:=Ws+'1';
    B := B Shr 1;
  End;
  Binaris:= Ws;
End;

Function Decimalis(S: String): Word;
Var I, N, H: Word;
    Ws: String;
Begin
  //bináris string konvertálása decimálissá
  Ws:= '0000000000000000'+S;
  N:= Length(WS);
  Ws:= Copy(Ws,N-15,16);
  N:= 0; H:= 1;
  For I:= 16 DownTo 1 Do
  Begin
    N:= N+StrToInt(Ws[I])*H;
    H:= 2*H;
  End;
  Decimalis:= N;
End;

Procedure TfmADemo.IAlap;
Var I: Word;
Begin
  //Input bitek körökkel
  With Canvas Do
  Begin
    Pen.Color:= clBlack;
    Brush.Color:= clBtnFace;
    For I:= 1 To 16 Do If Odd(I) Then
    Begin
      Ellipse(IX+Dx*I-R,IY-R,IX+Dx*I+R,IY+R);
      TextOut(IX+Dx*I-Ko,IY-SF,IntToStr(I));
    End
    Else
    Begin
      Ellipse(IX+Dx*I-R,IY+Dy-R,IX+Dx*I+R,IY+Dy+R);
      TextOut(IX+Dx*I-Ko,IY+Dy+SL,IntToStr(I));
    End;
  End;
End;

Procedure TfmADemo.OAlap;
Var I: Word;
Begin
  //Output bitek körökkel
  With Canvas Do
  Begin
    Pen.Color:= clBlack;
    Brush.Color:= clBtnFace;
    For I:= 1 To 16 Do If Odd(I) Then
    Begin
      Ellipse(OX+Dx*I-R,OY-R,OX+Dx*I+R,OY+R);
      TextOut(OX+Dx*I-Ko,OY-SF,IntToStr(I));
    End
    Else
    Begin

      Ellipse(OX+Dx*I-R,OY+Dy-R,OX+Dx*I+R,OY+Dy+R);
      TextOut(OX+Dx*I-Ko,OY+Dy+SL,IntToStr(I));
    End;
  End;
End;

Procedure TfmADemo.SAlap;
Var I: Word;
Begin
  //3*5 számkijelző
  With Canvas Do
  Begin
    Pen.Color:= clBlack;
    Brush.Color:= clBtnFace;
    For I:= 1 To 15 Do
    Ellipse(Sx+SDx*((I-1) Mod 3)-R,
            SY+SDy*((I-1) Div 3)-R,
            SX+SDx*((I-1) Mod 3)+R,
            SY+SDy*((I-1) Div 3)+R);
  End;
End;

Procedure TfmADemo.MAlap;
Var I: Word;
Begin
  //5*7 számkijelző
  With Canvas Do
  Begin
    Pen.Color:= clBlack;
    Brush.Color:= clBtnFace;
    For I:= 1 To 35 Do
    Ellipse(Mx+MDx*((I-1) Mod 5)-R,
            MY+MDy*((I-1) Div 5)-R,
            MX+MDx*((I-1) Mod 5)+R,
            MY+MDy*((I-1) Div 5)+R);
  End;
End;

Procedure TfmADemo.UAlap;
Var I: Word;
Begin
  //jelzőlámpa
  With Canvas Do
  Begin
    Pen.Color:= clBlack;
    Brush.Color:= clBtnFace;
    For I:= 1 To 14 Do
    Ellipse(H[I,1]-R,H[I,2]-R,H[I,1]+R,H[I,2]+R);
  End;
End;

Procedure TfmADemo.ISet(S: Word);
Var I: Word;
    Ws: String;
Begin
  //input beállítása
  Ws:= BinarisRev(S);
  With Canvas Do
  Begin
    Pen.Color:= clBlack;
    For I:= 1 To 16 Do
    Begin
      If Ws[I]='0' Then Brush.Color:= clBtnFace Else
      Brush.Color:= clRed;
      If Odd(I) Then
      Ellipse(IX+Dx*I-R,IY-R,IX+Dx*I+R,IY+R) Else
      Ellipse(IX+Dx*I-R,IY+Dy-R,IX+Dx*I+R,IY+Dy+R);
    End;
  End;
End;

Procedure TfmADemo.OSet(S: Word);
Var I: Word;
    Ws: String;
Begin
  //output beállítása
  Ws:= BinarisRev(S);
  With Canvas Do
  Begin
    Pen.Color:= clBlack;
    For I:= 1 To 16 Do
    Begin
      If Ws[I]='0' Then Brush.Color:= clBtnFace Else Brush.Color:= clRed;
      If Odd(I) Then Ellipse(OX+Dx*I-R,OY-R,OX+Dx*I+R,OY+R) Else
      Ellipse(OX+Dx*I-R,OY+Dy-R,OX+Dx*I+R,OY+Dy+R);
    End;
  End;
End;

Procedure TfmADemo.SSet(S: String);
Var I: Word;
Begin
  //3*5 számkijelző beállítása
  With Canvas Do
  Begin
    Pen.Color:= clBlack;
    For I:= 1 To 15 Do
    Begin
      If S[I]='0' Then Brush.Color:= clBtnFace Else
      Brush.Color:= clRed;
      Ellipse(Sx+SDx*((I-1) Mod 3)-R,
              SY+SDy*((I-1) Div 3)-R,
              SX+SDx*((I-1) Mod 3)+R,
              SY+SDy*((I-1) Div 3)+R);
    End;
  End;
End;

Procedure TfmADemo.MSet(S: String);
Var I: Word;
Begin
  //5*7 számkijelző beállítása
  With Canvas Do
  Begin
    Pen.Color:= clBlack;
    For I:= 1 To 35 Do
    Begin
      If S[I]='0' Then Brush.Color:= clBtnFace Else
      Brush.Color:= clRed;
      Ellipse(Mx+MDx*((I-1) Mod 5)-R,
              MY+MDy*((I-1) Div 5)-R,
              MX+MDx*((I-1) Mod 5)+R,
              MY+MDy*((I-1) Div 5)+R);
    End;
  End;
End;

Procedure TfmADemo.USet(S: String);
Var I: Word;
Begin
  //jelzőlámpa beállítása
  With Canvas Do
  Begin
    Pen.Color:= clBlack;
    For I:= 1 To 14 Do
    Begin
      If S[I]='0' Then Brush.Color:= clBtnFace Else
      Case I Of
        1,4,7,10,13: Brush.Color:= clRed;
           2,5,8,11: Brush.Color:= clYellow;
        3,6,9,12,14: Brush.Color:= clGreen;
      End;
      Ellipse(H[I,1]-R,H[I,2]-R,H[I,1]+R,H[I,2]+R);
    End;
  End;
End;

Procedure TfmADemo.SSleep(S: Longint);
Var Sender: TObject;
Begin
  //saját várakozás
  Sleep(S); Sender:= Nil; tmIdozitoTimer(Sender);
End;

function TfmADemo.i_Initialisation(Var b_BoardHandle : Byte):Integer;
Var b_SlotNumberArray : Array[0..7] Of Byte;
    w_BaseAddress     : Word;
    b_InterruptNbr    : Byte;
    b_SlotNumber      : Byte;
Begin
  //a kártya standard inicializálása
  i_ReturnValue:= i_APCI1500_InitCompiler(DLL_COMPILER_PASCAL);
  If i_ReturnValue=0 Then
  Begin
    i_ReturnValue:=
    i_APCI1500_CheckAndGetPCISlotNumber (b_SlotNumberArray [0]);
    If i_ReturnValue>0 Then
    i_ReturnValue:= i_APCI1500_SetBoardInformation(b_SlotNumberArray [0],
                                                   b_BoardHandle);
  End;
  If i_ReturnValue=0 Then
  i_ReturnValue:= i_APCI1500_GetHardwareInformation (b_BoardHandle,
                                                     w_BaseAddress,
                                                     b_InterruptNbr,
                                                     b_SlotNumber);
  i_Initialisation:= i_ReturnValue;
End;

procedure TfmADemo.FormPaint(Sender: TObject);
begin
  //az alap képernyő megrajzolása
  IAlap;
  OAlap;
  SAlap;
  MAlap;
  UAlap;
end;

procedure TfmADemo.FormCreate(Sender: TObject);
begin
  //a kártya indítása
  b_InitialisationOk:= False;
  i_ReturnValue:= i_Initialisation (b_BoardHandle);
  If i_ReturnValue=0 Then b_InitialisationOk:= True;
  All:= True; Vege:= False;
end;

procedure TfmADemo.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  //ha működött a kártya, akkor felkészítés a leállításra
  If b_InitialisationOk=True Then
  Begin
    i_ReturnValue:= i_APCI1500_SetOutputMemoryOff(b_BoardHandle);
    i_ReturnValue:= i_APCI1500_CloseBoardHandle(b_BoardHandle);
  End;
end;

procedure TfmADemo.btKilepClick(Sender: TObject);
begin
  //a kártya leállítása
  i_ReturnValue:= i_APCI1500_SetOutputMemoryOn(b_BoardHandle);
  if i_ReturnValue=0 Then
  i_ReturnValue:= i_APCI1500_Set16DigitalOutputOn(b_BoardHandle,0);
  Close;
end;

procedure TfmADemo.btOKiClick(Sender: TObject);
begin
  //16 digit kiadása az outputra
  i_ReturnValue:= i_APCI1500_SetOutputMemoryOn(b_BoardHandle);
  if i_ReturnValue=0 Then
  Begin
    i_ReturnValue:= i_APCI1500_Set16DigitalOutputOn(b_BoardHandle,
                                                    StrToInt(edOKi.Text));
    OSet(StrToInt(edOKi.Text));
  End;
end;

procedure TfmADemo.btSzamolClick(Sender: TObject);
Var I: Word;
begin
  //számolás egyesével a megadott értékig és outputra küldés
  lbSzam.Caption:= edOKI.Text+'-ig'; lbSzam.Repaint;
  For I:= 0 To StrToInt(edOKi.Text) Do
  Begin
    i_ReturnValue:= i_APCI1500_SetOutputMemoryOn(b_BoardHandle);
    if i_ReturnValue=0 Then
    Begin
      i_ReturnValue:= i_APCI1500_Set16DigitalOutputOn(b_BoardHandle, 0);
      i_ReturnValue:= i_APCI1500_Set16DigitalOutputOn(b_BoardHandle, I);
      OSet(I);
      edOKI.Text:= IntToStr(I); edOKI.Repaint;
      SSleep(Ss);
    End;
  End;
end;

procedure TfmADemo.tmIdozitoTimer(Sender: TObject);
Var InputValue: LongInt;
begin
  i_ReturnValue:= i_APCI1500_Read16DigitalInput(b_BoardHandle, InputValue);
  ISet(InputValue);
  //a 15. és 16. inputbit figyelése (Start, Stop nyomógombok)
  If All Then If Binaris(InputValue)[2]='1' Then btStartMClick(Sender);
  If Not All Then If Binaris(InputValue)[1]='1' Then Vege:= True;
end;

procedure TfmADemo.btTorolClick(Sender: TObject);
begin
  //output törlése
  i_ReturnValue:= i_APCI1500_SetOutputMemoryOn(b_BoardHandle);
  if i_ReturnValue=0 Then
  i_ReturnValue:= i_APCI1500_Set16DigitalOutputOn(b_BoardHandle, 0);
  OSet(0);
  edOKi.Text:= '0';
  lbSzam.Caption:= '0';
end;

procedure TfmADemo.btStartSzClick(Sender: TObject);
begin
   //3*5 számláló
            SSet('010101101101010');
  OSet(Decimalis('010101101101010')); SSleep(1000);  //0

            SSet('001011101001001');
  OSet(Decimalis('001011101001001')); SSleep(1000);  //1

            SSet('010101001010111');
  OSet(Decimalis('010101001010111')); SSleep(1000);  //2

            SSet('110001010001110');
  OSet(Decimalis('110001010001110')); SSleep(1000);  //3

            SSet('100100111001001');
  OSet(Decimalis('100100111001001')); SSleep(1000);  //4

            SSet('111100110001110');
  OSet(Decimalis('111100110001110')); SSleep(1000);  //5

            SSet('011100110101010');
  OSet(Decimalis('011100110101010')); SSleep(1000);  //6

            SSet('111001010100100');
  OSet(Decimalis('111001010100100')); SSleep(1000);  //7

            SSet('010101010101010');
  OSet(Decimalis('010101010101010')); SSleep(1000);  //8

            SSet('010101011001110');
  OSet(Decimalis('010101011001110')); SSleep(1000);  //9
  SSet('000000000000000');                          //törlés
  OSet(0);
end;

Procedure TfmADemo.Ki(S: String);
Begin
  //a digitális kimenet beállítása
  i_ReturnValue:= i_APCI1500_SetOutputMemoryOn(b_BoardHandle);
  if i_ReturnValue=0 Then
  Begin
    i_ReturnValue:= i_APCI1500_Set16DigitalOutputOn(b_BoardHandle, 0);
    i_ReturnValue:= i_APCI1500_Set16DigitalOutputOn(b_BoardHandle,
                               Decimalis(S));
  End;
End;

Function TfmADemo.Konv(S: String): String;
Var I: Word;
    Ws: String;
Begin
  //5*7 kijelző diódáinak lábkiosztása
  Ws:= '0000000000000000';
  For I:= 1 To 35 Do If S[I]='1' Then
  Case I Of
         2,3,4,26: Ws[16]:= '1';
                5: Ws[15]:= '1';
       6,32,33,34: Ws[14]:= '1';
             9,13: Ws[13]:= '1';
               10: Ws[12]:= '1';
               11: Ws[11]:= '1';
         14,22,31: Ws[10]:= '1';
               15: Ws[ 9]:= '1';
               16: Ws[ 8]:= '1';
               17: Ws[ 7]:= '1';
               18: Ws[ 6]:= '1';
               19: Ws[ 5]:= '1';
               20: Ws[ 4]:= '1';
               21: Ws[ 3]:= '1';
            25,30: Ws[ 2]:= '1';
               35: Ws[ 1]:= '1';
  End;
  Konv:= Ws;
End;

procedure TfmADemo.btStartMClick(Sender: TObject);
Var I: Byte;
  Procedure Kiad(Ws: String);
  Begin
    MSet(Ws); OSet(Decimalis(Konv(Ws))); Ki(Konv(Ws)); SSleep(800);
  End;
begin
  //5*7 számoltatás
  Vege:= False; All:= False;
  For I:= 1 To 2 Do
  Begin
    Kiad('01110100011000110001100011000101110'); If Vege Then Break;
    Kiad('00001000110010100001000010000100001'); If Vege Then Break;
    Kiad('01110100010001000100010001000011111'); If Vege Then Break;
    Kiad('01110100010000100110000011000101110'); If Vege Then Break;
    Kiad('00001000100010001111000010000100001'); If Vege Then Break;
    Kiad('01111100001000011110000011000101110'); If Vege Then Break;
    Kiad('01110100011000011110100011000101110'); If Vege Then Break;
    Kiad('01111000010001000100010001000010000'); If Vege Then Break;
    Kiad('01110100011000101110100011000101110'); If Vege Then Break;
    Kiad('01110100011000101111000011000101110'); If Vege Then Break;
    Kiad('00000000000000000000000000000000000'); If Vege Then Break;
  End;
  All:= True;
end;

procedure TfmADemo.btStartUtClick(Sender: TObject);
Var I: Word;
  Function Ford(S: String): String;
  Var K: Word;
      Ws: String;
  Begin
    //string megfordítása
    Ws:= ''; For K:= Length(S) DownTo 1 Do Ws:= Ws+S[k]; Ford:= Ws
  End;
begin
  //jelzőlámpák működtetése
  For I:= 1 To 2 Do
  Begin
              USet('10010010010010');
    OSet(Decimalis('10010010010010'));
           Ki(Ford('10010010010010')); SSleep(300); //mind piros

              USet('11010010010010');
    OSet(Decimalis('11010010010010'));
           Ki(Ford('11010010010010')); SSleep(300); //1ps

              USet('00110010010010');
    OSet(Decimalis('00110010010010'));
           Ki(Ford('00110010010010')); SSleep(2000); //1z

              USet('01010010010010');
    OSet(Decimalis('01010010010010'));
           Ki(Ford('01010010010010')); SSleep(300); //1s

              USet('10010010010010');
    OSet(Decimalis('10010010010010'));
           Ki(Ford('10010010010010')); SSleep(300); //1p

              USet('10011010010010');
    OSet(Decimalis('10011010010010'));
           Ki(Ford('10011010010010')); SSleep(300);   //2ps

              USet('10000110010010');
    OSet(Decimalis('10000110010010'));
           Ki(Ford('10000110010010')); SSleep(2000);  //2z

              USet('10001010010010');
    OSet(Decimalis('10001010010010'));
           Ki(Ford('10001010010010')); SSleep(300);   //2s

              USet('10010010010010');
    OSet(Decimalis('10010010010010'));
           Ki(Ford('10010010010010')); SSleep(300);   //2p

              USet('10010011010010');
    OSet(Decimalis('10010011010010'));
           Ki(Ford('10010011010010')); SSleep(300);   //3ps     

              USet('10010000110010');
    OSet(Decimalis('10010000110010'));
           Ki(Ford('10010000110010')); SSleep(2000);  //3z

              USet('10010001010010');
    OSet(Decimalis('10010001010010'));
           Ki(Ford('10010001010010')); SSleep(300);   //3s

              USet('10010010010010');
    OSet(Decimalis('10010010010010'));
           Ki(Ford('10010010010010')); SSleep(300);   //3p

              USet('10010010011010');
    OSet(Decimalis('10010010011010'));
           Ki(Ford('10010010011010')); SSleep(300);   //4ps

              USet('10010010000110');
    OSet(Decimalis('10010010000110'));
           Ki(Ford('10010010000110')); SSleep(2000);  //4z

              USet('10010010001010');
    OSet(Decimalis('10010010001010'));
           Ki(Ford('10010010001010')); SSleep(300);   //4s

              USet('10010010010010');
    OSet(Decimalis('10010010010010'));
           Ki(Ford('10010010010010')); SSleep(300);   //4p

              USet('10010010010001');
    OSet(Decimalis('10010010010001'));
           Ki(Ford('10010010010001')); SSleep(2000);   //5z

              USet('10010010010010');
    OSet(Decimalis('10010010010010'));
           Ki(Ford('10010010010010')); SSleep(300);   //5p
  End;
  USet('00000000000000');
  OSet(0);
  Ki(Ford('0000000000000'));
end;

procedure TfmADemo.btStartMotorJobbClick(Sender: TObject);
Var I: Word;
    V: Word;
    T: Word;
begin
  Vege:= False; All:= False; V:= StrToInt(edSeb.Text); V:= 500-V; T:= 30;
  For I:= 1 to 30 Do
  Begin
    Ki('0100000000000000'); SSleep(T); Ki('0000000000000000');
    SSleep(V); If Vege Then Break;
    Ki('0001000000000000'); SSleep(T); Ki('0000000000000000');
    SSleep(V); If Vege Then Break;
    Ki('0000010000000000'); SSleep(T); Ki('0000000000000000');
    SSleep(V); If Vege Then Break;
    Ki('0000000100000000'); SSleep(T); Ki('0000000000000000');
    SSleep(V); If Vege Then Break;
  End;
  All:= True;
  Ki('0000000000000000')
end;

procedure TfmADemo.btMotorStartBalClick(Sender: TObject);
Var I: Word;
    V: Word;
    T: Word;
begin
  Vege:= False; All:= False; V:= StrToInt(edSeb.Text); V:= 500-V; T:= 30;
  For I:= 1 to 10 Do
  Begin
    Ki('0000000100000000'); SSleep(T); Ki('0000000000000000');
    SSleep(V); If Vege Then Break;
    Ki('0000010000000000'); SSleep(T); Ki('0000000000000000');
    SSleep(V); If Vege Then Break;
    Ki('0001000000000000'); SSleep(T); Ki('0000000000000000');
    SSleep(V); If Vege Then Break;
    Ki('0100000000000000'); SSleep(T); Ki('0000000000000000');
    SSleep(V); If Vege Then Break;
  End;
  All:= True;
  Ki('0000000000000000')
end;

procedure TfmADemo.btBreakClick(Sender: TObject);
begin
   Vege:= True;
end;

end.


{Led-kiosztás:
 0: 1,7,8,12,23,24,27,28,29
 1: 2,3,4,26
 2: 5
 3: 6,32,33,34
 4: 9,13
 5: 10
 6: 11
 7: 14,22,31
 8: 15
 9: 16
10: 17
11: 18
12: 19
13: 20
14: 21
15: 25,30
16: 35}