Controlling I/O Peripherals

SeS 3rd Feb 2016

A person interested in building peripherals themselves to interface with a PC, either used the serial or parallel port in the 80's, 90's and early 2000's. For private projects or hobby, usually this meant some more electronics that one had to build to complete the application and ofcourse write the software to interface with it. A sometimes tedious but rewarding process when I think of it again. The options in todays world are even more numerous. It is not in my interest to reinvent the wheel. Thus I prefer making proper use of existing building blocks to achieve my goal developing a proper I/O system.

Some time ago, I chose the Velleman USB EXPERIMENT INTERFACE BOARD with id K8055N. They provide a DLL to estabilish the correct communication with the I/O board. It's a versatile board, unfortunately their downloadable software examples does cover only the mainstream programming languages. In addition, with todays standards, wireless is the way to go. But, for the ones who are in the know, the USB interface can act as a subblock in a more complex communication-path and is therefore not a showstopper if one requires wireless communication...

As a tcl/tk user, the lack of examples how to communicate with the DLL does not stop us though. I was able to translate the API calls of the DLL functions to Ffidl jargon...

I have used *most* of the DLL functions within tG² and to my relief and joy, it works very nice. Caution on reading back the analog output channels though, some more testing and tuning is required on that part I noticed. For those who have the same interest and vision, I would like to share the Ffidl-DLL header file with you. It will also be available as a plugin in the next release of tG².

See also:

# Copyright (C) 2016 by S. Serper, email : [email protected]
# Software is part of tG2 (C), to be provided as an optional plugin.
#
# The author  hereby grants permission to use,  copy, modify, distribute,
# and  license this  software  and its  documentation  for any  purpose,
# provided that  existing copyright notices  are retained in  all copies
# and that  this notice  is included verbatim  in any  distributions. No
# written agreement, license, or royalty  fee is required for any of the
# authorized uses.  Modifications to this software may be copyrighted by
# their authors and need not  follow the licensing terms described here,
# provided that the new terms are clearly indicated on the first page of
# each file where they apply.
#
# IN NO  EVENT SHALL THE AUTHOR  OR DISTRIBUTORS BE LIABLE  TO ANY PARTY
# FOR  DIRECT, INDIRECT, SPECIAL,  INCIDENTAL, OR  CONSEQUENTIAL DAMAGES
# ARISING OUT  OF THE  USE OF THIS  SOFTWARE, ITS DOCUMENTATION,  OR ANY
# DERIVATIVES  THEREOF, EVEN  IF THE  AUTHOR  HAVE BEEN  ADVISED OF  THE
# POSSIBILITY OF SUCH DAMAGE.
#
# THE  AUTHOR  AND DISTRIBUTORS  SPECIFICALLY  DISCLAIM ANY  WARRANTIES,
# INCLUDING,   BUT   NOT  LIMITED   TO,   THE   IMPLIED  WARRANTIES   OF
# MERCHANTABILITY,  FITNESS   FOR  A  PARTICULAR   PURPOSE,  AND
# NON-INFRINGEMENT.  THIS  SOFTWARE IS PROVIDED  ON AN "AS  IS" BASIS,
# AND  THE  AUTHOR  AND  DISTRIBUTORS  HAVE  NO  OBLIGATION  TO  PROVIDE
# MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.


# ------------------------------------------------------------------------------
#Private Declare Function OpenDevice Lib "k8055d.dll" (ByVal CardAddress As Integer) As Integer
ffidl::callout dll_OpenDevice {int} int [ffidl::symbol k8055d.dll OpenDevice]

#Private Declare Sub CloseDevice Lib "k8055d.dll"
ffidl::callout dll_CloseDevice {} int [ffidl::symbol k8055d.dll CloseDevice]

#Private Declare Function Version Lib "k8055d.dll" () As Integer
ffidl::callout dll_Version {} int [ffidl::symbol k8055d.dll Version]

#Private Declare Function SearchDevices Lib "k8055d.dll" () As Integer
ffidl::callout dll_SearchDevices {} int [ffidl::symbol k8055d.dll SearchDevices]

#Private Declare Function SetCurrentDevice Lib "k8055d.dll" (ByVal CardAddress As Integer) As Integer
ffidl::callout dll_SetCurrentDevice {int} int [ffidl::symbol k8055d.dll SetCurrentDevice]


# ------------------------------------------------------------------------------
#Private Declare Function ReadAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer) As Integer
ffidl::callout dll_ReadAnalogChannel {int} int [ffidl::symbol k8055d.dll ReadAnalogChannel]

#Private Declare Sub ReadAllAnalog Lib "k8055d.dll" (ByRef Data1 As Integer, ByRef Data2 As Integer)
ffidl::callout dll_ReadAllAnalog {int int} int [ffidl::symbol k8055d.dll ReadAllAnalog]

#Private Declare Sub OutputAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer, ByVal Data As Integer)
ffidl::callout dll_OutputAnalogChannel {int int} int [ffidl::symbol k8055d.dll OutputAnalogChannel]

#Private Declare Sub OutputAllAnalog Lib "k8055d.dll" (ByVal Data1 As Integer, ByVal Data2 As Integer)
ffidl::callout dll_OutputAllAnalog {int int} int [ffidl::symbol k8055d.dll OutputAllAnalog]

#Private Declare Sub ClearAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer)
ffidl::callout dll_ClearAnalogChannel {int} int [ffidl::symbol k8055d.dll ClearAnalogChannel]

#Private Declare Sub SetAllAnalog Lib "k8055d.dll" ()
ffidl::callout dll_SetAllAnalog {} int [ffidl::symbol k8055d.dll SetAllAnalog]

#Private Declare Sub ClearAllAnalog Lib "k8055d.dll" ()
ffidl::callout dll_ClearAllAnalog {} int [ffidl::symbol k8055d.dll ClearAllAnalog]

#Private Declare Sub SetAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer)
ffidl::callout dll_SetAnalogChannel {int} int [ffidl::symbol k8055d.dll SetAnalogChannel]

#Private Declare Sub ReadBackAnalogOut Lib "k8055d.dll" (ByRef Buffer As Integer)
ffidl::callout dll_ReadBackAnalogOut {pointer-var} int [ffidl::symbol k8055d.dll ReadBackAnalogOut]


# ------------------------------------------------------------------------------
#Private Declare Sub WriteAllDigital Lib "k8055d.dll" (ByVal Data As Integer)
ffidl::callout dll_WriteAllDigital {int} int [ffidl::symbol k8055d.dll WriteAllDigital]

#Private Declare Sub ClearDigitalChannel Lib "k8055d.dll" (ByVal Channel As Integer)
ffidl::callout dll_ClearDigitalChannel {int} int [ffidl::symbol k8055d.dll ClearDigitalChannel]

#Private Declare Sub ClearAllDigital Lib "k8055d.dll" ()
ffidl::callout dll_ClearAllDigital {} int [ffidl::symbol k8055d.dll ClearAllDigital]

#Private Declare Sub SetDigitalChannel Lib "k8055d.dll" (ByVal Channel As Integer)
ffidl::callout dll_SetDigitalChannel {int} int [ffidl::symbol k8055d.dll SetDigitalChannel]

#Private Declare Sub SetAllDigital Lib "k8055d.dll" ()
ffidl::callout dll_SetAllDigital {} int [ffidl::symbol k8055d.dll SetAllDigital]

#Private Declare Function ReadDigitalChannel Lib "k8055d.dll" (ByVal Channel As Integer) As Boolean
ffidl::callout dll_ReadDigitalChannel {int} int [ffidl::symbol k8055d.dll ReadDigitalChannel]

#Private Declare Function ReadAllDigital Lib "k8055d.dll" () As Integer
ffidl::callout dll_ReadAllDigital {} int [ffidl::symbol k8055d.dll ReadAllDigital]

#Private Declare Function ReadBackDigitalOut Lib "k8055d.dll" () As Integer
ffidl::callout dll_ReadBackDigitalOut {} int [ffidl::symbol k8055d.dll ReadBackDigitalOut]

# ------------------------------------------------------------------------------
#Private Declare Function ReadCounter Lib "k8055d.dll" (ByVal CounterNr As Integer) As Integer
ffidl::callout dll_ReadCounter {int} int [ffidl::symbol k8055d.dll ReadCounter]

#Private Declare Sub ResetCounter Lib "k8055d.dll" (ByVal CounterNr As Integer)
ffidl::callout dll_ResetCounter {int} int [ffidl::symbol k8055d.dll ResetCounter]

#Private Declare Sub SetCounterDebounceTime Lib "k8055d.dll" (ByVal CounterNr As Integer, ByVal DebounceTime As Integer)
ffidl::callout dll_SetCounterDebounceTime {int int} int [ffidl::symbol k8055d.dll SetCounterDebounceTime]