summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile72
-rw-r--r--README.txt37
-rw-r--r--java/build.xml213
-rw-r--r--java/src/c/jk8055.c398
-rw-r--r--java/src/java/net/sf/libk8055/jk8055/JK8055.java812
-rw-r--r--java/src/java/net/sf/libk8055/jk8055/JK8055Exception.java73
-rw-r--r--java/src/java/net/sf/libk8055/jk8055/JK8055Test.java400
-rw-r--r--java/src/java/net/sf/libk8055/jk8055/overview.html7
-rw-r--r--java/src/java/net/sf/libk8055/jk8055/package.html8
-rw-r--r--k8055.h55
-rw-r--r--libk8055.c600
-rw-r--r--main.c295
-rw-r--r--man/k8055.1.gzbin0 -> 1843 bytes
-rw-r--r--pyk8055/Makefile37
-rw-r--r--pyk8055/frmk8055qt.ui1422
-rw-r--r--pyk8055/frmk8055qt.ui.h260
-rwxr-xr-xpyk8055/k8055.py117
-rw-r--r--pyk8055/k8055qt.pngbin0 -> 33894 bytes
-rw-r--r--pyk8055/k8055qt.py232
-rwxr-xr-xpyk8055/k8055test.py70
-rw-r--r--pyk8055/k8055testm.py98
-rw-r--r--pyk8055/libk8055.i352
-rwxr-xr-xpyk8055/pyplotA.py88
-rw-r--r--pyk8055/pyplotA_1.pngbin0 -> 21901 bytes
-rwxr-xr-xpyk8055/pyplotD.py113
-rw-r--r--pyk8055/pyplotD_2.pngbin0 -> 20543 bytes
-rw-r--r--pyk8055/setup.py31
-rw-r--r--velleman.rules19
28 files changed, 5809 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e647ae1
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,72 @@
+# $Id: Makefile,v 1.5 2008/05/21 20:22:44 mr_brain Exp $
+#
+# Simple makefile for the libk8055 library
+#
+# change this to your distribution default
+# usually /usr/local or /usr
+PREFIX = ?/usr/local
+CC = gcc
+EXEC = k8055
+VERSION =0.4.1
+BINDIR = $(PREFIX)/bin
+LIBDIR = $(PREFIX)/lib
+PYLIBDIR = pyk8055
+INCLUDEDIR = $(PREFIX)/include
+MANDIR = $(PREFIX)/man/man1
+OBJS = main.o libk8055.o
+CFLAGS = -O2 -DDAEMON -DVERSION='"$(VERSION)"' -Wall
+LIBS = -lusb -L/usr/lib -lm
+LINK = ln
+
+libk8055.so.$(VERSION): libk8055.o
+ $(CC) -o libk8055.so.${VERSION} $(LIBS) -shared libk8055.o
+ -$(LINK) -sf libk8055.so.${VERSION} libk8055.so
+
+libk8055.o: libk8055.c
+ $(CC) $(CFLAGS) -c -g -fPIC libk8055.c
+
+libk8055.a: libk8055.o
+ ar rvs libk8055.a libk8055.o
+
+libk8055.c: k8055.h
+
+all: k8055_prog libk8055.so.${VERSION} libk8055.a
+
+.PHONY: k8055_prog
+
+k8055_prog: $(OBJS)
+ $(CC) $(OBJS) -o $(EXEC) $(LIBS)
+ # strip $(EXEC)
+
+pylib: $(PYLIBDIR)/libk8055.i libk8055.c
+ export VERSION=$(VERSION); $(MAKE) -C $(PYLIBDIR)
+
+clean:
+ rm -f *.o libk8055.so libk8055.so.$(VERSION) $(EXEC) libk8055.a
+ @$(MAKE) -C $(PYLIBDIR) clean
+
+install: k8055_prog libk8055.so.$(VERSION)
+ cp -f $(EXEC) $(BINDIR)/
+ if !(test -d $(LIBDIR)); then \
+ mkdir -p $(LIBDIR); \
+ fi
+ if !(test -d $(INCLUDEDIR)); then \
+ mkdir -p $(INCLUDEDIR); \
+ fi
+ rm -f $(LIBDIR)/libk8055*
+ cp -Pf lib* $(LIBDIR)
+ cp -f k8055.h $(INCLUDEDIR)
+ if !(test -d $(MANDIR)); then \
+ mkdir -p $(MANDIR); \
+ fi
+ cp -f man/k8055.1.gz $(MANDIR)/
+
+pyinstall: $(PYLIBDIR)/libk8055.i
+ @$(MAKE) -C $(PYLIBDIR) install
+
+uninstall:
+ rm -f $(BINDIR)/$(EXEC) $(LIBDIR)/libk8055* $(INCLUDEDIR)/k8055.h
+
+test: k8055_prog
+ -@killall $(EXEC)
+ ./$(EXEC)
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..5b5d45c
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,37 @@
+The k8055 require libusb-0.1.9 or newer and kernel 2.4.18 or never.
+
+install:
+ # make all
+ # make install
+ update ld.so.conf with "/usr/local/lib" if not there or run
+ env-update at gentoo systems
+
+uninstall:
+ # make uninstall
+
+Check out the Makefile for all different make rules...
+
+User access to the k8055 device:
+ read comments in velleman.rules
+
+Using the k8055 library:
+ in the program file "#include <k8055.h>" and compile with -lk8055 and
+ -lusb, e.g gcc -lusb -lk8055 main.c -o k8055_rocks
+
+Python part
+ Python makes use of SWIG interface language, for setup and install
+ see http://www.swig.org
+
+ There might be a prepared package for your distribution, use
+ emerge swig, apt-get install swig, urpmi swig, rpm -Uvh swig_package
+ Or whatever your favorite distribution provides.
+ Then, from the library source directory:
+
+ # make pylib
+
+ You can then run the python programs from within the pyk8055 directory
+
+ For global install, run as root:
+ # make pyinstall
+ This should install your package in the proper site-package dircetory
+ globally accessible for the python interpreter
diff --git a/java/build.xml b/java/build.xml
new file mode 100644
index 0000000..66dc02c
--- /dev/null
+++ b/java/build.xml
@@ -0,0 +1,213 @@
+<?xml version="1.0"?>
+<!--
+ * Copyright (C) 2008 Martin Pischky (mailto:martin@pischky.de)
+ *
+ * This file (build.xml) is part of libk8055/jk8055.
+ * jk8055 - a java wrapper for libk8055
+ *
+ *
+ * libk8055/jk8055 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * $Id: build.xml,v 1.4 2008/07/28 09:58:30 pischky Exp $
+-->
+<project name="jk8055" default="all">
+ <description>
+ java wrapper for libk8055
+ </description>
+
+ <property environment="env" />
+
+ <!-- some files -->
+
+ <property name="file.base" value="jk8055" />
+ <property name="file.c" location="src/c/${file.base}.c" />
+
+ <property name="version" value="0.3" />
+
+ <!-- set global properties for building -->
+
+ <property file="build.properties" />
+ <property file="${user.home}/build.properties" />
+ <!-- example (build.properties is not stored in cvs):
+ # My installation of M$ VS 2003.
+ # Use VS 2003 Command Prompt to get the value
+ VSINSTALLDIR=D:\\Programme\\Visual Studio .NET 2003\\Common7\\IDE
+ VCINSTALLDIR=D:\\Programme\\Microsoft Visual Studio .NET 2003
+ # My installation of the java development kit
+ jdk.home=D:\\j2sdk1.4.2_11
+ # My installation of the Velleman "K8055D_C.lib", "K8055D_C.DLL",
+ # "K8055D_C.h" and "K8055D.DLL"
+ VellemanDir=D:\\Programme\\Velleman\\K8055
+ -->
+
+ <!-- set properties if not definded in build.properties -->
+
+ <!-- guess java development kit -->
+ <property name="jdk.home" value="${env.JDK_HOME}" />
+
+ <!-- guess c compiler for windows (eg.: microsoft visual studio 2003) -->
+ <property name="VSINSTALLDIR"
+ location="${env.ProgramFiles}\Microsoft Visual Studio .NET 2003\Common7\IDE" />
+ <property name="VCINSTALLDIR"
+ location="${env.ProgramFiles}\Microsoft Visual Studio .NET 2003" />
+ <property name="MSVCDir"
+ location="${VCINSTALLDIR}\VC7" />
+ <property name="DevEnvDir"
+ location="${VSINSTALLDIR}" />
+ <property name="VellemanDir"
+ location="C:\Program Files\Velleman\K8055" />
+
+ <target name="init">
+ <echo message="running ant '${ant.version}'" level="info" />
+ <echo message="on java '${ant.java.version}'" level="info" />
+ <echo message="java.home='${java.home}'" level="info" />
+ <echo message="jdk.home ='${jdk.home}'" level="info" />
+ <mkdir dir="build/java" />
+ <mkdir dir="build/c" />
+ <mkdir dir="dist" />
+ <mkdir dir="dist/win32" />
+ <mkdir dir="dist/linux" />
+ </target>
+
+ <target name="compile-java" depends="init">
+ <javac srcdir="src/java" destdir="build/java">
+ <include name="**/*.java"/>
+ <exclude name="**/*Test.java"/>
+ </javac>
+ <javah classpath="build/java"
+ class="net.sf.libk8055.jk8055.JK8055"
+ outputfile="build/c/jk8055.h" />
+ </target>
+
+ <target name="compile-c" depends="compile-java">
+ <javah classpath="build/java"
+ class="net.sf.libk8055.jk8055.JK8055"
+ outputfile="build/c/jk8055.h" />
+ <exec executable="gcc" dir="build/c" os="Linux">
+ <arg line='-o lib${file.base}.so
+ -shared
+ -Wl,-soname,lib${file.base}.so
+ -I${jdk.home}/include
+ -I${jdk.home}/include/linux
+ -I.
+ -lk8055
+ "${file.c}"' />
+ </exec>
+ <exec executable="${MSVCDir}\BIN\cl.exe" dir="build/c"
+ os="Windows 2000, Windows XP" failonerror="true">
+ <!-- be carefull with case here ! -->
+ <env key="Path" path="${DevEnvDir};${MSVCDir}\BIN;${env.Path}" />
+ <env key="INCLUDE" path="${MSVCDir}\INCLUDE;${env.INCLUDE}" />
+ <env key="LIB" path="${MSVCDir}\LIB;${env.LIB}" />
+ <arg line='-I "${jdk.home}\include"
+ -I "${jdk.home}\include\win32"
+ -I "${VellemanDir}"
+ -I.
+ -DUSE_VELLEMAN_DLL
+ -LD
+ "${file.c}"
+ -Fe${file.base}.dll
+ -link "${VellemanDir}\K8055D_C.lib"' />
+ </exec>
+ </target>
+
+ <target name="dist" depends="compile-c"
+ description="create files for distribution">
+ <copy todir="dist/linux" failonerror="false">
+ <fileset dir="build/c">
+ <include name="lib${file.base}.so"/>
+ </fileset>
+ </copy>
+ <copy todir="dist/win32" failonerror="false">
+ <fileset dir="build/c">
+ <include name="${file.base}.dll"/>
+ </fileset>
+ <fileset dir="${VellemanDir}">
+ <include name="K8055D_C.DLL"/>
+ <include name="K8055D.DLL"/>
+ </fileset>
+ </copy>
+ <jar destfile="dist/${file.base}-${version}.jar" basedir="build/java">
+ <manifest>
+ <attribute name="Built-By" value="${user.name}"/>
+ <attribute name="JK8055-Version" value="${version}"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name="javadoc" depends="compile-java"
+ description="create component Javadoc documentation">
+ <mkdir dir="build/docs"/>
+ <mkdir dir="build/docs/api"/>
+ <javadoc destdir="build/docs/api"
+ overview="src/java/net/sf/libk8055/jk8055/overview.html"
+ packagenames="net.sf.libk8055.jk8055"
+ author="true"
+ version="true"
+ doctitle="&lt;h1&gt;JK8055&lt;/h1&gt;"
+ windowtitle="JK8055 (Version ${version})"
+ bottom="Copyright &amp;copy; 2008 by Martin Pischky"
+ use="true"
+ link="http://java.sun.com/j2se/1.4/docs/api/">
+ <fileset dir="src/java">
+ <include name="**/*.java"/>
+ <exclude name="**/*Test.java"/>
+ </fileset>
+ </javadoc>
+ <jar jarfile="dist/${file.base}-${version}-javadoc.jar"
+ basedir="build/docs/api" />
+ </target>
+
+ <target name="junit" depends="compile-c"
+ description="run junit tests" >
+ <!-- we assume that junit.jar is in ant's lib directory -->
+ <mkdir dir="build/reports" />
+ <mkdir dir="build/junit" />
+ <javac srcdir="src/java" destdir="build/junit">
+ <include name="**/*Test.java"/>
+ </javac>
+ <junit printsummary="yes"
+ haltonfailure="yes" showoutput="yes">
+ <classpath>
+ <pathelement location="build/java" />
+ <pathelement location="build/junit" />
+ <pathelement path="${java.class.path}" />
+ </classpath>
+ <env key="Path" path="build/c;${VellemanDir};${env.Path}"/>
+ <env key="LD_LIBRARY_PATH" path="build/c:${env.LD_LIBRARY_PATH}"/>
+ <formatter type="plain"/>
+ <batchtest fork="yes" todir="build/reports">
+ <fileset dir="src/java">
+ <include name="**/*Test.java"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <target name="all" depends="dist, javadoc"
+ description="--> java wrapper for libk8055">
+ </target>
+
+ <target name="clean">
+ <delete dir="build"/>
+ </target>
+
+ <target name="distclean" depends="clean">
+ <delete dir="dist"/>
+ </target>
+
+</project>
+
+
diff --git a/java/src/c/jk8055.c b/java/src/c/jk8055.c
new file mode 100644
index 0000000..e33de70
--- /dev/null
+++ b/java/src/c/jk8055.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2008 Martin Pischky (mailto:martin@pischky.de)
+ *
+ * This file (jk8055.c) is part of libk8055/jk8055.
+ * jk8055 - a java wrapper for libk8055
+ *
+ * libk8055/jk8055 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * $Id: jk8055.c,v 1.2 2008/07/12 11:32:01 pischky Exp $
+ *
+ */
+
+#include <jni.h>
+#ifdef USE_VELLEMAN_DLL
+ // assumes that Velleman DLL Version 2 has been installed
+ #define bool int
+ #include <K8055D_C.h>
+#else
+ // assumes that the c library as been installed with header file
+ #include <k8055.h>
+#endif
+#include <stdio.h>
+#include "jk8055.h"
+
+#define K8055_ERROR -1
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: COpenDevice
+ * Signature: (I)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_COpenDevice
+(JNIEnv* env, jobject obj, jint cardAddress)
+{
+ return OpenDevice(cardAddress);
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CCloseDevice
+ * Signature: ()I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CCloseDevice
+(JNIEnv* env, jobject obj)
+{
+ return CloseDevice();
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CReadAnalogChannel
+ * Signature: (I)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CReadAnalogChannel
+(JNIEnv* env, jobject obj, jint channel)
+{
+ return ReadAnalogChannel( channel );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CReadAllAnalog
+ * Signature: (Lnet/sf/libk8055/jk8055/JK8055$AllAnalog;)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CReadAllAnalog
+(JNIEnv* env, jobject obj, jobject data)
+{
+ long a1, a2;
+ jfieldID fid1, fid2;
+ int retval;
+ jclass cls;
+
+ retval = ReadAllAnalog( &a1, &a2 );
+ if( retval == K8055_ERROR ) return retval;
+ cls = (*env)->GetObjectClass( env, data );
+ fid1 = (*env)->GetFieldID( env, cls, "data1", "I" );
+ if( fid1 == NULL ) return K8055_ERROR;
+ fid2 = (*env)->GetFieldID( env, cls, "data2", "I" );
+ if( fid2 == NULL ) return K8055_ERROR;
+ (*env)->SetIntField( env, data, fid1, (jint) a1 );
+ (*env)->SetIntField( env, data, fid2, (jint) a2 );
+ return 0;
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: COutputAnalogChannel
+ * Signature: (II)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_COutputAnalogChannel
+(JNIEnv* env, jobject obj, jint channel, jint data)
+{
+ return OutputAnalogChannel( channel, data );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: COutputAllAnalog
+ * Signature: (II)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_COutputAllAnalog
+(JNIEnv* env, jobject obj, jint data1, jint data2)
+{
+ return OutputAllAnalog( data1, data2 );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CClearAllAnalog
+ * Signature: ()I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CClearAllAnalog
+(JNIEnv* env, jobject obj)
+{
+ return ClearAllAnalog();
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CClearAnalogChannel
+ * Signature: (I)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CClearAnalogChannel
+(JNIEnv* env, jobject obj, jint channel)
+{
+ return ClearAnalogChannel( channel );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CSetAnalogChannel
+ * Signature: (I)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CSetAnalogChannel
+(JNIEnv* env, jobject obj, jint channel)
+{
+ return SetAnalogChannel( channel );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CSetAllAnalog
+ * Signature: ()I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CSetAllAnalog
+(JNIEnv* env, jobject obj)
+{
+ return SetAllAnalog();
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CWriteAllDigital
+ * Signature: (I)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CWriteAllDigital
+(JNIEnv* env, jobject obj, jint data)
+{
+ return WriteAllDigital( data );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CClearDigitalChannel
+ * Signature: (I)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CClearDigitalChannel
+(JNIEnv* env, jobject obj, jint channel)
+{
+ return ClearDigitalChannel( channel );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CClearAllDigital
+ * Signature: ()I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CClearAllDigital
+(JNIEnv* env, jobject obj)
+{
+ return ClearAllDigital();
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CSetDigitalChannel
+ * Signature: (I)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CSetDigitalChannel
+(JNIEnv* env, jobject obj, jint channel)
+{
+ return SetDigitalChannel( channel );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CSetAllDigital
+ * Signature: ()I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CSetAllDigital
+(JNIEnv* env, jobject obj)
+{
+ return SetAllDigital();
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CReadDigitalChannel
+ * Signature: (I)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CReadDigitalChannel
+(JNIEnv* env, jobject obj, jint channel)
+{
+ return ReadDigitalChannel( channel );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CReadAllDigital
+ * Signature: ()I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CReadAllDigital
+(JNIEnv* env, jobject obj)
+{
+ return ReadAllDigital();
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CResetCounter
+ * Signature: (I)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CResetCounter
+(JNIEnv* env, jobject obj, jint counterno)
+{
+ return ResetCounter( counterno );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CReadCounter
+ * Signature: (I)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CReadCounter
+(JNIEnv* env, jobject obj, jint counterno)
+{
+ return ReadCounter( counterno );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CSetCounterDebounceTime
+ * Signature: (II)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CSetCounterDebounceTime
+(JNIEnv* env, jobject obj, jint counterno, jint debouncetime)
+{
+ return SetCounterDebounceTime( counterno, debouncetime );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CReadAllValues
+ * Signature: (Lnet/sf/libk8055/jk8055/JK8055$AllValues;)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CReadAllValues
+(JNIEnv* env, jobject obj, jobject av)
+{
+ long input, analog1, analog2, counter1, counter2;
+ int retval;
+ jfieldID fid_input, fid_analog1, fid_analog2, fid_counter1, fid_counter2;
+ jclass cls;
+
+ #ifdef USE_VELLEMAN_DLL
+ input = ReadAllDigital();
+ if( input == K8055_ERROR ) return input;
+ retval = ReadAllAnalog( &analog1, &analog2 );
+ if( retval == K8055_ERROR ) return retval;
+ counter1 = ReadCounter( 1 );
+ if( counter1 == K8055_ERROR ) return counter1;
+ counter2 = ReadCounter( 2 );
+ if( counter2 == K8055_ERROR ) return counter2;
+ #else
+ retval = ReadAllValues( &input, &analog1, &analog2, &counter1, &counter2 );
+ if( retval == K8055_ERROR ) return retval;
+ #endif
+ cls = (*env)->GetObjectClass( env, av );
+ fid_input = (*env)->GetFieldID( env, cls, "input", "I" );
+ if( fid_input == NULL ) return K8055_ERROR;
+ fid_analog1 = (*env)->GetFieldID( env, cls, "analog1", "I" );
+ if( fid_analog1 == NULL ) return K8055_ERROR;
+ fid_analog2 = (*env)->GetFieldID( env, cls, "analog2", "I" );
+ if( fid_analog2 == NULL ) return K8055_ERROR;
+ fid_counter1 = (*env)->GetFieldID( env, cls, "counter1", "I" );
+ if( fid_counter1 == NULL ) return K8055_ERROR;
+ fid_counter2 = (*env)->GetFieldID( env, cls, "counter2", "I" );
+ if( fid_counter2 == NULL ) return K8055_ERROR;
+ (*env)->SetIntField( env, av, fid_input, (jint) input );
+ (*env)->SetIntField( env, av, fid_analog1, (jint) analog1 );
+ (*env)->SetIntField( env, av, fid_analog2, (jint) analog2 );
+ (*env)->SetIntField( env, av, fid_counter1, (jint) counter1 );
+ (*env)->SetIntField( env, av, fid_counter2, (jint) counter2 );
+ return 0;
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CSetAllValues
+ * Signature: (III)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CSetAllValues
+(JNIEnv* env, jobject obj, jint digitaldata, jint analogdata1, jint analogdata2)
+{
+ int retval;
+ #ifdef USE_VELLEMAN_DLL
+ retval = WriteAllDigital( digitaldata );
+ if( retval == K8055_ERROR ) return retval;
+ retval = OutputAllAnalog( analogdata1, analogdata2 );
+ if( retval == K8055_ERROR ) return retval;
+ #else
+ retval = SetAllValues( digitaldata, analogdata1, analogdata2 );
+ #endif
+ return retval;
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CSetCurrentDevice
+ * Signature: (I)I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CSetCurrentDevice
+(JNIEnv* env, jobject obj, jint deviceno)
+{
+ return SetCurrentDevice( deviceno );
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CSearchDevices
+ * Signature: ()I
+ */
+JNIEXPORT jint
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CSearchDevices
+(JNIEnv* env, jobject obj)
+{
+ return SearchDevices();
+}
+
+/*
+ * Class: net_sf_libk8055_jk8055_JK8055
+ * Method: CVersion
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring
+JNICALL Java_net_sf_libk8055_jk8055_JK8055_CVersion
+(JNIEnv* env, jobject obj)
+{
+ #ifdef USE_VELLEMAN_DLL
+ return (*env)->NewStringUTF( env, "unknown" );
+ #else
+ return (*env)->NewStringUTF( env, Version() );
+ #endif
+}
diff --git a/java/src/java/net/sf/libk8055/jk8055/JK8055.java b/java/src/java/net/sf/libk8055/jk8055/JK8055.java
new file mode 100644
index 0000000..26cdbc1
--- /dev/null
+++ b/java/src/java/net/sf/libk8055/jk8055/JK8055.java
@@ -0,0 +1,812 @@
+/*
+ * Copyright (C) 2008 Martin Pischky (mailto:martin@pischky.de)
+ *
+ * This file (JK8055.java) is part of libk8055/jk8055.
+ * jk8055 - a java wrapper for libk8055
+ *
+ * libk8055/jk8055 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * $Id: JK8055.java,v 1.4 2008/07/28 09:58:30 pischky Exp $
+ *
+ */
+
+package net.sf.libk8055.jk8055;
+
+/**
+ * JK8055 - A java wrapper for libk8055.
+ *
+ * @see <a href="http://libk8055.sourceforge.net/">http://libk8055.sourceforge.net/</a>
+ * @author <a href="mailto:martin@pischky.de">Martin Pischky</a>
+ *
+ */
+public class JK8055 {
+
+ public static final String CVS_ID = "$Id: JK8055.java,v 1.4 2008/07/28 09:58:30 pischky Exp $";
+
+ /**
+ * This class is singleton.
+ */
+ private JK8055() {
+ }
+
+ private static JK8055 instance = null;
+
+ /**
+ * Create an instance if needed and return it.
+ * @return the instance
+ */
+ public static JK8055 getInstance() {
+ if( instance != null ) {
+ return instance;
+ }
+ synchronized (JK8055.class) {
+ if( instance == null ) {
+ instance = new JK8055();
+ }
+ }
+ return instance;
+ }
+
+ public static final int K8055_ERROR = -1;
+
+ static {
+ System.loadLibrary("jk8055");
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#finalize()
+ */
+ protected void finalize() throws Throwable {
+ try {
+ CloseAllOpenDevices();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ /**
+ * Open device.
+ * Scan through usb busses looking
+ * for the right device, claim it and then open the device.
+ * @param cardAddress
+ * @return BoardAddress or K8055_ERROR
+ */
+ private native int COpenDevice( int cardAddress );
+
+ /**
+ * Opens the communication link to the K8055 device.
+ * Opens the communication link to the K8055 card. Loads the drivers
+ * needed to communicate via the USB port. This procedure must be performed
+ * before any attempts to communicate with the K8055 card.
+ * <br>
+ * This function can also be used to selects the active K8055 card to read
+ * and write the data. All the communication routines after this function
+ * call are addressed to this card until the other card is selected by this
+ * function call.
+ *
+ * @param cardAddress Value between 0 and 3 which corresponds to the
+ * jumper (SK5, SK6) setting on the K8055 board.
+ * @return If succeeded the return value will be the card address read
+ * from the K8055 hardware.
+ * @throws JK8055Exception indicates that K8055 card was not found.
+ */
+ public synchronized int OpenDevice( int cardAddress )
+ throws JK8055Exception
+ {
+ if( cardAddress<0 || 3<cardAddress ) {
+ throw new IllegalArgumentException( "cardAddress: "+cardAddress );
+ }
+ int retval = COpenDevice( cardAddress );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "OpenDevice("+cardAddress+") failed" );
+ }
+ return retval;
+ }
+
+ /**
+ * Close the Current device.
+ * @return retunvalue from usb_close: 0 on success or < 0 on error.
+ */
+ private native int CCloseDevice();
+
+ /**
+ * Closes the link to the K8055 device.
+ * Unloads the communication routines for K8055 card and unloads the driver
+ * needed to communicate via the USB port. This is the last action of the
+ * application program before termination.
+ *
+ * @throws JK8055Exception indicates an error.
+ */
+ public synchronized void CloseDevice()
+ throws JK8055Exception
+ {
+ int retval = CCloseDevice();
+ if( retval<0 ) {
+ throw new JK8055Exception( "CloseDevice failed with rc="+retval );
+ }
+ }
+
+ /**
+ * Close all open devices.
+ * Check what open devices still exist an closes them.
+ *
+ * @throws JK8055Exception
+ */
+ public synchronized void CloseAllOpenDevices()
+ throws JK8055Exception
+ {
+ for( int i = 0; i < 4; i++ ) {
+ if( CSetCurrentDevice( i ) != K8055_ERROR ) {
+ CloseDevice();
+ }
+ }
+ }
+
+ /**
+ * @param channel 1..2
+ * @return 0..255 or K8055_ERROR
+ */
+ private native int CReadAnalogChannel( int channel );
+
+ /**
+ * Reads the status of one analogue input-channel.
+ * The input voltage of the selected 8-bit Analogue to Digital converter
+ * channel is converted to a value which lies between 0 and 255.
+ *
+ * @param channel Value between 1 and 2 which corresponds to the AD channel
+ * whose status is to be read.
+ * @return The corresponding Analogue to Digital Converter data is read.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid channel number.
+ */
+ public synchronized int ReadAnalogChannel( int channel )
+ throws JK8055Exception
+ {
+ if( channel<1 || 2<channel ) {
+ throw new IllegalArgumentException( "channel: "+channel );
+ }
+ int retval = CReadAnalogChannel( channel );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "ReadAnalogChannel failed" );
+ }
+ return retval;
+ }
+
+ public class AllAnalog {
+ public int data1;
+ public int data2;
+ }
+
+ /**
+ * @param data
+ * @return 0 or K8055_ERROR
+ */
+ private native int CReadAllAnalog(AllAnalog data);
+
+ /**
+ * Reads the status of both analogue input-channels.
+ * The status of both Analogue to Digital Converters are read to a new
+ * object of class AllAnalogarray
+ *
+ * @return the values read
+ * @throws JK8055Exception indicates an error.
+ */
+ public synchronized AllAnalog ReadAllAnalog()
+ throws JK8055Exception
+ {
+ AllAnalog aa = new AllAnalog();
+ int retval = CReadAllAnalog( aa );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "ReadAllAnalog failed" );
+ }
+ return aa;
+ }
+
+ /**
+ * @param channel 1..2
+ * @param data 0..255
+ * @return K8055_ERROR or 0
+ */
+ private native int COutputAnalogChannel( int channel, int data );
+
+ /**
+ * Sets the analogue output channel according to the data.
+ * The indicated 8-bit Digital to Analogue Converter channel is altered
+ * according to the new data. This means that the data corresponds to a
+ * specific voltage. The value 0 corresponds to a minimum output voltage
+ * (0 Volt) and the value 255 corresponds to a maximum output voltage
+ * (+5V). A value of 'Data' lying in between these extremes can be
+ * translated by the following formula : Data / 255 x 5V.
+ *
+ * @param channel Value between 1 and 2 which corresponds to the 8-bit DA
+ * channel number whose data is to be set.
+ * @param data Value between 0 and 255 which is to be sent to the 8-bit
+ * Digital to Analogue Converter.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid parameter.
+ */
+ public synchronized void OutputAnalogChannel( int channel, int data )
+ throws JK8055Exception
+ {
+ if( channel<1 || 2<channel ) {
+ throw new IllegalArgumentException( "channel: "+channel );
+ }
+ if( data<0 || 255<data ) {
+ throw new IllegalArgumentException( "data: "+data );
+ }
+ int retval = COutputAnalogChannel( channel, data );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "OutputAnalogChannel failed" );
+ }
+ }
+
+ /**
+ * @param data1 0..255
+ * @param data2 0..255
+ * @return K8055_ERROR or 0
+ */
+ private native int COutputAllAnalog( int data1, int data2 );
+
+ /**
+ * Sets both analogue output channels according to the data.
+ * Both 8-bit Digital to Analogue Converter channels are altered according
+ * to the new data. This means that the data corresponds to a specific
+ * voltage. The value 0 corresponds to a minimum output voltage (0 Volt)
+ * and the value 255 corresponds to a maximum output voltage (+5V). A
+ * value of 'Data1' or 'Data2' lying in between these extremes can be
+ * translated by the following formula : Data / 255 x 5V.
+ *
+ * @param data1 Value between 0 and 255 which is to be sent to the 8-bit
+ * Digital to Analogue Converter.
+ * @param data2 Value between 0 and 255 which is to be sent to the 8-bit
+ * Digital to Analogue Converter.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid parameter.
+ */
+ public synchronized void OutputAllAnalog( int data1, int data2 )
+ throws JK8055Exception
+ {
+ if( data1<0 || 255<data1 ) {
+ throw new IllegalArgumentException( "data1: "+data1 );
+ }
+ if( data2<0 || 255<data2 ) {
+ throw new IllegalArgumentException( "data2: "+data2 );
+ }
+ int retval = COutputAllAnalog( data1, data2 );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "OutputAllAnalog failed" );
+ }
+ }
+
+ /**
+ * @return K8055_ERROR or 0
+ */
+ private native int CClearAllAnalog();
+
+ /**
+ * Sets all analogue output channels to minimum.
+ * Both DA-channels are set to minimum output voltage (0 Volt) .
+ *
+ * @throws JK8055Exception indicates an error.
+ */
+ public synchronized void ClearAllAnalog()
+ throws JK8055Exception
+ {
+ int retval = CClearAllAnalog();
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "ClearAllAnalog failed" );
+ }
+ }
+
+ /**
+ * @param channel 1..2
+ * @return K8055_ERROR or 0
+ */
+ private native int CClearAnalogChannel( int channel );
+
+ /**
+ * Sets the analogue output channel to minimum.
+ * The selected DA-channel is set to minimum output voltage (0 Volt).
+ *
+ * @param channel Value between 1 and 2 which corresponds to the 8-bit DA
+ * channel number in which the data is to be erased.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid channel number.
+ */
+ public synchronized void ClearAnalogChannel( int channel )
+ throws JK8055Exception
+ {
+ if( channel<1 || 2<channel ) {
+ throw new IllegalArgumentException( "channel: "+channel );
+ }
+ int retval = CClearAnalogChannel( channel );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "ClearAllAnalog failed" );
+ }
+ }
+
+ /**
+ * @param channel 1..2
+ * @return K8055_ERROR or 0
+ */
+ private native int CSetAnalogChannel( int channel );
+
+ /**
+ * Sets the analogue output channel to maximum.
+ * The selected 8-bit Digital to Analogue Converter channel is set to
+ * maximum output voltage.
+ *
+ * @param channel Value between 1 and 2 which corresponds to the 8-bit DA
+ * channel number in which the data is to be set to maximum.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid channel number.
+ */
+ public synchronized void SetAnalogChannel( int channel )
+ throws JK8055Exception
+ {
+ if( channel<1 || 2<channel ) {
+ throw new IllegalArgumentException( "channel: "+channel );
+ }
+ int retval = CSetAnalogChannel( channel );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "SetAnalogChannel failed" );
+ }
+ }
+
+ /**
+ * @return K8055_ERROR or 0
+ */
+ private native int CSetAllAnalog();
+
+ /**
+ * Sets all analogue output channels to maximum.
+ * All channels of the 8-bit Digital to Analogue Converters are set to
+ * maximum output voltage.
+ *
+ * @throws JK8055Exception indicates an error.
+ */
+ public synchronized void SetAllAnalog()
+ throws JK8055Exception
+ {
+ int retval = CSetAllAnalog();
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "SetAllAnalog failed" );
+ }
+ }
+
+ /**
+ * @param data 0..255
+ * @return K8055_ERROR or 0
+ */
+ private native int CWriteAllDigital( int data );
+
+ /**
+ * Sets the digital outputs according to the data.
+ * The channels of the digital output port are updated with the status of
+ * the corresponding bits in the data parameter. A high (1) level means
+ * that the microcontroller IC1 output is set, and a low (0) level means
+ * that the output is cleared.
+ *
+ * @param data Value between 0 and 255 that is sent to the output
+ * port (8 channels).
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid parameter.
+ */
+ public synchronized void WriteAllDigital( int data )
+ throws JK8055Exception
+ {
+ if( data<0 || 255<data ) {
+ throw new IllegalArgumentException( "data: "+data );
+ }
+ int retval = CWriteAllDigital( data );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "WriteAllDigital failed" );
+ }
+ }
+
+ /**
+ * @param channel 1..8
+ * @return K8055_ERROR or 0
+ */
+ private native int CClearDigitalChannel( int channel );
+
+ /**
+ * Clears the output channel.
+ * The selected channel is cleared.
+ *
+ * @param channel Value between 1 and 8 which corresponds to the output
+ * channel that is to be cleared.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid channel number.
+ */
+ public synchronized void ClearDigitalChannel( int channel )
+ throws JK8055Exception
+ {
+ if( channel<1 || 8<channel ) {
+ throw new IllegalArgumentException( "channel: "+channel );
+ }
+ int retval = CClearDigitalChannel( channel );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "ClearDigitalChannel failed" );
+ }
+ }
+
+ /**
+ * @return K8055_ERROR or 0
+ */
+ private native int CClearAllDigital();
+
+ /**
+ * Clears all output channels.
+ * All digital outputs are cleared.
+ *
+ * @throws JK8055Exception indicates an error.
+ */
+ public synchronized void ClearAllDigital()
+ throws JK8055Exception
+ {
+ int retval = CClearAllDigital();
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "ClearAllDigital failed" );
+ }
+ }
+
+ /**
+ * @param channel 1..8
+ * @return K8055_ERROR or 0
+ */
+ private native int CSetDigitalChannel( int channel );
+
+ /**
+ * Sets the output channel.
+ * The selected digital output channel is set.
+ *
+ * @param channel Value between 1 and 8 which corresponds to the output
+ * channel that is to be set.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid channel number.
+ */
+ public synchronized void SetDigitalChannel( int channel )
+ throws JK8055Exception
+ {
+ if( channel<1 || 8<channel ) {
+ throw new IllegalArgumentException( "channel: "+channel );
+ }
+ int retval = CSetDigitalChannel( channel );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "SetDigitalChannel failed" );
+ }
+ }
+
+ /**
+ * @return K8055_ERROR or 0
+ */
+ private native int CSetAllDigital();
+
+ /**
+ * Sets all output channels.
+ * All the digital output channels are set.
+ *
+ * @throws JK8055Exception indicates an error.
+ */
+ public synchronized void SetAllDigital()
+ throws JK8055Exception
+ {
+ int retval = CSetAllDigital();
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "SetAllDigital failed" );
+ }
+ }
+
+ /**
+ * @param channel 1..5
+ * @return K8055_ERROR or 0,1
+ */
+ private native int CReadDigitalChannel( int channel );
+
+ /**
+ * Reads the status of the input channel.
+ * The status of the selected Input channel is read.
+ *
+ * @param channel Value between 1 and 5 which corresponds to the input
+ * channel whose status is to be read.
+ * @return TRUE means that the channel has been set and FALSE means that
+ * it has been cleared.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid channel number.
+ */
+ public synchronized boolean ReadDigitalChannel( int channel )
+ throws JK8055Exception
+ {
+ if( channel<1 || 5<channel ) {
+ throw new IllegalArgumentException( "channel: "+channel );
+ }
+ int retval = CReadDigitalChannel( channel );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "ReadDigitalChannel failed" );
+ }
+ return retval != 0;
+ }
+
+ /**
+ * @return K8055_ERROR or 0..31
+ */
+ private native int CReadAllDigital();
+
+ /**
+ * Reads the status of all the input channels.
+ * The function returns the status of the digital inputs.
+ *
+ * @return The 5 LSB correspond to the status of the input channels. A high
+ * (1) means that the channel is HIGH, a low (0) means that the
+ * channel is LOW.
+ * @throws JK8055Exception indicates an error.
+ */
+ public synchronized int ReadAllDigital()
+ throws JK8055Exception
+ {
+ int retval = CReadAllDigital();
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "ReadAllDigital failed" );
+ }
+ return retval;
+ }
+
+ /**
+ * @param counterno 1..2
+ * @return K8055_ERROR or 0
+ */
+ private native int CResetCounter( int counterno );
+
+ /**
+ * Resets the 16 bit pulse counter number 1 or counter number 2.
+ * The selected pulse counter is reset.
+ *
+ * @param counterno Value 1 or 2, which corresponds to the counter to
+ * be reset.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid counter number.
+ */
+ public synchronized void ResetCount( int counterno )
+ throws JK8055Exception
+ {
+ if( counterno<1 || 2<counterno ) {
+ throw new IllegalArgumentException( "counterno: "+counterno );
+ }
+ int retval = CResetCounter( counterno );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "ResetCount failed" );
+ }
+ }
+
+ /**
+ * @param counterno 1..2
+ * @return K8055_ERROR or 0..65535
+ */
+ private native int CReadCounter( int counterno );
+
+ /**
+ * Reads the content of the pulse counter number 1 or counter number 2.
+ * The function returns the status of the selected 16 bit pulse counter.
+ * <br>
+ * The counter number 1 counts the pulses fed to the input I1 and the
+ * counter number 2 counts the pulses fed to the input I2.
+ *
+ * @param counterno Value 1 or 2, which corresponds to the counter to be
+ * read.
+ * @return The content of the 16 bit pulse counter.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid counter number.
+ */
+ public synchronized int ReadCounter( int counterno )
+ throws JK8055Exception
+ {
+ if( counterno<1 || 2<counterno ) {
+ throw new IllegalArgumentException( "counterno: "+counterno );
+ }
+ int retval = CReadCounter( counterno );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "ReadCounter failed" );
+ }
+ return retval;
+ }
+
+ /**
+ * @param counterno 1..2
+ * @param debouncetime 0..7450
+ * @return K8055_ERROR or 0
+ */
+ private native int CSetCounterDebounceTime( int counterno, int debouncetime );
+
+ /**
+ * Sets the debounce time to the pulse counter.
+ * The counter inputs are debounced in the software to prevent false
+ * triggering when mechanical switches or relay inputs are used. The
+ * debounce time is equal for both falling and rising edges. The
+ * default debounce time is 2ms. This means the counter input must be
+ * stable for at least 2ms before it is recognised, giving the maximum
+ * count rate of about 200 counts per second.
+ * <br>
+ * If the debounce time is set to 0, then the maximum counting rate is
+ * about 2000 counts per second.
+ *
+ * @param counterno Value 1 or 2, which corresponds to the counter
+ * to be set.
+ * @param debouncetime (0..7450?) Debounce time for the pulse counter.
+ * <br>
+ * The DebounceTime value corresponds to the debounce
+ * time in milliseconds (ms) to be set for the
+ * pulse counter. Debounce time value may vary between
+ * 0 and 5000?.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid parameter.
+ */
+ public synchronized void SetCounterDebounceTime( int counterno,
+ int debouncetime )
+ throws JK8055Exception
+ {
+ if( counterno<1 || 2<counterno ) {
+ throw new IllegalArgumentException( "counterno: "+counterno );
+ }
+ if( debouncetime<0 || 7450<debouncetime ) {
+ throw new IllegalArgumentException( "debouncetime: "+debouncetime );
+ }
+ int retval = CSetCounterDebounceTime( counterno, debouncetime );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "SetCounterDebounceTime failed" );
+ }
+ }
+
+ public class AllValues {
+ public int input;
+ public int analog1;
+ public int analog2;
+ public int counter1;
+ public int counter2;
+ }
+
+ /**
+ * @param av
+ * @return K8055_ERROR or 0
+ */
+ private native int CReadAllValues( AllValues av );
+
+ /**
+ * Read all values at once.
+ *
+ * @return an new object of type AllValues
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid parameter.
+ */
+ public synchronized AllValues ReadAllValues()
+ throws JK8055Exception
+ {
+ AllValues av = new AllValues();
+ int retval = CReadAllValues( av );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "ReadAllValues failed" );
+ }
+ return av;
+ }
+
+ /**
+ * @param digitaldata 0..255
+ * @param analogdata1 0..255
+ * @param analogdata2 0..255
+ * @return K8055_ERROR or 0
+ */
+ private native int CSetAllValues( int digitaldata,
+ int analogdata1, int analogdata2 );
+
+ /**
+ * Set all values at once.
+ *
+ * @param digitaldata 0..255
+ * @param analogdata1 0..255
+ * @param analogdata2 0..255
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid parameter.
+ */
+ public synchronized void SetAllValues( int digitaldata,
+ int analogdata1, int analogdata2 )
+ throws JK8055Exception
+ {
+ if( digitaldata<1 || 255<digitaldata ) {
+ throw new IllegalArgumentException( "digitaldata: "+digitaldata );
+ }
+ if( analogdata1<1 || 255<analogdata1 ) {
+ throw new IllegalArgumentException( "analogdata1: "+analogdata1 );
+ }
+ if( analogdata2<1 || 255<analogdata2 ) {
+ throw new IllegalArgumentException( "analogdata2: "+analogdata2 );
+ }
+ int retval = CSetAllValues( digitaldata, analogdata1, analogdata2);
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "SetAllValues failed" );
+ }
+ }
+
+ /**
+ * @param deviceno 0..3
+ * @return K8055_ERROR or 0..3
+ */
+ private native int CSetCurrentDevice( int deviceno );
+
+ /**
+ * The function set the current controlled device.
+ * If no device with the address parameter was found.
+ * an JK8055Exception is thrown.
+ *
+ * @param deviceno Value 0 to 3, which corresponds to the device address.
+ * @throws JK8055Exception indicates an error.
+ * @throws IllegalArgumentException indicates an invalid parameter.
+ */
+ public synchronized void SetCurrentDevice( int deviceno )
+ throws JK8055Exception
+ {
+ if( deviceno<0 || 3<deviceno ) {
+ throw new IllegalArgumentException( "deviceno: "+deviceno );
+ }
+ int retval = CSetCurrentDevice( deviceno );
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "SetCurrentDevice failed" );
+ }
+ }
+
+ /**
+ * @return K8055_ERROR or 0..15
+ */
+ private native int CSearchDevices();
+
+ /**
+ * The function returns all connected devices on the computer.
+ * The returned value is a bit field.
+ * <br><b>Note</b>
+ * <br> Once a specific device address is connected with a program
+ * another program can't get access to it.
+ *
+ * @return
+ * <pre>
+ * Bin 0000, Dec 0 : No devices was found
+ * Bin 0001, Dec 1 : Card address 0 was found.
+ * Bin 0010, Dec 2 : Card address 1 was found.
+ * Bin 0100, Dec 4 : Card address 2 was found.
+ * Bin 1000, Dec 8 : Card address 3 was found.
+ * Example : return value 9 = devices with address 0 and 3 are connected.
+ * </pre>
+ * @throws JK8055Exception
+ */
+ public synchronized int SearchDevices()
+ throws JK8055Exception
+ {
+ int retval = CSearchDevices();
+ if( retval == K8055_ERROR ) {
+ throw new JK8055Exception( "SearchDevices failed" );
+ }
+ return retval;
+ }
+
+ private native String CVersion();
+
+ /**
+ * Return the version number of the libk8055 library used.
+ *
+ * @return a string like "0.3"
+ */
+ public synchronized String Version() {
+ return CVersion();
+ }
+
+}
diff --git a/java/src/java/net/sf/libk8055/jk8055/JK8055Exception.java b/java/src/java/net/sf/libk8055/jk8055/JK8055Exception.java
new file mode 100644
index 0000000..d0e7104
--- /dev/null
+++ b/java/src/java/net/sf/libk8055/jk8055/JK8055Exception.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 Martin Pischky (mailto:martin@pischky.de)
+ *
+ * This file (JK8055Exception.java) is part of libk8055/jk8055.
+ * jk8055 - a java wrapper for libk8055
+ *
+ * libk8055/jk8055 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * $Id: JK8055Exception.java,v 1.3 2008/07/14 07:47:55 pischky Exp $
+ *
+ */
+
+package net.sf.libk8055.jk8055;
+
+/**
+ * Exceptions thrown by class JK8055.
+ *
+ * @author Martin Pischky
+ */
+public class JK8055Exception extends Exception {
+
+ public static final String CVS_ID = "$Id: JK8055Exception.java,v 1.3 2008/07/14 07:47:55 pischky Exp $";
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3821577565947420161L;
+
+ /**
+ * Constructor.
+ */
+ public JK8055Exception() {
+ super();
+ }
+
+ /**
+ * Constructor.
+ * @param message
+ */
+ public JK8055Exception(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor.
+ * @param cause
+ */
+ public JK8055Exception(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructor.
+ * @param message
+ * @param cause
+ */
+ public JK8055Exception(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/java/src/java/net/sf/libk8055/jk8055/JK8055Test.java b/java/src/java/net/sf/libk8055/jk8055/JK8055Test.java
new file mode 100644
index 0000000..c2c559c
--- /dev/null
+++ b/java/src/java/net/sf/libk8055/jk8055/JK8055Test.java
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2008 Martin Pischky (mailto:martin@pischky.de)
+ *
+ * This file (JK8055Test.java) is part of libk8055/jk8055.
+ * jk8055 - a java wrapper for libk8055
+ *
+ * libk8055/jk8055 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * $Id: JK8055Test.java,v 1.4 2008/07/14 07:47:55 pischky Exp $
+ *
+ */
+
+package net.sf.libk8055.jk8055;
+
+import junit.framework.TestCase;
+
+/**
+ * JUnit tests for class JK8055.
+ *
+ * If you want to run this from eclipse add
+ * -Djava.library.path=build/c
+ * to VM arguments in run configuration.
+ *
+ * @author Martin Pischky
+ */
+public class JK8055Test extends TestCase {
+
+ public static final int DEVICE = 0;
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ static void sleep( int ms ) {
+ try {
+ Thread.sleep( ms );
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void testGetInstance() {
+ JK8055.getInstance();
+ }
+
+ public void testOpenCloseDevice() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.CloseDevice();
+ }
+
+ public void testReadAnalogChannel() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ int a1 = jk8055.ReadAnalogChannel(1);
+ int a2 = jk8055.ReadAnalogChannel(2);
+ assertTrue("a1>=0", a1>=0 );
+ assertTrue("a1<=255",a1<=255);
+ assertTrue("a2>=0", a2>=0 );
+ assertTrue("a2<=255",a2<=255);
+ jk8055.CloseDevice();
+ }
+
+ public void testReadAllAnalog() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ JK8055.AllAnalog aa = jk8055.ReadAllAnalog();
+ assertTrue( "aa.data1>=0", aa.data1>=0 );
+ assertTrue( "aa.data1<=255",aa.data1<=255 );
+ assertTrue( "aa.data2>=0", aa.data2>=0 );
+ assertTrue( "aa.data2<=255",aa.data2<=255 );
+ int a1 = jk8055.ReadAnalogChannel(1);
+ int a2 = jk8055.ReadAnalogChannel(2);
+ assertTrue( "a1 ~= aa.data1", Math.abs(a1-aa.data1)<2 );
+ assertTrue( "a2 ~= aa.data2", Math.abs(a2-aa.data2)<2 );
+ jk8055.CloseDevice();
+ }
+
+ public void testOutputAnalogChannel() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.OutputAnalogChannel( 1, 0 );
+ jk8055.OutputAnalogChannel( 2, 255 );
+ sleep( 500 );
+ for (int i = 0; i <= 255; i++) {
+ jk8055.OutputAnalogChannel( 1, i );
+ jk8055.OutputAnalogChannel( 2, 255-i );
+ }
+ for (int i = 255; i >= 0; i--) {
+ jk8055.OutputAnalogChannel( 1, i );
+ jk8055.OutputAnalogChannel( 2, 255-i );
+ }
+ sleep( 500 );
+ jk8055.OutputAnalogChannel( 1, 0 );
+ jk8055.OutputAnalogChannel( 2, 0 );
+ jk8055.CloseDevice();
+ }
+
+ public void testOutputAllAnalog() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.OutputAllAnalog( 0, 255 );
+ sleep( 500 );
+ for (int i = 0; i <= 255; i++) {
+ jk8055.OutputAllAnalog( i, 255-i );
+ }
+ for (int i = 255; i >= 0; i--) {
+ jk8055.OutputAllAnalog( i, 255-i );
+ }
+ sleep( 500 );
+ jk8055.OutputAllAnalog( 0, 0 );
+ jk8055.CloseDevice();
+ }
+
+ public void testClearAllAnalog() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.ClearAllAnalog();
+ jk8055.CloseDevice();
+ }
+
+ public void testClearAnalogChannel() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.ClearAnalogChannel( 1 );
+ jk8055.ClearAnalogChannel( 2 );
+ jk8055.CloseDevice();
+ }
+
+ public void testSetAnalogChannel() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.SetAnalogChannel( 1 );
+ jk8055.SetAnalogChannel( 2 );
+ jk8055.CloseDevice();
+ }
+
+ public void testSetAllAnalog() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.SetAllAnalog();
+ jk8055.CloseDevice();
+ }
+
+ public void testWriteAllDigital() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.WriteAllDigital( 0 );
+ for (int i = 0; i <= 7; i++) {
+ jk8055.WriteAllDigital( 1<<i );
+ sleep( 50 );
+ }
+ for (int i = 7; i >= 0; i--) {
+ jk8055.WriteAllDigital( 1<<i );
+ sleep( 50 );
+ }
+ jk8055.WriteAllDigital( 0 );
+ jk8055.CloseDevice();
+ }
+
+ public void testClearDigitalChannel() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ for (int i = 1; i <= 8; i++) {
+ jk8055.ClearDigitalChannel( i );
+ }
+ jk8055.CloseDevice();
+ }
+
+ public void testClearAllDigital() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.ClearAllDigital();
+ jk8055.CloseDevice();
+ }
+
+ public void testSetDigitalChannel() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ for (int i = 1; i <= 8; i++) {
+ jk8055.SetDigitalChannel( i );
+ }
+ jk8055.CloseDevice();
+ }
+
+ public void testSetAllDigital() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.SetAllDigital();
+ jk8055.CloseDevice();
+ }
+
+ public void testReadDigitalChannel() throws JK8055Exception {
+ System.out.println( "---- testReadDigitalChannel()" );
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ for (int i = 1; i <= 5; i++) {
+ boolean b = jk8055.ReadDigitalChannel( i );
+ System.out.println( "Inp"+i+"="+b );
+ }
+ jk8055.CloseDevice();
+ }
+
+ public void testReadAllDigital() throws JK8055Exception {
+ System.out.println( "---- testReadAllDigital()" );
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ int data = jk8055.ReadAllDigital();
+ assertTrue("data>=0", data>=0 );
+ assertTrue("data<=255",data<=255);
+ for (int i = 1; i <= 5; i++) {
+ boolean b = (data & (1<<(i-1))) != 0;
+ System.out.println( "Inp"+i+"="+b );
+ }
+ jk8055.CloseDevice();
+ }
+
+ public void testResetCount() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.ResetCount( 1 );
+ jk8055.ResetCount( 2 );
+ jk8055.CloseDevice();
+ }
+
+ public void testReadCounter() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ int c1 = jk8055.ReadCounter( 1 );
+ int c2 = jk8055.ReadCounter( 2 );
+ assertTrue( "c1", 0<=c1 && c1<=65535 );
+ assertTrue( "c2", 0<=c2 && c2<=65535 );
+ jk8055.CloseDevice();
+ }
+
+ public void testSetCounterDebounceTime() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.SetCounterDebounceTime( 1, 1214 );
+ jk8055.SetCounterDebounceTime( 2, 1214 );
+ jk8055.CloseDevice();
+ }
+
+ public void testReadAllValues() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ JK8055.AllValues av = jk8055.ReadAllValues();
+ assertTrue( "av.input>=0", av.input>=0 );
+ assertTrue( "av.input<=32", av.input<=32 );
+ assertTrue( "av.analog1>=0", av.analog1>=0 );
+ assertTrue( "av.analog1<=255", av.analog2<=255 );
+ assertTrue( "av.analog2>=0", av.analog2>=0 );
+ assertTrue( "av.analog2<=255", av.analog2<=255 );
+ assertTrue( "av.counter1>=0", av.counter1>=0 );
+ assertTrue( "av.counter1<=65535", av.counter1<=65535 );
+ assertTrue( "av.counter2>=0", av.counter2>=0 );
+ assertTrue( "av.counter2<=65535", av.counter2<=65535 );
+ int a1 = jk8055.ReadAnalogChannel(1);
+ int a2 = jk8055.ReadAnalogChannel(2);
+ assertTrue( "a1 ~= aa.data1", Math.abs(a1-av.analog1)<2 );
+ assertTrue( "a2 ~= aa.data2", Math.abs(a2-av.analog2)<2 );
+ jk8055.CloseDevice();
+ }
+
+ public void testSetAllValues() throws JK8055Exception {
+ JK8055 jk8055 = JK8055.getInstance();
+ jk8055.OpenDevice( DEVICE );
+ jk8055.SetAllValues( 123, 232, 87 );
+ jk8055.CloseDevice();
+ }
+
+ public void testSetCurrentDevice() throws JK8055Exception {
+ System.out.println( "---- testSetCurrentDevice()" );
+ JK8055 jk8055 = JK8055.getInstance();
+ int d = jk8055.SearchDevices();
+ if( d == 0 ) {
+ System.out.println( "No devices found." );
+ } else {
+ for (int i = 0; i <= 3; i++) {
+ if( (d & (1<<i)) != 0 ) {
+ System.out.println( "Device with card address "+i+" was found." );
+ }
+ }
+ }
+ jk8055.CloseDevice(); // required for windows version ?!?
+ for (int i = 0; i <= 3; i++) {
+ if( (d & (1<<i)) != 0 ) {
+ System.out.println( "OpenDevice("+i+")" );
+ jk8055.OpenDevice( i );
+ }
+ }
+ for (int i = 0; i <= 3; i++) {
+ if( (d & (1<<i)) != 0 ) {
+ System.out.println( "SetCurrentDevice("+i+")" );
+ jk8055.SetCurrentDevice( i );
+ System.out.println( "WriteAllDigital("+(1<<i)+")" );
+ jk8055.WriteAllDigital( 1<<i );
+ }
+ }
+ for (int i = 0; i <= 3; i++) {
+ if( (d & (1<<i)) == 0 ) {
+ boolean exThrown = false;
+ try {
+ jk8055.SetCurrentDevice( i );
+ } catch( JK8055Exception ex ) {
+ exThrown = true;
+ }
+ assertTrue( "exThrown", exThrown );
+ }
+ }
+ for (int i = 0; i <= 3; i++) {
+ if( (d & (1<<i)) != 0 ) {
+ System.out.println( "SetCurrentDevice("+i+")" );
+ jk8055.SetCurrentDevice( i );
+ System.out.println( "CloseDevice()" );
+ jk8055.CloseDevice();
+ }
+ }
+ }
+
+ public void testCloseAllOpenDevices() throws JK8055Exception {
+ System.out.println( "---- testCloseAllOpenDevices()" );
+ JK8055 jk8055 = JK8055.getInstance();
+ int d = jk8055.SearchDevices();
+ if( d == 0 ) {
+ System.out.println( "No devices found." );
+ } else {
+ for (int i = 0; i <= 3; i++) {
+ if( (d & (1<<i)) != 0 ) {
+ System.out.println( "Device with card address "+i+" was found." );
+ }
+ }
+ }
+ jk8055.CloseDevice(); // required for windows version ?!?
+ for (int i = 0; i <= 3; i++) {
+ if( (d & (1<<i)) != 0 ) {
+ System.out.println( "OpenDevice("+i+")" );
+ jk8055.OpenDevice( i );
+ }
+ }
+ for (int i = 0; i <= 3; i++) {
+ if( (d & (1<<i)) != 0 ) {
+ System.out.println( "SetCurrentDevice("+i+")" );
+ jk8055.SetCurrentDevice( i );
+ System.out.println( "WriteAllDigital("+(1<<i)+")" );
+ jk8055.WriteAllDigital( 1<<i );
+ }
+ }
+ jk8055.CloseAllOpenDevices();
+ }
+
+ public void testSearchDevices() throws JK8055Exception {
+ System.out.println( "---- testSearchDevices()" );
+ JK8055 jk8055 = JK8055.getInstance();
+ //jk8055.OpenDevice( DEVICE );
+ // Windows Version (Velleman DDL v2)
+ // does not return devices already opened
+ int d = jk8055.SearchDevices();
+ if( d == 0 ) {
+ System.out.println( "No devices found." );
+ } else {
+ for (int i = 0; i <= 3; i++) {
+ if( (d & (1<<i)) != 0 ) {
+ System.out.println( "Device with card address "+i+" was found." );
+ }
+ }
+ }
+ jk8055.CloseDevice();
+ }
+
+ public void testVersion() {
+ System.out.println( "---- testVersion()" );
+ assertNotNull( JK8055.getInstance().Version() );
+ assertTrue( JK8055.getInstance().Version().length() > 0 );
+ System.out.println( "version=\""+JK8055.getInstance().Version()+"\"" );
+ }
+
+}
diff --git a/java/src/java/net/sf/libk8055/jk8055/overview.html b/java/src/java/net/sf/libk8055/jk8055/overview.html
new file mode 100644
index 0000000..2fff579
--- /dev/null
+++ b/java/src/java/net/sf/libk8055/jk8055/overview.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+<p>
+This document is the API specification for JK8055 - A java wrapper for libk8055.
+</p>
+</body>
+</html>
diff --git a/java/src/java/net/sf/libk8055/jk8055/package.html b/java/src/java/net/sf/libk8055/jk8055/package.html
new file mode 100644
index 0000000..4dba573
--- /dev/null
+++ b/java/src/java/net/sf/libk8055/jk8055/package.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+<p>JK8055 - A java wrapper for libk8055.</p>
+<p>The wrapper can be used on Linux with libk8055 (see
+<a href="http://libk8055.sourceforge.net/">http://libk8055.sourceforge.net/</a>)
+or the standard Vellemann DLLs on Windows.
+</body>
+</html>
diff --git a/k8055.h b/k8055.h
new file mode 100644
index 0000000..4d5ae81
--- /dev/null
+++ b/k8055.h
@@ -0,0 +1,55 @@
+/* $Id: k8055.h,v 1.4 2008/05/21 20:25:51 mr_brain Exp $
+
+ This file is part of the libk8055 Library.
+
+ The libk8055 Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The libk8055 Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ http://opensource.org/licenses/
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* prototypes */
+int OpenDevice(long board_address);
+int CloseDevice();
+long ReadAnalogChannel(long Channelno);
+int ReadAllAnalog(long* data1, long* data2);
+int OutputAnalogChannel(long channel, long data);
+int OutputAllAnalog(long data1,long data2);
+int ClearAllAnalog();
+int ClearAnalogChannel(long channel);
+int SetAnalogChannel(long channel);
+int SetAllAnalog();
+int WriteAllDigital(long data);
+int ClearDigitalChannel(long channel);
+int ClearAllDigital();
+int SetDigitalChannel(long channel);
+int SetAllDigital();
+int ReadDigitalChannel(long channel);
+long ReadAllDigital();
+int ResetCounter(long counternr);
+long ReadCounter(long counterno);
+int SetCounterDebounceTime(long counterno, long debouncetime);
+int ReadAllValues (long int *data1, long int *data2, long int *data3, long int *data4, long int *data5);
+int SetAllValues(int digitaldata, int addata1, int addata2);
+long SetCurrentDevice(long deviceno);
+long SearchDevices(void);
+char *Version(void);
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/libk8055.c b/libk8055.c
new file mode 100644
index 0000000..9556294
--- /dev/null
+++ b/libk8055.c
@@ -0,0 +1,600 @@
+/* $Id: libk8055.c,v 1.7 2008/08/20 17:00:55 mr_brain Exp $
+
+ This file is part of the libk8055 Library.
+
+ The libk8055 Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The libk8055 Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ http://opensource.org/licenses/
+
+ Copyleft (C) 2005 by Sven Lindberg
+ k8055@k8055.mine.nu
+
+ Copyright (C) 2007 by Pjetur G. Hjaltason
+ pjetur@pjetur.net
+ Commenting, general rearrangement of code, bugfixes,
+ python interface with swig and simple k8055 python class
+
+
+ Input packet format
+
+ +---+---+---+---+---+---+---+---+
+ |DIn|Sta|A1 |A2 | C1 | C2 |
+ +---+---+---+---+---+---+---+---+
+ DIn = Digital input in high nibble, except for input 3 in 0x01
+ Sta = Status, Board number + 1
+ A1 = Analog input 1, 0-255
+ A2 = Analog input 2, 0-255
+ C1 = Counter 1, 16 bits (lsb)
+ C2 = Counter 2, 16 bits (lsb)
+
+ Output packet format
+
+ +---+---+---+---+---+---+---+---+
+ |CMD|DIG|An1|An2|Rs1|Rs2|Dbv|Dbv|
+ +---+---+---+---+---+---+---+---+
+ CMD = Command
+ DIG = Digital output bitmask
+ An1 = Analog output 1 value, 0-255
+ An2 = Analog output 2 value, 0-255
+ Rs1 = Reset counter 1, command 3
+ Rs2 = Reset counter 3, command 4
+ Dbv = Debounce value for counter 1 and 2, command 1 and 2
+
+ Or split by commands
+
+ Cmd 0, Reset ??
+ Cmd 1, Set debounce Counter 1
+ +---+---+---+---+---+---+---+---+
+ |CMD| | | | | |Dbv| |
+ +---+---+---+---+---+---+---+---+
+ Cmd 2, Set debounce Counter 2
+ +---+---+---+---+---+---+---+---+
+ |CMD| | | | | | |Dbv|
+ +---+---+---+---+---+---+---+---+
+ Cmd 3, Reset counter 1
+ +---+---+---+---+---+---+---+---+
+ | 3 | | | | 00| | | |
+ +---+---+---+---+---+---+---+---+
+ Cmd 4, Reset counter 2
+ +---+---+---+---+---+---+---+---+
+ | 4 | | | | | 00| | |
+ +---+---+---+---+---+---+---+---+
+ cmd 5, Set analog/digital
+ +---+---+---+---+---+---+---+---+
+ | 5 |DIG|An1|An2| | | | |
+ +---+---+---+---+---+---+---+---+
+
+**/
+
+#include <string.h>
+#include <stdio.h>
+#include <usb.h>
+#include <assert.h>
+#include <math.h>
+#include "k8055.h"
+
+#define STR_BUFF 256
+#define PACKET_LEN 8
+
+#define K8055_IPID 0x5500
+#define VELLEMAN_VENDOR_ID 0x10cf
+#define K8055_MAX_DEV 4
+
+#define USB_OUT_EP 0x01 /* USB output endpoint */
+#define USB_INP_EP 0x81 /* USB Input endpoint */
+
+#define USB_TIMEOUT 20
+#define K8055_ERROR -1
+
+#define DIGITAL_INP_OFFSET 0
+#define DIGITAL_OUT_OFFSET 1
+#define ANALOG_1_OFFSET 2
+#define ANALOG_2_OFFSET 3
+#define COUNTER_1_OFFSET 4
+#define COUNTER_2_OFFSET 6
+
+#define CMD_RESET 0x00
+#define CMD_SET_DEBOUNCE_1 0x01
+#define CMD_SET_DEBOUNCE_2 0x01
+#define CMD_RESET_COUNTER_1 0x03
+#define CMD_RESET_COUNTER_2 0x04
+#define CMD_SET_ANALOG_DIGITAL 0x05
+
+/* set debug to 0 to not print excess info */
+int DEBUG = 0;
+
+/* variables for usb */
+static struct usb_bus *bus, *busses;
+static struct usb_device *dev;
+
+/* globals for datatransfer */
+struct k8055_dev {
+ unsigned char data_in[PACKET_LEN+1];
+ unsigned char data_out[PACKET_LEN+1];
+ struct usb_dev_handle *device_handle;
+ int DevNo;
+};
+
+static struct k8055_dev k8055d[K8055_MAX_DEV];
+static struct k8055_dev *CurrDev;
+
+/* Keep these globals for now */
+unsigned char *data_in, *data_out;
+
+/* char* device_id[]; */
+
+/* Initialize the usb library - only once */
+static void init_usb(void)
+{
+ static int Done = 0; /* Only need to do this once */
+ if (!Done)
+ {
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+ busses = usb_get_busses();
+ Done = 1;
+ }
+}
+/* Actual read of data from the device endpoint, retry 3 times if not responding ok */
+static int ReadK8055Data(void)
+{
+ int read_status = 0, i = 0;
+
+ if (CurrDev->DevNo == 0) return K8055_ERROR;
+
+ for(i=0; i < 3; i++)
+ {
+ read_status = usb_interrupt_read(CurrDev->device_handle, USB_INP_EP, (char *)CurrDev->data_in, PACKET_LEN, USB_TIMEOUT);
+ if ((read_status == PACKET_LEN) && (CurrDev->data_in[1] == CurrDev->DevNo )) return 0;
+ if (DEBUG)
+ fprintf(stderr, "Read retry\n");
+ }
+ return K8055_ERROR;
+}
+
+/* Actual write of data to the device endpont, retry 3 times if not reponding correctly */
+static int WriteK8055Data(unsigned char cmd)
+{
+ int write_status = 0, i = 0;
+
+ if (CurrDev->DevNo == 0) return K8055_ERROR;
+
+ CurrDev->data_out[0] = cmd;
+ for(i=0; i < 3; i++)
+ {
+ write_status = usb_interrupt_write(CurrDev->device_handle, USB_OUT_EP, (char *)CurrDev->data_out, PACKET_LEN, USB_TIMEOUT);
+ if (write_status == PACKET_LEN) return 0;
+ if (DEBUG)
+ fprintf(stderr, "Write retry\n");
+ }
+ return K8055_ERROR;
+}
+
+/* If device is owned by some kernel driver, try to disconnect it and claim the device*/
+static int takeover_device(usb_dev_handle * udev, int interface)
+{
+ char driver_name[STR_BUFF];
+
+ memset(driver_name, 0, STR_BUFF);
+ int ret = K8055_ERROR;
+
+ assert(udev != NULL);
+ ret = usb_get_driver_np(udev, interface, driver_name, sizeof(driver_name));
+ if (ret == 0)
+ {
+ if (DEBUG)
+ fprintf(stderr, "Got driver name: %s\n", driver_name);
+ if (0 > usb_detach_kernel_driver_np(udev, interface))
+ {
+ if (DEBUG)
+ fprintf(stderr, "Disconnect OS driver: %s\n", usb_strerror());
+ }
+ else if (DEBUG)
+ fprintf(stderr, "Disconnected OS driver: %s\n", usb_strerror());
+ }
+ else if (DEBUG)
+ fprintf(stderr, "Get driver name: - %s\n", usb_strerror());
+
+ /* claim interface */
+ if (usb_claim_interface(udev, interface) < 0)
+ {
+ if (DEBUG)
+ fprintf(stderr, "Claim interface error: %s\n", usb_strerror());
+ return K8055_ERROR;
+ }
+ else
+ usb_set_altinterface(udev, interface);
+ usb_set_configuration(udev, 1);
+
+ if (DEBUG)
+ {
+ fprintf(stderr, "Found interface %d\n", interface);
+ fprintf(stderr, "Took over the device\n");
+ }
+
+ return 0;
+}
+
+/* Open device - scan through usb busses looking for the right device,
+ claim it and then open the device
+*/
+int OpenDevice(long BoardAddress)
+{
+
+ int ipid;
+
+ /* init USB and find all of the devices on all busses */
+ init_usb();
+
+ /* ID of the welleman board is 5500h + address config */
+ if (BoardAddress >= 0 && BoardAddress < K8055_MAX_DEV)
+ ipid = K8055_IPID + (int)BoardAddress;
+ else
+ return K8055_ERROR; /* throw error instead of being nice */
+
+ /* start looping through the devices to find the correct one */
+ for (bus = busses; bus; bus = bus->next)
+ {
+ for (dev = bus->devices; dev; dev = dev->next)
+ {
+ if ((dev->descriptor.idVendor == VELLEMAN_VENDOR_ID) &&
+ (dev->descriptor.idProduct == ipid))
+ {
+ CurrDev = &k8055d[BoardAddress];
+ CurrDev->device_handle = usb_open(dev);
+ if (DEBUG)
+ fprintf(stderr,
+ "Velleman Device Found @ Address %s Vendor 0x0%x Product ID 0x0%x\n",
+ dev->filename, dev->descriptor.idVendor,
+ dev->descriptor.idProduct);
+ if (takeover_device(CurrDev->device_handle, 0) < 0)
+ {
+ if (DEBUG)
+ fprintf(stderr,
+ "Can not take over the device from the OS driver\n");
+ usb_close(CurrDev->device_handle); /* close usb if we fail */
+ return K8055_ERROR; /* throw K8055_ERROR to show that OpenDevice failed */
+ }
+ else
+ {
+ CurrDev->DevNo = BoardAddress + 1; /* Mark as open and valid */
+ SetCurrentDevice(BoardAddress);
+ memset(CurrDev->data_out,0,PACKET_LEN); /* Write cmd 0, read data */
+ WriteK8055Data(CMD_RESET);
+ if (ReadK8055Data() == 0)
+ return BoardAddress; /* This function should return board address */
+ else
+ return K8055_ERROR;
+ }
+ }
+ }
+ }
+ if (DEBUG)
+ fprintf(stderr, "Could not find Velleman k8055 with address %d\n",
+ (int)BoardAddress);
+ return K8055_ERROR;
+}
+
+/* Close the Current device */
+int CloseDevice()
+{
+ int rc;
+
+ if (CurrDev->DevNo == 0)
+ {
+ if (DEBUG)
+ fprintf(stderr, "Current device is not open\n" );
+ return 0;
+ }
+ rc = usb_close(CurrDev->device_handle);
+ if (rc >= 0)
+ {
+ CurrDev->DevNo = 0; /* Not active nay more */
+ CurrDev->device_handle = NULL;
+ }
+ return rc;
+}
+
+/* New function in version 2 of Velleman DLL, should return deviceno if OK */
+long SetCurrentDevice(long deviceno)
+{
+ if (deviceno >= 0 && deviceno < K8055_MAX_DEV)
+ {
+ if (k8055d[deviceno].DevNo != 0)
+ {
+ CurrDev = &k8055d[deviceno];
+ data_in = CurrDev->data_in;
+ data_out = CurrDev->data_out;
+ return deviceno;
+ }
+ }
+ return K8055_ERROR;
+
+}
+
+/* New function in version 2 of Velleman DLL, should return devices-found bitmask or 0*/
+long SearchDevices(void)
+{
+ int retval = 0;
+ init_usb();
+ /* start looping through the devices to find the correct one */
+ for (bus = busses; bus; bus = bus->next)
+ {
+ for (dev = bus->devices; dev; dev = dev->next)
+ {
+ if (dev->descriptor.idVendor == VELLEMAN_VENDOR_ID) {
+ if(dev->descriptor.idProduct == K8055_IPID + 0) retval |= 0x01;
+ if(dev->descriptor.idProduct == K8055_IPID + 1) retval |= 0x02;
+ if(dev->descriptor.idProduct == K8055_IPID + 2) retval |= 0x04;
+ if(dev->descriptor.idProduct == K8055_IPID + 3) retval |= 0x08;
+ /* else some other kind of Velleman board */
+ }
+ }
+ }
+ return retval;
+}
+
+long ReadAnalogChannel(long Channel)
+{
+ if (Channel == 1 || Channel == 2)
+ {
+ if ( ReadK8055Data() == 0)
+ {
+ if (Channel == 2)
+ return CurrDev->data_in[ANALOG_2_OFFSET];
+ else
+ return CurrDev->data_in[ANALOG_1_OFFSET];
+ }
+ else
+ return K8055_ERROR;
+ }
+ else
+ return K8055_ERROR;
+}
+
+int ReadAllAnalog(long *data1, long *data2)
+{
+ if (ReadK8055Data() == 0)
+ {
+ *data1 = CurrDev->data_in[ANALOG_1_OFFSET];
+ *data2 = CurrDev->data_in[ANALOG_2_OFFSET];
+ return 0;
+ }
+ else
+ return K8055_ERROR;
+}
+
+int OutputAnalogChannel(long Channel, long data)
+{
+ if (Channel == 1 || Channel == 2)
+ {
+ if (Channel == 2)
+ CurrDev->data_out[ANALOG_2_OFFSET] = (unsigned char)data;
+ else
+ CurrDev->data_out[ANALOG_1_OFFSET] = (unsigned char)data;
+
+ return WriteK8055Data(CMD_SET_ANALOG_DIGITAL);
+ }
+ else
+ return K8055_ERROR;
+}
+
+int OutputAllAnalog(long data1, long data2)
+{
+ CurrDev->data_out[2] = (unsigned char)data1;
+ CurrDev->data_out[3] = (unsigned char)data2;
+
+ return WriteK8055Data(CMD_SET_ANALOG_DIGITAL);
+}
+
+int ClearAllAnalog()
+{
+ return OutputAllAnalog(0, 0);
+}
+
+int ClearAnalogChannel(long Channel)
+{
+ if (Channel == 1 || Channel == 2)
+ {
+ if (Channel == 2)
+ return OutputAnalogChannel(2, 0);
+ else
+ return OutputAnalogChannel(1, 0);
+ }
+ else
+ return K8055_ERROR;
+}
+
+int SetAnalogChannel(long Channel)
+{
+ if (Channel == 1 || Channel == 2)
+ {
+ if (Channel == 2)
+ return OutputAnalogChannel(2, 0xff);
+ else
+ return OutputAnalogChannel(1, 0xff);
+ }
+ else
+ return K8055_ERROR;
+
+}
+
+int SetAllAnalog()
+{
+ return OutputAllAnalog(0xff, 0xff);
+}
+
+int WriteAllDigital(long data)
+{
+ CurrDev->data_out[1] = (unsigned char)data;
+ return WriteK8055Data(CMD_SET_ANALOG_DIGITAL);
+}
+
+int ClearDigitalChannel(long Channel)
+{
+ unsigned char data;
+
+ if (Channel > 0 && Channel < 9)
+ {
+ data = CurrDev->data_out[1] & ~(1 << (Channel-1));
+ return WriteAllDigital(data);
+ }
+ else
+ return K8055_ERROR;
+}
+
+int ClearAllDigital()
+{
+ return WriteAllDigital(0x00);
+}
+
+int SetDigitalChannel(long Channel)
+{
+ unsigned char data;
+
+ if (Channel > 0 && Channel < 9)
+ {
+ data = CurrDev->data_out[1] | (1 << (Channel-1));
+ return WriteAllDigital(data);
+ }
+ else
+ return K8055_ERROR;
+}
+
+int SetAllDigital()
+{
+ return WriteAllDigital(0xff);
+}
+
+int ReadDigitalChannel(long Channel)
+{
+ int rval;
+ if (Channel > 0 && Channel < 9)
+ {
+ if ((rval = ReadAllDigital()) == K8055_ERROR) return K8055_ERROR;
+ return ((rval & (1 << (Channel-1))) > 0);
+ }
+ else
+ return K8055_ERROR;
+}
+
+long ReadAllDigital()
+{
+ int return_data = 0;
+
+ if (ReadK8055Data() == 0)
+ {
+ return_data = (
+ ((CurrDev->data_in[0] >> 4) & 0x03) | /* Input 1 and 2 */
+ ((CurrDev->data_in[0] << 2) & 0x04) | /* Input 3 */
+ ((CurrDev->data_in[0] >> 3) & 0x18) ); /* Input 4 and 5 */
+ return return_data;
+ }
+ else
+ return K8055_ERROR;
+}
+
+int ReadAllValues(long int *data1, long int * data2, long int * data3, long int * data4, long int * data5)
+{
+ if (ReadK8055Data() == 0)
+ {
+ *data1 = (
+ ((CurrDev->data_in[0] >> 4) & 0x03) | /* Input 1 and 2 */
+ ((CurrDev->data_in[0] << 2) & 0x04) | /* Input 3 */
+ ((CurrDev->data_in[0] >> 3) & 0x18) ); /* Input 4 and 5 */
+ *data2 = CurrDev->data_in[ANALOG_1_OFFSET];
+ *data3 = CurrDev->data_in[ANALOG_2_OFFSET];
+ *data4 = *((short int *)(&CurrDev->data_in[COUNTER_1_OFFSET]));
+ *data5 = *((short int *)(&CurrDev->data_in[COUNTER_2_OFFSET]));
+ return 0;
+ }
+ else
+ return K8055_ERROR;
+}
+
+int SetAllValues(int DigitalData, int AdData1, int AdData2)
+{
+ CurrDev->data_out[1] = (unsigned char)DigitalData;
+ CurrDev->data_out[2] = (unsigned char)AdData1;
+ CurrDev->data_out[3] = (unsigned char)AdData2;
+
+ return WriteK8055Data(CMD_SET_ANALOG_DIGITAL);
+}
+
+int ResetCounter(long CounterNo)
+{
+ if (CounterNo == 1 || CounterNo == 2)
+ {
+ CurrDev->data_out[0] = 0x02 + (unsigned char)CounterNo; /* counter selection */
+ CurrDev->data_out[3 + CounterNo] = 0x00;
+ return WriteK8055Data(CurrDev->data_out[0]);
+ }
+ else
+ return K8055_ERROR;
+}
+
+long ReadCounter(long CounterNo)
+{
+ if (CounterNo == 1 || CounterNo == 2)
+ {
+ if (ReadK8055Data() == 0)
+ {
+ if (CounterNo == 2)
+ return *((short int *)(&CurrDev->data_in[COUNTER_2_OFFSET]));
+ else
+ return *((short int *)(&CurrDev->data_in[COUNTER_1_OFFSET]));
+ }
+ else
+ return K8055_ERROR;
+ }
+ else
+ return K8055_ERROR;
+}
+
+int SetCounterDebounceTime(long CounterNo, long DebounceTime)
+{
+ float value;
+
+ if (CounterNo == 1 || CounterNo == 2)
+ {
+ CurrDev->data_out[0] = (unsigned char)CounterNo;
+ /* the velleman k8055 use a exponetial formula to split up the
+ DebounceTime 0-7450 over value 1-255. I've tested every value and
+ found that the formula dbt=0,338*value^1,8017 is closest to
+ vellemans dll. By testing and measuring times on the other hand I
+ found the formula dbt=0,115*x^2 quite near the actual values, a
+ little below at really low values and a little above at really
+ high values. But the time set with this formula is within +-4% */
+ if (DebounceTime > 7450)
+ DebounceTime = 7450;
+ value = sqrtf(DebounceTime / 0.115);
+ if (value > ((int)value + 0.49999999)) /* simple round() function) */
+ value += 1;
+ CurrDev->data_out[5 + CounterNo] = (unsigned char)value;
+ if (DEBUG)
+ fprintf(stderr, "Debouncetime%d value for k8055:%d\n",
+ (int)CounterNo, CurrDev->data_out[5 + CounterNo]);
+ return WriteK8055Data(CurrDev->data_out[0]);
+ }
+ else
+ return K8055_ERROR;
+}
+
+char * Version(void)
+{
+ return(VERSION);
+}
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..a6fa602
--- /dev/null
+++ b/main.c
@@ -0,0 +1,295 @@
+/* $Id: main.c,v 1.3 2007/03/15 14:37:58 pjetur Exp $
+ ***************************************************************************
+ * Copyright (C) 2004 by Nicolas Sutre *
+ * nicolas.sutre@free.fr *
+ * *
+ * Copyright (C) 2005 by Bob Dempsey *
+ * bdempsey_64@msn.com *
+ * *
+ * Copyright (C) 2005 by Julien Etelain and Edward Nys *
+ * Converted to C *
+ * Commented and improved by Julien Etelain <julien.etelain@utbm.fr> *
+ * Edward Nys <edward.ny@utbm.fr> *
+ * *
+ * Copyleft (L) 2005 by Sven Lindberg *
+ * k8055@k8055.mine.nu *
+ * Give it up already :) Simplified (read improved..) and included *
+ * with k8055 lib and with a functional man page *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <string.h>
+#include <stdio.h>
+#include <usb.h>
+#include <assert.h>
+#include <sys/time.h>
+#include "k8055.h"
+
+#define STR_BUFF 256
+#define false 0
+#define true 1
+
+extern int DEBUG;
+
+int ia1 = -1;
+int ia2 = -1;
+int id8 = -1;
+int ipid = 0;
+
+int numread = 1;
+
+int debug = 0;
+
+int dbt1 = -1; // (-1 => not to set)
+int dbt2 = -1; // (-1 => not to set)
+
+int resetcnt1 = false;
+int resetcnt2 = false;
+
+int delay = 0;
+
+/*
+ Convert a string on n chars to an integer
+ Return 1 on sucess
+ 0 on failure (non number)
+*/
+int Convert_StringToInt(char *text, int *i)
+{
+ return sscanf(text, "%d", i);
+}
+
+/*
+ Write help to standard output
+*/
+void display_help ( char *params[] ) {
+
+ printf("K8055 version %s MrBrain Build\n",Version());
+ printf("Copyright (C) 2004 by Nicolas Sutre\n");
+ printf("Copyright (C) 2005 by Bob Dempsey\n");
+ printf("Copyright (C) 2005 by Julien Etelain and Edward Nys\n");
+ printf("Copyleft (L) 2005 by Sven Lindberg\n");
+ printf("\n");
+ printf("Syntax : %s [-p:(number)] [-d:(value)] [-a1:(value)] [-a2:(value)]\n",params[0]);
+ printf(" [-num:(number) [-delay:(number)] [-dbt1:(value)]\n");
+ printf(" [-dbt2:(value)] [-reset1] [-reset2] [-debug]\n");
+ printf(" -p:(number) Set board number\n");
+ printf(" -d:(value) Set digital output value (8 bits in decimal)\n");
+ printf(" -a1:(value) Set analog output 1 value (0-255)\n");
+ printf(" -a2:(value) Set analog output 2 value (0-255)\n");
+ printf(" -num:(number) Set number of measures\n");
+ printf(" -delay:(number) Set delay between two measure (in msec)\n");
+ printf(" -dbt1:(value) Set debounce time for counter 1 (in msec)\n");
+ printf(" -dbt2:(value) Set debounce time for counter 2 (in msec)\n");
+ printf(" -reset1 Reset counter 1\n");
+ printf(" -reset2 Reset counter 2\n");
+ printf(" -debug Activate debug mode\n");
+ printf("Example : %s -p:1 -d:147 -a1:25 -a2:203\n",params[0]);
+ printf("\n");
+ printf("Output : (timestamp);(digital);(analog 1);(analog 2);(counter 1);(counter 2)\n");
+ printf("Note : timestamp is the number of msec when data is read since program start\n");
+ printf("Example : 499;16;128;230;9;8\n");
+ printf("499 : Measure done 499 msec after program start\n");
+
+}
+
+
+/*
+ Read arguments, and store values
+ Return true if arguments are valid
+ else return false
+*/
+int read_param(int argc,char *params[])
+{
+ int erreurParam = false;
+ int i;
+
+ ipid = 0;
+
+ for (i=1; i<argc;i++)
+ {
+ if ( !strncmp(params[i],"-p:",3) &&
+ !Convert_StringToInt(params[i]+3,&ipid) ) erreurParam = true;
+ else
+ if ( !strncmp(params[i],"-a1:",4) &&
+ !Convert_StringToInt(params[i]+4,&ia1) ) erreurParam = true;
+ else
+ if ( !strncmp(params[i],"-a2:",4) &&
+ !Convert_StringToInt(params[i]+4,&ia2) ) erreurParam = true;
+ else
+ if ( !strncmp(params[i],"-d:",3) &&
+ !Convert_StringToInt(params[i]+3,&id8) ) erreurParam = true;
+ else
+ if ( !strncmp(params[i],"-num:",5) &&
+ !Convert_StringToInt(params[i]+5,&numread) ) erreurParam = true;
+ else
+ if ( !strncmp(params[i],"-delay:",7) &&
+ !Convert_StringToInt(params[i]+7,&delay) ) erreurParam = true;
+ else
+ if ( !strncmp(params[i],"-dbt1:",6) &&
+ !Convert_StringToInt(params[i]+6,&dbt1) ) erreurParam = true;
+ else
+ if ( !strncmp(params[i],"-dbt2:",6) &&
+ !Convert_StringToInt(params[i]+6,&dbt2) ) erreurParam = true;
+ else
+ if ( !strcmp(params[i],"-debug") ){
+ debug = true;
+ DEBUG = true;
+ }
+ else
+ if ( !strcmp(params[i],"-reset1") ) resetcnt1 = true;
+ else
+ if ( !strcmp(params[i],"-reset2") ) resetcnt2 = true;
+ else
+ if ( !strcmp(params[i],"--help") ) {
+ display_help(params);
+ return false;
+ }
+
+ }
+
+
+ /*
+ Send parameters to standart error
+ */
+ if ( debug )
+ fprintf(stderr,"Parameters : Card=%d Analog1=%d Analog2=%d Digital=%d\n",ipid,ia1,ia2,id8);
+
+ if (ipid<0 || ipid>3){
+ printf("Invalid board address!\n");
+ return -1;
+ }
+
+
+ if (erreurParam)
+ {
+
+ printf("Invalid or incomplete options\n");
+
+ display_help(params);
+ return false;
+ }
+
+
+ return true;
+}
+
+/*
+ Give current timestamp in miliseconds
+*/
+inline unsigned long int time_msec ( void ) {
+ struct timeval t; struct timezone tz;
+ gettimeofday (&t,&tz);
+ return (1000*t.tv_sec)+(t.tv_usec/1000);
+}
+
+
+int main (int argc,char *params[])
+{
+ int i,result;
+ long d=0;
+ long a1=0,a2=0;
+ long c1=0, c2=0;
+ unsigned long int start,mstart=0,lastcall=0;
+
+ start = time_msec();
+
+ /*
+ Load parameters
+ If parameters are valid continue
+ */
+
+ if (read_param(argc,params))
+ {
+ /*
+ Initialise USB system
+ and enable debug mode
+
+ if ( debug )
+ usb_set_debug(2);
+ */
+ /*
+ Search the device
+ */
+ if ( OpenDevice(ipid)<0 ) {
+ printf("Could not open the k8055 (port:%d)\nPlease ensure that the device is correctly connected.\n",ipid);
+ return (-1);
+
+ } else {
+
+ if ( resetcnt1 )
+ ResetCounter(1);
+ if ( resetcnt2 )
+ ResetCounter(2);
+ if ( dbt1 != -1 )
+ SetCounterDebounceTime(1,dbt1);
+ if ( dbt2 != -1 )
+ SetCounterDebounceTime(2,dbt1);
+
+ if ((ia1!=-1) && (ia2!=-1) && (id8!=-1)) {
+ result = SetAllValues(id8,ia1,ia2);
+ if (debug) printf("SetAllValues=%d - Digital:%d, analog1:%d, analog2:%d\n",result,id8,ia1,ia2);
+ }
+ else if ((id8 != -1) && (ia1!=-1)) {
+ result = SetAllValues(id8,ia1,0);
+ if (debug) printf("SetAllValues=%d - Digital:%d, analog1:%d\n",result,id8,ia1);
+ }
+ else if ((id8 != -1) && (ia2!=-1)) {
+ result = SetAllValues(id8,0,ia2);
+ if (debug) printf("SetAllValues=%d - Digital:%d, analog2:%d\n",result,id8,ia2);
+ }
+ else if ((ia1 != -1) && (ia2!=-1)) {
+ result = SetAllValues(0,ia1,ia2);
+ if (debug) printf("SetAllValues=%d - analog1:%d, analog2:%d\n",result,ia1,ia2);
+ }
+ else {
+ if (ia1!=-1) {
+ result=OutputAnalogChannel(1,ia1);
+ if (debug) printf("Set analog1:%d=>%d\n",ia1,result);
+ }
+ if (ia2!=-1) {
+ result=OutputAnalogChannel(2,ia2);
+ if (debug) printf("Set analog2:%d=>%d\n",ia2,result);
+ }
+ if (id8!=-1) {
+ result=WriteAllDigital((long)id8);
+ if (debug) printf("Set digital:%d=>%d\n",id8,result);
+ }
+ }
+
+ mstart = time_msec(); // Measure start
+ for (i=0; i<numread; i++) {
+
+ if ( delay ) {
+ // Wait until next measure
+ while ( time_msec()-mstart < i*delay );
+ }
+ ReadAllValues( &d,&a1,&a2,&c1,&c2);
+
+/* ReadAllAnalog(&a1,&a2);
+ d=ReadAllDigital();
+ c1=ReadCounter(1);
+ c2=ReadCounter(2);
+*/
+ lastcall = time_msec();
+ printf("%d;%d;%d;%d;%d;%d\n", (int)(lastcall-start),(int)d, (int)a1, (int)a2,(int)c1,(int)c2 );
+ }
+
+ CloseDevice();
+ }
+ }
+ return 0;
+}
diff --git a/man/k8055.1.gz b/man/k8055.1.gz
new file mode 100644
index 0000000..042fdf4
--- /dev/null
+++ b/man/k8055.1.gz
Binary files differ
diff --git a/pyk8055/Makefile b/pyk8055/Makefile
new file mode 100644
index 0000000..a2069d3
--- /dev/null
+++ b/pyk8055/Makefile
@@ -0,0 +1,37 @@
+# $Id: Makefile,v 1.3 2007/04/08 10:54:49 pjetur Exp $
+#
+#cc = gcc
+#pylibdir = pyk8055
+#libs = -lusb -L/usr/lib -lm
+
+# We have to build extension "inplace" if We're to
+# run samples locally without installing
+
+all: libk8055.i ../libk8055.c
+ python setup.py build_ext --inplace
+ python setup.py build
+
+# Or in plain language
+# swig -python libk8055.i
+# cc -fpic -O2 -c ../libk8055.c -o ./libk8055.o
+# cc -fpic -O2 -c libk8055_wrap.c -I /usr/include/python2.4/ -o libk8055_wrap.o
+# ld -shared libk8055.o libk8055_wrap.o -lusb -o _pyk8055.so
+## mv -f pyk8055.py __init__.py
+
+.PHONY: kdemo
+
+kdemo: k8055qt.py frmk8055qt.ui frmk8055qt.ui.h
+ pyuic frmk8055qt.ui -o frmk8055qt.py
+
+# install will both make build and install
+install:
+ python setup.py install
+
+# Remove all swig generated files
+clean:
+ python setup.py clean --all
+ rm -f *.o _pyk8055.so libk8055_wrap.c pyk8055.py pyk8055.pyc
+
+uninstall:
+ python setup.py uninstall
+ #rm -f /usr/lib/python-2.4/site-packages/pyk8055.py /usr/lib/python-2.4/site-packages/_pyk8055.so
diff --git a/pyk8055/frmk8055qt.ui b/pyk8055/frmk8055qt.ui
new file mode 100644
index 0000000..2669c01
--- /dev/null
+++ b/pyk8055/frmk8055qt.ui
@@ -0,0 +1,1422 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>K8055QT</class>
+<comment>Python:#from kdecore import *
+Python:from kdeui import *
+Python:from pyk8055 import *
+</comment>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>K8055QT</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>314</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>K8055 Status</string>
+ </property>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>OutputGroup</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>320</x>
+ <y>70</y>
+ <width>270</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Digital Output</string>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>OutputBox5</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>20</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>5</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital Output 5</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>OutputBox6</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>169</x>
+ <y>20</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>6</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital Output 6</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>OutputBox7</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>199</x>
+ <y>20</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>7</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital Output 7</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>OutputBox8</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>229</x>
+ <y>20</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>8</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital Output 8</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>OutputBox1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>1</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital Output 1</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>OutputBox2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>42</x>
+ <y>20</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>2</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital Output 2</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>OutputBox3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>76</x>
+ <y>20</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>3</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital Output 3</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>OutputBox4</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>110</x>
+ <y>20</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>4</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital Output 4</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>InputGroup</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>320</x>
+ <y>130</y>
+ <width>270</width>
+ <height>70</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Digital Input</string>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>DigitaltextLabel1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>18</x>
+ <y>40</y>
+ <width>20</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>1</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>DigitaltextLabel4</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>170</x>
+ <y>40</y>
+ <width>20</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>4</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>DigitaltextLabel5</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>220</x>
+ <y>40</y>
+ <width>20</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>5</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>DigitaltextLabel2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>69</x>
+ <y>40</y>
+ <width>20</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>2</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>DigitaltextLabel3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>120</x>
+ <y>40</y>
+ <width>20</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>3</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="KLed">
+ <property name="name">
+ <cstring>DigitalLed1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>20</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="state">
+ <enum>Off</enum>
+ </property>
+ <property name="color">
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital 1 input state</string>
+ </property>
+ </widget>
+ <widget class="KLed">
+ <property name="name">
+ <cstring>DigitalLed2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>70</x>
+ <y>20</y>
+ <width>20</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="state">
+ <enum>Off</enum>
+ </property>
+ <property name="color">
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital 2 input state</string>
+ </property>
+ </widget>
+ <widget class="KLed">
+ <property name="name">
+ <cstring>DigitalLed3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>121</x>
+ <y>20</y>
+ <width>20</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="state">
+ <enum>Off</enum>
+ </property>
+ <property name="color">
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital 3 input state</string>
+ </property>
+ </widget>
+ <widget class="KLed">
+ <property name="name">
+ <cstring>DigitalLed4</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>173</x>
+ <y>20</y>
+ <width>20</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="state">
+ <enum>Off</enum>
+ </property>
+ <property name="color">
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital 4 input state</string>
+ </property>
+ </widget>
+ <widget class="KLed">
+ <property name="name">
+ <cstring>DigitalLed5</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>221</x>
+ <y>20</y>
+ <width>20</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="state">
+ <enum>Off</enum>
+ </property>
+ <property name="color">
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Digital 5 input state</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupCounter1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>320</x>
+ <y>200</y>
+ <width>271</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Counter 1</string>
+ </property>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>1 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>2 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>5 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>10 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>50 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>100 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>500 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>1000 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>2000 ms</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>comboCounter1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>171</x>
+ <y>20</y>
+ <width>90</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Debounce value counter #1</string>
+ </property>
+ </widget>
+ <widget class="QLCDNumber">
+ <property name="name">
+ <cstring>Counter1Value</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>71</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="segmentStyle">
+ <enum>Flat</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Counter #1</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>ClearCounter1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>100</x>
+ <y>20</y>
+ <width>60</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Reset</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Reset Counter #1</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupCounter2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>320</x>
+ <y>250</y>
+ <width>271</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Counter 2</string>
+ </property>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>1 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>2 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>5 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>10 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>50 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>100 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>500 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>1000 ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>2000 ms</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>comboCounter2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>171</x>
+ <y>20</y>
+ <width>90</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Debounce value counter #2</string>
+ </property>
+ </widget>
+ <widget class="QLCDNumber">
+ <property name="name">
+ <cstring>Counter2Value</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>71</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="segmentStyle">
+ <enum>Flat</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Counter #2</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>ClearCounter2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>100</x>
+ <y>20</y>
+ <width>60</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Reset</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Reset Counter #2</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupDigitalButtonBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>200</x>
+ <y>10</y>
+ <width>110</width>
+ <height>90</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Digital</string>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>ClearAllDigitalButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>50</y>
+ <width>90</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Clear All</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Clear all digital outputs</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>SetAllDigitalButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>90</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Set All</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Set all digital outputs</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupAnalogButtonBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>200</x>
+ <y>110</y>
+ <width>110</width>
+ <height>90</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Analog</string>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>ClearAllAnalogButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>50</y>
+ <width>90</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Clear All</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Set all analog outputs low</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>SetAllAnalogButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>90</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Set All</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Set all analog outputs high</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupTestButtonBox</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>200</x>
+ <y>210</y>
+ <width>110</width>
+ <height>90</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Test</string>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>TestAnalogButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>50</y>
+ <width>90</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Analog</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Run analog tests</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>TestDigitalButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>90</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Digital</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Run digital output tests</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBoxAD2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>10</y>
+ <width>45</width>
+ <height>290</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>AD2</string>
+ </property>
+ <widget class="QScrollBar">
+ <property name="name">
+ <cstring>BarAD2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>16</x>
+ <y>20</y>
+ <width>20</width>
+ <height>230</height>
+ </rect>
+ </property>
+ <property name="maxValue">
+ <number>255</number>
+ </property>
+ <property name="pageStep">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Analog input value - AD2</string>
+ </property>
+ </widget>
+ <widget class="QLCDNumber">
+ <property name="name">
+ <cstring>AD2Value</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>260</y>
+ <width>30</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="numDigits">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>Flat</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Analog value AD2</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBoxAD1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>100</x>
+ <y>10</y>
+ <width>45</width>
+ <height>290</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>AD1</string>
+ </property>
+ <widget class="QLCDNumber">
+ <property name="name">
+ <cstring>AD1Value</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>260</y>
+ <width>30</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="numDigits">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>Flat</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Analog value AD1</string>
+ </property>
+ </widget>
+ <widget class="QScrollBar">
+ <property name="name">
+ <cstring>BarAD1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>15</x>
+ <y>20</y>
+ <width>20</width>
+ <height>230</height>
+ </rect>
+ </property>
+ <property name="maxValue">
+ <number>255</number>
+ </property>
+ <property name="pageStep">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Analog input value - AD1</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBoxDA2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>55</x>
+ <y>10</y>
+ <width>45</width>
+ <height>290</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>DA2</string>
+ </property>
+ <widget class="QLCDNumber">
+ <property name="name">
+ <cstring>DA2Value</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>260</y>
+ <width>30</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="numDigits">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>Flat</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Analog value DA2</string>
+ </property>
+ </widget>
+ <widget class="QScrollBar">
+ <property name="name">
+ <cstring>BarDA2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>15</x>
+ <y>20</y>
+ <width>20</width>
+ <height>230</height>
+ </rect>
+ </property>
+ <property name="maxValue">
+ <number>255</number>
+ </property>
+ <property name="pageStep">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Analog output value - DA2</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBoxDA1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>45</width>
+ <height>290</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>DA1</string>
+ </property>
+ <widget class="QLCDNumber">
+ <property name="name">
+ <cstring>DA1Value</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>260</y>
+ <width>30</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="numDigits">
+ <number>3</number>
+ </property>
+ <property name="segmentStyle">
+ <enum>Flat</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Analog value DA1</string>
+ </property>
+ </widget>
+ <widget class="QScrollBar">
+ <property name="name">
+ <cstring>BarDA1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>15</x>
+ <y>20</y>
+ <width>20</width>
+ <height>230</height>
+ </rect>
+ </property>
+ <property name="maxValue">
+ <number>255</number>
+ </property>
+ <property name="pageStep">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Analog output value - DA1</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupCard</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>320</x>
+ <y>10</y>
+ <width>271</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Card</string>
+ </property>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>CardRadioGroup</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>19</y>
+ <width>151</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="title">
+ <string></string>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>CardButton1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>1</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select Card #1</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>CardButton3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>80</x>
+ <y>0</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>3</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select Card #3</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>CardButton2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>40</x>
+ <y>0</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>2</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select Card #2</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>CardButton4</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>120</x>
+ <y>0</y>
+ <width>30</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>4</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select Card #4</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>ConnectButton</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>179</x>
+ <y>15</y>
+ <width>80</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Connect</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Connect to selected card</string>
+ </property>
+ </widget>
+ </widget>
+</widget>
+<connections>
+ <connection>
+ <sender>ConnectButton</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>ConnectButton_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>CardButton1</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>CardButton1_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>CardButton2</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>CardButton2_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>ClearCounter2</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>ClearCounter2_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>OutputBox1</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>OutputBox1_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>ClearCounter1</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>ClearCounter1_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>OutputBox8</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>OutputBox8_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>OutputBox7</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>OutputBox7_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>OutputBox2</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>OutputBox2_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>OutputBox3</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>OutputBox3_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>OutputBox4</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>OutputBox4_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>OutputBox5</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>OutputBox5_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>OutputBox6</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>OutputBox6_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>SetAllAnalogButton</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>SetAllAnalogButton_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>ClearAllAnalogButton</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>ClearAllAnalogButton_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>SetAllDigitalButton</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>SetAllDigitalButton_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>ClearAllDigitalButton</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>ClearAllDigitalButton_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>BarAD2</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>K8055QT</receiver>
+ <slot>BarAD2_valueChanged(int)</slot>
+ </connection>
+ <connection>
+ <sender>BarAD1</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>K8055QT</receiver>
+ <slot>BarAD1_valueChanged(int)</slot>
+ </connection>
+ <connection>
+ <sender>comboCounter2</sender>
+ <signal>activated(int)</signal>
+ <receiver>K8055QT</receiver>
+ <slot>comboCounter2_activated(int)</slot>
+ </connection>
+ <connection>
+ <sender>comboCounter1</sender>
+ <signal>activated(int)</signal>
+ <receiver>K8055QT</receiver>
+ <slot>comboCounter1_activated(int)</slot>
+ </connection>
+ <connection>
+ <sender>TestDigitalButton</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>TestDigitalButton_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>TestAnalogButton</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>TestAnalogButton_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>CardButton3</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>CardButton3_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>CardButton4</sender>
+ <signal>clicked()</signal>
+ <receiver>K8055QT</receiver>
+ <slot>CardButton4_clicked()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">frmk8055qt.ui.h</include>
+</includes>
+<variables>
+ <variable access="private">Kpriv;</variable>
+ <variable access="public">Kp = False;</variable>
+</variables>
+<slots>
+ <slot>ConnectButton_clicked()</slot>
+ <slot>CardButton1_clicked()</slot>
+ <slot>CardButton2_clicked()</slot>
+ <slot>CardButton3_clicked()</slot>
+ <slot>CardButton4_clicked()</slot>
+ <slot>init()</slot>
+ <slot>ClearCounter1_clicked()</slot>
+ <slot>ClearCounter2_clicked()</slot>
+ <slot>OutputBox1_clicked()</slot>
+ <slot>OutputBox2_clicked()</slot>
+ <slot>OutputBox3_clicked()</slot>
+ <slot>OutputBox4_clicked()</slot>
+ <slot>OutputBox5_clicked()</slot>
+ <slot>OutputBox6_clicked()</slot>
+ <slot>OutputBox7_clicked()</slot>
+ <slot>OutputBox8_clicked()</slot>
+ <slot>SetAllAnalogButton_clicked()</slot>
+ <slot>ClearAllAnalogButton_clicked()</slot>
+ <slot>SetAllDigitalButton_clicked()</slot>
+ <slot>ClearAllDigitalButton_clicked()</slot>
+ <slot>BarAD1_valueChanged( int )</slot>
+ <slot>BarAD2_valueChanged( int )</slot>
+ <slot>comboCounter2_activated( int )</slot>
+ <slot>comboCounter1_activated( int )</slot>
+ <slot>TestDigitalButton_clicked()</slot>
+ <slot>TestAnalogButton_clicked()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kled.h</includehint>
+ <includehint>kled.h</includehint>
+ <includehint>kled.h</includehint>
+ <includehint>kled.h</includehint>
+ <includehint>kled.h</includehint>
+</includehints>
+</UI>
diff --git a/pyk8055/frmk8055qt.ui.h b/pyk8055/frmk8055qt.ui.h
new file mode 100644
index 0000000..1e986e6
--- /dev/null
+++ b/pyk8055/frmk8055qt.ui.h
@@ -0,0 +1,260 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you want to add, delete, or rename functions or slots, use
+** Qt Designer to update this file, preserving your code.
+**
+** You should not define a constructor or destructor in this file.
+** Instead, write your code in functions called init() and destroy().
+** These will automatically be called by the form's constructor and
+** destructor.
+*****************************************************************************/
+
+
+void K8055QT::ConnectButton_clicked()
+{
+ if (self.card != None) and (self.k == None):
+ try:
+ #print "Connect to card #",self.card
+ self.k = k8055(self.card)
+ self.EnableAll()
+ self.ClearAllDigitalButton_clicked()
+ self.ClearAllAnalogButton_clicked()
+ self.comboCounter1.setCurrentItem(0)
+ self.comboCounter2.setCurrentItem(0)
+
+ self.ConnectButton.setText(self.__tr("Disconnect"))
+ except:
+ print "No such Card"
+ elif (self.k != None):
+ try:
+ #print "Disconnect from card #",self.card
+ self.k.CloseDevice()
+ self.k = None
+ self.DisableAll()
+ self.OutputBox1.setChecked(0)
+ self.OutputBox2.setChecked(0)
+ self.OutputBox3.setChecked(0)
+ self.OutputBox4.setChecked(0)
+ self.OutputBox5.setChecked(0)
+ self.OutputBox6.setChecked(0)
+ self.OutputBox7.setChecked(0)
+ self.OutputBox8.setChecked(0)
+ self.BarDA1.setValue(0)
+ self.BarDA2.setValue(0)
+ self.BarAD1.setValue(0)
+ self.BarAD2.setValue(0)
+ self.DA1Value.setProperty("intValue",QVariant(0))
+ self.DA2Value.setProperty("intValue",QVariant(0))
+ self.AD1Value.setProperty("intValue",QVariant(0))
+ self.AD2Value.setProperty("intValue",QVariant(0))
+ self.comboCounter1.setCurrentItem(0)
+ self.comboCounter2.setCurrentItem(0)
+ self.Counter1Value.setProperty("intValue",QVariant(0))
+ self.Counter2Value.setProperty("intValue",QVariant(0))
+ self.ConnectButton.setText(self.__tr("Connect"))
+ except:
+ pass
+
+}
+
+
+void K8055QT::CardButton1_clicked()
+{
+ self.card = 0
+}
+
+void K8055QT::CardButton2_clicked()
+{
+ self.card = 1
+}
+
+void K8055QT::CardButton3_clicked()
+{
+ self.card = 2
+}
+
+void K8055QT::CardButton4_clicked()
+{
+ self.card = 3
+}
+
+
+void K8055QT::init()
+{
+ self.k = None
+ self.DisableAll()
+}
+
+void K8055QT::ClearCounter1_clicked()
+{
+ if self.k:
+ self.k.ResetCounter(1)
+}
+
+void K8055QT::ClearCounter2_clicked()
+{
+ if self.k:
+ self.k.ResetCounter(2)
+}
+
+
+void K8055QT::OutputBox1_clicked()
+{
+ if self.k:
+ if self.OutputBox1.isChecked():
+ self.k.SetDigitalChannel(1)
+ else:
+ self.k.ClearDigitalChannel(1)
+}
+
+void K8055QT::OutputBox2_clicked()
+{
+ if self.k:
+ if self.OutputBox2.isChecked():
+ self.k.SetDigitalChannel(2)
+ else:
+ self.k.ClearDigitalChannel(2)
+
+void K8055QT::OutputBox3_clicked()
+{
+ if self.k:
+ if self.OutputBox3.isChecked():
+ self.k.SetDigitalChannel(3)
+ else:
+ self.k.ClearDigitalChannel(3)
+}
+void K8055QT::OutputBox4_clicked()
+{
+ if self.k:
+ if self.OutputBox4.isChecked():
+ self.k.SetDigitalChannel(4)
+ else:
+ self.k.ClearDigitalChannel(4)
+}
+void K8055QT::OutputBox5_clicked()
+{
+ if self.k:
+ if self.OutputBox5.isChecked():
+ self.k.SetDigitalChannel(5)
+ else:
+ self.k.ClearDigitalChannel(5)
+}
+void K8055QT::OutputBox6_clicked()
+{
+ if self.k:
+ if self.OutputBox6.isChecked():
+ self.k.SetDigitalChannel(6)
+ else:
+ self.k.ClearDigitalChannel(6)
+}
+void K8055QT::OutputBox7_clicked()
+{
+ if self.k:
+ if self.OutputBox7.isChecked():
+ self.k.SetDigitalChannel(7)
+ else:
+ self.k.ClearDigitalChannel(7)
+}
+void K8055QT::OutputBox8_clicked()
+{
+ if self.k:
+ if self.OutputBox8.isChecked():
+ self.k.SetDigitalChannel(8)
+ else:
+ self.k.ClearDigitalChannel(8)
+}
+
+
+void K8055QT::SetAllAnalogButton_clicked()
+{
+ if self.k:
+ self.k.SetAllAnalog()
+ self.BarAD1.setValue(0)
+ self.BarAD2.setValue(0)
+ self.AD1Value.setProperty("intValue",QVariant(255))
+ self.AD2Value.setProperty("intValue",QVariant(255))
+}
+
+
+void K8055QT::ClearAllAnalogButton_clicked()
+{
+ if self.k:
+ self.k.ClearAllAnalog()
+ self.BarAD1.setValue(255)
+ self.BarAD2.setValue(255)
+ self.AD1Value.setProperty("intValue",QVariant(0))
+ self.AD2Value.setProperty("intValue",QVariant(0))
+}
+
+
+void K8055QT::SetAllDigitalButton_clicked()
+{
+ if self.k:
+ self.k.SetAllDigital()
+ self.OutputBox1.setChecked(1)
+ self.OutputBox2.setChecked(1)
+ self.OutputBox3.setChecked(1)
+ self.OutputBox4.setChecked(1)
+ self.OutputBox5.setChecked(1)
+ self.OutputBox6.setChecked(1)
+ self.OutputBox7.setChecked(1)
+ self.OutputBox8.setChecked(1)
+}
+
+void K8055QT::ClearAllDigitalButton_clicked()
+{
+ if self.k:
+ self.k.ClearAllDigital()
+ self.OutputBox1.setChecked(0)
+ self.OutputBox2.setChecked(0)
+ self.OutputBox3.setChecked(0)
+ self.OutputBox4.setChecked(0)
+ self.OutputBox5.setChecked(0)
+ self.OutputBox6.setChecked(0)
+ self.OutputBox7.setChecked(0)
+ self.OutputBox8.setChecked(0)
+}
+
+
+void K8055QT::BarAD1_valueChanged( int )
+{
+ if self.k:
+ self.k.OutputAnalogChannel(1,255-a0)
+ self.AD1Value.setProperty("intValue",QVariant(255-a0))
+}
+
+void K8055QT::BarAD2_valueChanged( int )
+{
+ if self.k:
+ self.k.OutputAnalogChannel(2,255-a0)
+ self.AD2Value.setProperty("intValue",QVariant(255-a0))
+}
+
+
+void K8055QT::comboCounter2_activated( int )
+{
+ if self.k:
+ v = str(self.comboCounter2.currentText()).split()
+ self.k.SetCounterDebounceTime(2,int(v[0]))
+}
+
+
+void K8055QT::comboCounter1_activated( int )
+{
+ if self.k:
+ v = str(self.comboCounter1.currentText()).split()
+ self.k.SetCounterDebounceTime(1,int(v[0]))
+}
+
+
+void K8055QT::TestDigitalButton_clicked()
+{
+ self.DigitalTest()
+}
+
+
+void K8055QT::TestAnalogButton_clicked()
+{
+ self.AnalogTest()
+}
diff --git a/pyk8055/k8055.py b/pyk8055/k8055.py
new file mode 100755
index 0000000..3c03a10
--- /dev/null
+++ b/pyk8055/k8055.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+# $Id: k8055.py,v 1.2 2007/03/15 14:50:55 pjetur Exp $
+"""
+Python version of K8055 command line program
+
+Copyright (C) 2007 by Pjetur G. Hjaltason
+
+Syntax : python k8055.py [-p:(number)] [-d:(value)] [-a1:(value)] [-a2:(value)]
+ [-num:(number) [-delay:(number)] [-dbt1:(value)]
+ [-dbt2:(value)] [-reset1] [-reset2] [-debug] [-h|--help]
+ -p:(number) Set board number (0/1/2/3)
+ -d:(value) Set digital output value (bitmask, 8 bits in decimal)
+ -a1:(value) Set analog output 1 value (0-255)
+ -a2:(value) Set analog output 2 value (0-255)
+ -num:(number) Set number of measures (-1 for no read)
+ -delay:(number) Set delay between two measures (in msec)
+ -dbt1:(value) Set debounce time for counter 1 (in msec)
+ -dbt2:(value) Set debounce time for counter 2 (in msec)
+ -reset1 Reset counter 1
+ -reset2 Reset counter 2
+ -debug Activate debug mode
+ -h or --help Print this text
+
+Example : python k8055.py -p:1 -d:147 -a1:25 -a2:203
+
+NOTE:
+ Because of the nature of commands sent to the K8055 board, this
+ program has no way of knowing previous state of the analog or
+ digial outputs, thus each run of this command will clear the previous
+ state - and set a new state - of the analog and digital outputs
+
+ See header of libk8055.c for more details of K8055 commands
+"""
+import sys
+from time import sleep, time
+from pyk8055 import *
+
+def main(argv):
+ # preset values
+ p , db = 0,0 # Port, debug
+ r1, r2 = 0,0 # reset1, reset2
+ dl = -1 # delay
+ db1,db2 = -1,-1 # debounce1, debounce2
+ a1,a2,d = -1,-1,-1 # analog1, analog2, digital
+ nm = 1 # number of times to read, default once
+
+ # not the standard getopts way, but...
+ for arg in argv:
+ if arg in ("-h", "--help"):
+ print __doc__
+ sys.exit(0)
+ elif arg[:4] == "-a1:" : a1 = int(arg[4:])
+ elif arg[:4] == "-a2:" : a2 = int(arg[4:])
+ elif arg[:5] == "-num:" : nm = int(arg[5:])
+ elif arg[:3] == "-d:" : d = int(arg[3:])
+ elif arg[:3] == "-p:" : p = int(arg[3:])
+ elif arg[:7] == "-delay:" : dl = int(arg[7:])
+ elif arg[:6] == "-dbt1:" : db1 = int(arg[6:])
+ elif arg[:6] == "-dbt2:" : db2 = int(arg[6:])
+ elif arg == "-reset1" : r1 = 1
+ elif arg == "-reset2" : r2 = 1
+ elif arg == "-debug" : db = 1
+ else:
+ print __doc__
+ sys.exit(0)
+
+ try:
+ # Open device
+ if db == 1: k = k8055(p,True) # Debug mode
+ else: k = k8055(p)
+
+ # set requested
+ if r1 != 0: k.ResetCounter(1)
+ if r2 != 0: k.ResetCounter(2)
+ if db1 != -1: k.SetCounterDebounceTime(1, db1)
+ if db2 != -1: k.SetCounterDebounceTime(2, db2)
+
+ # Try to set all digital/analog values at the same time
+ if (d != -1 and a1 != -1 and a2 != -1) : SetAllValues(d,a1,a2)
+ elif (d != -1 and a1 != -1 ) : SetAllValues(d,a1,0)
+ elif (d != -1 and a2 != -1 ) : SetAllValues(d,0,a2)
+ elif (a1 != -1 and a2 != -1 ) : SetAllValues(0,a1,a2)
+ # Else only one specified
+ else:
+ if d != -1: k.WriteAllDigital(d)
+ if a1 != -1: k.OutputAnalogChannel(1,a1)
+ if a2 != -1: k.OutputAnalogChannel(2,a2)
+
+ # Now we loop (or not) for the specified number of times
+ # reading all the input values
+
+ # Each read of all values will take about 2-8ms, at least
+ # on my setup - so no sense in using delay less than 10
+ if (dl > 0) & (dl < 10): dl = 10
+
+ if (nm > 0) & (dl > 0):
+ tst = tstart = time()
+ i = 0
+ while nm > 0:
+ ds = str(k)
+ tnow = time()
+ tms = (tnow - tstart) * 1000.0
+ delta= dl - (tms - dl*i)
+ #tst = tnow
+ print str(int(tms+0.4999))+";"+ds
+ sleep((delta)/1000.0) # compensate for read time
+ nm -= 1
+ i += 1
+ elif nm > 0:
+ print "0;"+ str(k)
+
+ k.CloseDevice()
+
+ except IOError:
+ print "Could not open the k8055 (port:%s)" % str(p)
+
+main(sys.argv[1:])
diff --git a/pyk8055/k8055qt.png b/pyk8055/k8055qt.png
new file mode 100644
index 0000000..85647db
--- /dev/null
+++ b/pyk8055/k8055qt.png
Binary files differ
diff --git a/pyk8055/k8055qt.py b/pyk8055/k8055qt.py
new file mode 100644
index 0000000..49288f6
--- /dev/null
+++ b/pyk8055/k8055qt.py
@@ -0,0 +1,232 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Python version of libK8055 demo program
+#
+# Copyright (C) 2007 by Pjetur G. Hjaltason
+#
+
+import sys
+from qt import *
+#from qwt import *
+
+import time, string
+from pyk8055 import *
+from frmk8055qt import *
+
+class QTK8055(K8055QT):
+ def __init__(self):
+ K8055QT.__init__(self)
+
+ # Not much sense in making a fancy menu yet
+ #
+ #puProg = QPopupMenu(self)
+ #puProg.insertItem("Quit", Kapp.quit)
+
+ #puHelp = QPopupMenu(self)
+ #puHelp.insertItem("About", self.about)
+
+ #self.menu = QMenuBar(self)
+ #self.menu.insertItem("Program", puProg)
+ #self.menu.insertItem("Help", puHelp)
+
+ # enumerate devices
+ BMask = SearchDevices()
+ if not BMask:
+ print "No K8055 devices found"
+ exit
+
+ # Enable those present
+ self.CardButton1.setEnabled((BMask & 0x01) > 0)
+ self.CardButton2.setEnabled((BMask & 0x02) > 0)
+ self.CardButton3.setEnabled((BMask & 0x04) > 0)
+ self.CardButton4.setEnabled((BMask & 0x08) > 0)
+
+ # set the first one found as suggestion
+ if (BMask & 0x01) > 0:
+ self.card = 0
+ self.CardButton1.setChecked(1)
+ elif (BMask & 0x02) > 0:
+ self.card = 1
+ self.CardButton2.setChecked(1)
+ elif (BMask & 0x04) > 0:
+ self.card = 2
+ self.CardButton3.setChecked(1)
+ elif (BMask & 0x08) > 0:
+ self.card = 3
+ self.CardButton4.setChecked(1)
+
+ self.time = QTime.currentTime() # get current time
+ internalTimer = QTimer( self ) # create internal timer
+ self.connect( internalTimer, SIGNAL("timeout()"), self.timeout )
+ internalTimer.start( 100 ) # emit signal every 1/10 second
+
+ self.timeout()
+
+ def AnalogTest(self):
+ try:
+ for step in range(0,255,10):
+ self.BarAD1.setValue(step)
+ self.BarAD2.setValue(step)
+ time.sleep(0.1)
+ # set analog output channel 1 to 200/255*5v = 3.9V
+ for step in range(255,0,10):
+ self.BarAD1.setValue(step)
+ self.BarAD2.setValue(step)
+ time.sleep(0.1)
+
+ # read both analog inputs
+ # note: this returns a list
+ #res = self.k.ReadAllAnalog()
+ #sres = res[1:]
+
+ # There should be more interesting information in the messagebox ;-/
+
+ QMessageBox.information( self,'Information', "AllOK","Ok")
+ except:
+ pass
+
+ def DigitalTest(self):
+ try:
+ # Create a rotating display of digital outputs
+ # while waiting for keypress on digital input 1
+ # (longer than .2sec :) Loop at most 3 times
+ Input1High = False
+ for i in range(1,3):
+ d = 1
+ self.k.WriteAllDigital(1)
+ while Input1High == False and d < 128:
+ Input1High = (self.k.ReadDigitalChannel(1) > 0)
+ if Input1High: break
+ time.sleep(0.2) # wait .2 sec
+ d *=2 # and continue rotating digital outputs
+ #if d > 128: d=1;
+ self.k.WriteAllDigital(d)
+ if Input1High: break
+
+ res = "Digital input 1=" + str(self.k.ReadDigitalChannel(1)) + "<br>"
+ # read the counter on input 1
+ res+= "Counter(1)=" + str(self.k.ReadCounter(1)) + "<br>"
+ # read the counter on input 2
+ res+= "Counter(2)=" + str(self.k.ReadCounter(2))
+
+ # set even bits on digital outputs
+ self.k.WriteAllDigital(170)
+ time.sleep(1)
+ # set odd bits on digital outputs
+ self.k.WriteAllDigital(85)
+ time.sleep(1)
+ # Clear all digital outputs
+ self.k.WriteAllDigital(0)
+
+ # There should be more interesting information in the messagebox ;-/
+
+ QMessageBox.information( self,'DigitalTest', res,"Ok")
+ except:
+ QMessageBox.warning( self,'DigitalTest', "Not OK","Ok")
+ pass
+
+ def EnableAll(self):
+ self.OutputBox1.setEnabled(1)
+ self.OutputBox2.setEnabled(1)
+ self.OutputBox3.setEnabled(1)
+ self.OutputBox4.setEnabled(1)
+ self.OutputBox5.setEnabled(1)
+ self.OutputBox6.setEnabled(1)
+ self.OutputBox7.setEnabled(1)
+ self.OutputBox8.setEnabled(1)
+ self.SetAllDigitalButton.setEnabled(1)
+ self.ClearAllDigitalButton.setEnabled(1)
+ self.SetAllAnalogButton.setEnabled(1)
+ self.ClearAllAnalogButton.setEnabled(1)
+ self.comboCounter1.setEnabled(1)
+ self.comboCounter2.setEnabled(1)
+ self.ClearCounter1.setEnabled(1)
+ self.ClearCounter2.setEnabled(1)
+ self.TestDigitalButton.setEnabled(1)
+ self.TestAnalogButton.setEnabled(1)
+ self.BarAD1.setEnabled(1)
+ self.BarAD2.setEnabled(1)
+ self.BarDA1.setEnabled(1)
+ self.BarDA2.setEnabled(1)
+
+ def DisableAll(self):
+ self.OutputBox1.setEnabled(0)
+ self.OutputBox2.setEnabled(0)
+ self.OutputBox3.setEnabled(0)
+ self.OutputBox4.setEnabled(0)
+ self.OutputBox5.setEnabled(0)
+ self.OutputBox6.setEnabled(0)
+ self.OutputBox7.setEnabled(0)
+ self.OutputBox8.setEnabled(0)
+ self.SetAllDigitalButton.setEnabled(0)
+ self.ClearAllDigitalButton.setEnabled(0)
+ self.SetAllAnalogButton.setEnabled(0)
+ self.ClearAllAnalogButton.setEnabled(0)
+ self.comboCounter1.setEnabled(0)
+ self.comboCounter2.setEnabled(0)
+ self.ClearCounter1.setEnabled(0)
+ self.ClearCounter2.setEnabled(0)
+ self.TestDigitalButton.setEnabled(0)
+ self.TestAnalogButton.setEnabled(0)
+ self.BarAD1.setEnabled(0)
+ self.BarAD2.setEnabled(0)
+ self.BarDA1.setEnabled(0)
+ self.BarDA2.setEnabled(0)
+#
+## The QTimer::timeout() signal is received by this slot.
+#
+
+ def timeout( self ):
+ #new_time = QTime.currentTime() # get the current time
+ if self.k != None:
+ try:
+ AllVal = self.k.ReadAllValues()
+ #print AllVal,AllVal[2]
+ self.BarDA1.setValue(255 - AllVal[2])
+ self.BarDA2.setValue(255 - AllVal[3])
+ self.DA1Value.setProperty("intValue",QVariant(AllVal[2]))
+ self.DA2Value.setProperty("intValue",QVariant(AllVal[3]))
+ self.Counter1Value.setProperty("intValue",QVariant(AllVal[4]))
+ self.Counter2Value.setProperty("intValue",QVariant(AllVal[5]))
+
+ if (AllVal[1] & 0x01) > 0:
+ self.DigitalLed1.setState(KLed.On)
+ else:
+ self.DigitalLed1.setState(KLed.Off)
+ if (AllVal[1] & 0x02) > 0:
+ self.DigitalLed2.setState(KLed.On)
+ else:
+ self.DigitalLed2.setState(KLed.Off)
+ if (AllVal[1] & 0x04) > 0:
+ self.DigitalLed3.setState(KLed.On)
+ else:
+ self.DigitalLed3.setState(KLed.Off)
+ if (AllVal[1] & 0x08) > 0:
+ self.DigitalLed4.setState(KLed.On)
+ else:
+ self.DigitalLed4.setState(KLed.Off)
+ if (AllVal[1] & 0x10) > 0:
+ self.DigitalLed5.setState(KLed.On)
+ else:
+ self.DigitalLed5.setState(KLed.Off)
+ except:
+ print "K8055 Read failed"
+
+ def about(self):
+ QMessageBox.about( self, "About k8055qt",
+ "k8055qt is a small GUI program using libk8055\n\n"
+ "Copyright 2007 Pjetur G. Hjaltason. "
+ "Distributed under GPL license\n\n"
+ "For technical support, study the source code or surf\n"
+ "http://sourceforge.net/projects/libk8055/\n" )
+
+if __name__ == "__main__":
+ Kapp = QApplication(sys.argv)
+ QObject.connect(Kapp,SIGNAL("lastWindowClosed()"),Kapp,SLOT("quit()"))
+ w = QTK8055()
+ Kapp.setMainWidget(w)
+ w.show()
+ Kapp.exec_loop()
+
+
diff --git a/pyk8055/k8055test.py b/pyk8055/k8055test.py
new file mode 100755
index 0000000..db5ee54
--- /dev/null
+++ b/pyk8055/k8055test.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# $Id: k8055test.py,v 1.3 2007/03/28 10:09:34 pjetur Exp $
+#
+# Sample pyton test program for pyk8055 wrapper
+# Testing single board
+#
+from time import sleep
+from pyk8055 import *
+
+try:
+ # CHANGE PORT HERE IF NEEDED
+ # Open device port 0
+ k = k8055(0)
+
+ # set analog output channel 1 to 200/255*5v = 3.9V
+ k.OutputAnalogChannel(1,200)
+ sleep(1)
+ # set analog output channel low again = 0V
+ k.OutputAnalogChannel(1,0)
+
+ # read both analog inputs
+ # note: this returns a list
+ res = k.ReadAllAnalog()
+ print res[1:]
+
+ # Test class string function
+ print str(k)
+
+ # Set debounce time on counter 1
+ k.SetCounterDebounceTime(1, 100)
+
+ # reset counter 1
+ k.ResetCounter(1)
+
+ # create a rotating display of digital outputs
+ # while waiting for keypress on digital input 1
+ # (longer than .2sec :)
+ Loop,dInput1,d = 0,0,1
+ k.WriteAllDigital(1)
+ while Loop < 3 or dInput1 == 0: # is key 1 down (input 1 high)
+ dInput1 = k.ReadDigitalChannel(1)
+ Loop += 1
+ sleep(0.2) # wait .2 sec
+ d *=2 # and continue rotating digital outputs
+ if d > 128: d=1;
+ k.WriteAllDigital(d)
+
+ print "Digital input 1=",dInput1
+
+ # read the counter on input 1
+ print "Counter(1)=",k.ReadCounter(1)
+ # read the counter on input 2
+ print "Counter(2)=",k.ReadCounter(2)
+
+ # set even bits on digital outputs
+ k.WriteAllDigital(170)
+ sleep(1)
+ # set odd bits on digital outputs
+ k.WriteAllDigital(85)
+ sleep(1)
+ # Clear all digital outputs
+ k.WriteAllDigital(0)
+
+ # and close
+ k.CloseDevice()
+
+except IOError:
+ print "Could not open Device"
+
+
diff --git a/pyk8055/k8055testm.py b/pyk8055/k8055testm.py
new file mode 100644
index 0000000..a20dc30
--- /dev/null
+++ b/pyk8055/k8055testm.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+# $Id: k8055testm.py,v 1.1 2007/03/28 10:10:32 pjetur Exp $
+#
+# Sample pyton test program for pyk8055 wrapper
+# Scanning and testing multiple boards
+#
+from time import sleep
+from pyk8055 import *
+
+try:
+ K8055_devices =[]
+ BMask = SearchDevices()
+ if not BMask:
+ print "No K8055 devices found"
+ exit
+
+ if BMask & 0x01 : K8055_devices.append(k8055(0))
+ if BMask & 0x02 : K8055_devices.append(k8055(1))
+ if BMask & 0x04 : K8055_devices.append(k8055(2))
+ if BMask & 0x08 : K8055_devices.append(k8055(3))
+
+ for k in K8055_devices:
+ k.SetCurrentDevice()
+ # set analog output channel 1 to 200/255*5v = 3.9V
+ k.OutputAnalogChannel(1,200)
+ sleep(1)
+ # set analog output channel low again = 0V
+ k.OutputAnalogChannel(1,0)
+
+ # read both analog inputs
+ # note: this returns a list
+ res = k.ReadAllAnalog()
+ print "Analog status, board #",k.DeviceAddress(),res[1:]
+
+ # Test class string function
+ print "Status, board #",k.DeviceAddress(),str(k)
+
+ # Set debounce time on counter 1
+ k.SetCounterDebounceTime(1, 100)
+
+ # reset counter 1
+ k.ResetCounter(1)
+
+ # Loop creating a rotating display of digital outputs
+ # Loop 3 times
+ for i in range(1,3):
+ for k in K8055_devices:
+ k.SetCurrentDevice()
+ d = 1
+ k.WriteAllDigital(1)
+ while d <= 128: # While this running
+ if k.ReadDigitalChannel(1):
+ print "Hello world (from board #%d)" %(k.DeviceAddress(),)
+ sleep(0.2) # wait .2 sec
+ d *=2 # and continue rotating digital outputs
+ k.WriteAllDigital(d)
+
+ for k in K8055_devices:
+ k.SetCurrentDevice()
+ # read/print the counter on input 1
+ print "Board # %d Counter #1=%d" % (k.DeviceAddress(),k.ReadCounter(1))
+ # read/print the counter on input 2
+ print "Board # %d Counter #2=%d" % (k.DeviceAddress(),k.ReadCounter(2))
+
+ for k in K8055_devices:
+ k.SetCurrentDevice()
+ # set even bits on digital outputs
+ k.WriteAllDigital(170)
+
+ sleep(1)
+
+ for k in K8055_devices:
+ k.SetCurrentDevice()
+ # set odd bits on digital outputs
+ k.WriteAllDigital(85)
+
+ sleep(1)
+
+ for k in K8055_devices:
+ k.SetCurrentDevice()
+ # Clear all digital outputs
+ k.WriteAllDigital(0)
+
+ # and close
+ for k in K8055_devices:
+ k.SetCurrentDevice()
+ k.CloseDevice()
+
+except KeyboardInterrupt:
+ for k in K8055_devices:
+ k.SetCurrentDevice()
+ k.WriteAllDigital(0)
+ k.CloseDevice()
+ exit
+
+except IOError:
+ print "Could not open Device"
+
diff --git a/pyk8055/libk8055.i b/pyk8055/libk8055.i
new file mode 100644
index 0000000..b0d31e9
--- /dev/null
+++ b/pyk8055/libk8055.i
@@ -0,0 +1,352 @@
+/* $Id: libk8055.i,v 1.3 2007/03/28 10:08:13 pjetur Exp $
+
+ Copyright (C) 2007 by Pjetur G. Hjaltason
+
+
+ Python wrapper for the libk8055 library using "swig"
+ This file is part of the libk8055 Library.
+
+ The libk8055 Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The libk8055 Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ http://opensource.org/licenses/
+
+*/
+%module pyk8055
+%include "typemaps.i"
+
+/* for the ReadAllAnalog and ReadAllValues function */
+%apply long *OUTPUT { long int *data1, long int *data2, long int *data3, long int *data4, long int *data5 };
+
+%inline %{
+
+/* For direct access to the DEBUG variable and global IO strings */
+extern int DEBUG;
+extern unsigned char data_in[9];
+extern unsigned char data_out[9];
+/*
+ Extended functions for debugging the IO
+*/
+
+char strval[30];
+
+/* returns 16byte hex string - 8 bytes */
+char * RawInput()
+ {
+ int i;
+ for(i=0; i< 8; i++) {
+ sprintf((char *)&strval[i*2],"%02X",data_in[i]);
+ }
+ return (char *)strval;
+ }
+
+/* More print friendly format */
+char * DumpInput()
+ {
+ int i;
+ for(i=0; i< 8; i++) {
+ sprintf((char *)&strval[i*3],"%02X:",data_in[i]);
+ }
+ strval[23] = '\0';
+ return (char *)strval;
+ }
+
+char * DumpOutput()
+ {
+ int i;
+ for(i=0; i< 8; i++) {
+ sprintf((char *)&strval[i*3],"%02X:",data_out[i]);
+ }
+ strval[23] = '\0';
+ return (char *)strval;
+ }
+%}
+
+%{
+extern int OpenDevice (long int BoardAddress);
+extern int CloseDevice (void);
+extern long int ReadAnalogChannel (long int Channelno);
+extern int ReadAllAnalog (long int *data1, long int *data2);
+extern int OutputAnalogChannel (long int Channel, long int data);
+extern int OutputAllAnalog (long int data1, long int data2);
+extern int ClearAllAnalog (void);
+extern int ClearAnalogChannel (long int Channel);
+extern int SetAnalogChannel (long int Channel);
+extern int SetAllAnalog (void);
+extern int WriteAllDigital (long int data);
+extern int ClearDigitalChannel (long int Channel);
+extern int ClearAllDigital (void);
+extern int SetDigitalChannel (long int Channel);
+extern int SetAllDigital (void);
+extern int ReadDigitalChannel (long int Channel);
+extern long int ReadAllDigital (void);
+extern int ResetCounter (long int counternr);
+extern long int ReadCounter (long int CounterNo);
+extern int SetCounterDebounceTime (long int CounterNo, long int DebounceTime);
+extern int ReadAllValues (long int *data1, long int *data2, long int *data3, long int *data4, long int *data5);
+extern int SetAllValues(int digitaldata, int addata1, int addata2);
+extern int SetCounterDebounceTime(long CounterNo, long DebounceTime);
+extern long SetCurrentDevice(long deviceno);
+extern long SearchDevices(void);
+extern char *Version(void);
+
+%}
+/*
+
+And here we create the class interface to the library
+
+*/
+%pythoncode %{
+K8055_ERROR = -1
+_K8055_CLOSED = -1
+
+class k8055:
+ "Class interface to the libk8055 library"
+ def __init__(self,BoardAddress=None,debug=False):
+ """Constructor, optional board open
+
+ k=k8055() # Does not connect to board
+ k=k8055(1) # Init class and connect to board 1
+ k=k8055(1,True) # connect to board 0 and enable debugging
+
+ """
+ self.Buttons = 0
+ self.dev = _K8055_CLOSED
+ self.Address = BoardAddress
+ if debug == False:
+ self.DebugOff()
+ else:
+ self.DebugOn()
+ if BoardAddress != None:
+ try:
+ self.dev = self.OpenDevice(BoardAddress)
+ # print "Open OK " + str(self.dev)
+ except:
+ self.dev = _K8055_CLOSED
+ raise IOError, "Could not open device"
+ # print "Open error"
+
+ def __str__(self):
+ """String format (almost) as from K8055 program"""
+ if self.__opentest() == True: # Device open
+ all = self.ReadAllValues()
+ return str(all[1])+";"+str(all[2])+";"+str(all[3])+";"+str(all[4])+";"+str(all[5])
+ else:
+ return ""
+
+ def __opentest(self):
+ if self.dev == _K8055_CLOSED:
+ return False
+ else:
+ return True
+
+ def OpenDevice(self,BoardAddress):
+ """Open the connection to K8055
+
+ k=k8055()
+ try;
+ k.OpenDevice(0) # possible (address 0/1/2/3)
+ except IOError:
+ ...
+ returns 0 if OK,
+ Throws IOError if invalid board or not accessible
+ """
+ if self.__opentest() == False: # Not open yet
+ self.dev = _pyk8055.OpenDevice(BoardAddress)
+ if self.dev == K8055_ERROR:
+ raise IOError, "Could not open device"
+ # print "Open OK " + str(self.dev)
+ return self.dev
+
+ def CloseDevice(self):
+ """Close the connection to K8055
+
+ k.CloseDevice()
+
+ retuns 0 if OK else -1
+ """
+ if self.dev != _K8055_CLOSED:
+ ret = _pyk8055.CloseDevice()
+ self.dev = _K8055_CLOSED
+ return ret
+
+ def OutputAnalogChannel(self,Channel,value=0):
+ """Set analog output channel value, default 0 (0-255)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.OutputAnalogChannel(Channel,value)
+
+ def ReadAnalogChannel(self,Channel):
+ """Read data from analog input channel (1/2)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.ReadAnalogChannel(Channel)
+
+ def ReadAllAnalog(self):
+ """Read data from both analog input channels at once
+
+ Returns list, [return-value,channel_data1, channel_data2]
+
+ """
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.ReadAllAnalog()
+
+ def OutputAllAnalog(self,data1,data2):
+ """Set both analog output channels at once (0-255,0-255)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.OutputAllAnalog(data1,data2)
+
+ def ClearAllAnalog(self):
+ """Set all (both) analog output channels to 0 (low)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.ClearAllAnalog()
+
+ def ClearAnalogChannel(self,Channel):
+ """Set analog output channel (1/2)to 0 (low)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.ClearAnalogChannel(Channel)
+
+ def SetAnalogChannel(self,Channel):
+ """Set analog output channel (1/2) to 0xFF (high)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.SetAnalogChannel(Channel)
+
+ def SetAllAnalog(self):
+ """Set all (both) analog output channels to 0xFF (high)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.SetAllAnalog()
+
+ def WriteAllDigital(self,data):
+ """Write digital output channel bitmask (0-255)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.WriteAllDigital(data)
+
+ def ClearDigitalChannel(self,Channel):
+ """Clear digital output channel (1-8)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.ClearDigitalChannel(Channel)
+
+ def ClearAllDigital(self):
+ """Set all digital output channels low (0)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.ClearAllDigital()
+
+ def SetDigitalChannel(self,Channel):
+ """Set digital output channel (1-8)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.SetDigitalChannel(Channel)
+
+ def SetAllDigital(self):
+ """Set all digital output channels high (1)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.SetAllDigital()
+
+ def ReadDigitalChannel(self,Channel):
+ """Read digital input channel (1-5), returns 0/1 (-1 on error)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.ReadDigitalChannel(Channel)
+
+ def ReadAllDigital(self):
+ """Read all digital input channels - bitmask
+
+ returns mask 0x00 - 0x1f, 0x01 as channel 1, 0x02 as channel 2...
+ retuns -1 on error
+
+ """
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.ReadAllDigital()
+
+ def ResetCounter(self,CounterNo):
+ """Reset input counter (1/2), input channel 1/2"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.ResetCounter(CounterNo)
+
+ def ReadCounter(self,CounterNo):
+ """Read input counter (1/2), input channel 1/2"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.ReadCounter(CounterNo)
+
+ def SetCounterDebounceTime(self,CounterNo, DebounceTime):
+ """Set counter debounce time on counter 1/2 (1-7450 ms)"""
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.SetCounterDebounceTime(CounterNo,DebounceTime)
+
+ # Makes no sense to switch to another class here
+ def SetCurrentDevice(self):
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.SetCurrentDevice(self.Address)
+
+ # This function makes no sense in this context as
+ # the device is already open
+ #def SearchDevices(self):
+ #return _pyk8055.SearchDevices()
+
+ def DeviceAddress(self):
+ return self.Address
+
+ def IsOpen(self):
+ return self.__opentest()
+
+ def ReadAllValues(self):
+ """Read data from all input channels at once
+
+ Returns list, [return-value,digital input data, analog channel_data1, analog channel_data2, counter1, counter2]
+
+ """
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.ReadAllValues()
+ def SetAllValues(self,digitaldata, addata1, addata2):
+ if self.__opentest() == False : return K8055_ERROR
+ return _pyk8055.SetAllValues(digitaldata, addata1, addata2)
+
+ def Version(self):
+ return _pyk8055.Version();
+
+ def DebugOn(self):
+ _pyk8055.cvar.DEBUG = 1
+ def DebugOff(self):
+ _pyk8055.cvar.DEBUG = 0
+
+ def RawInput(self):
+ return _pyk8055.RawInput()
+ def DumpInput(self):
+ return "In <-"+_pyk8055.DumpInput()
+ def DumpOutput(self):
+ return "Out->"+_pyk8055.DumpOutput()
+
+%}
+extern int OpenDevice (long int BoardAddress);
+extern int CloseDevice (void);
+extern long int ReadAnalogChannel (long int Channelno);
+extern int ReadAllAnalog (long int *data1, long int *data2);
+extern int OutputAnalogChannel (long int Channel, long int data);
+extern int OutputAllAnalog (long int data1, long int data2);
+extern int ClearAllAnalog (void);
+extern int ClearAnalogChannel (long int Channel);
+extern int SetAnalogChannel (long int Channel);
+extern int SetAllAnalog (void);
+extern int WriteAllDigital (long int data);
+extern int ClearDigitalChannel (long int Channel);
+extern int ClearAllDigital (void);
+extern int SetDigitalChannel (long int Channel);
+extern int SetAllDigital (void);
+extern int ReadDigitalChannel (long int Channel);
+extern long int ReadAllDigital (void);
+extern int ResetCounter (long int counternr);
+extern long int ReadCounter (long int CounterNo);
+extern int SetCounterDebounceTime (long int CounterNo, long int DebounceTime);
+extern int ReadAllValues (long int *data1, long int *data2, long int *data3, long int *data4, long int *data5);
+extern int SetAllValues(int digitaldata, int addata1, int addata2);
+extern long SetCurrentDevice(long deviceno);
+extern long SearchDevices(void);
+extern char *Version(void);
diff --git a/pyk8055/pyplotA.py b/pyk8055/pyplotA.py
new file mode 100755
index 0000000..6d19e29
--- /dev/null
+++ b/pyk8055/pyplotA.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+# $Id: pyplotA.py,v 1.2 2007/03/15 14:55:38 pjetur Exp $
+#
+# Simple plotting of analog input data from the K8055 board
+#
+# based on the running plot sample from pyQwt
+# The Python version of qwt-*/examples/data_plot/data_plot.cpp
+
+import random, sys
+from qt import *
+from qwt import *
+from Numeric import *
+from pyk8055 import *
+
+
+class DataPlot(QwtPlot):
+
+ def __init__(self, *args):
+ QwtPlot.__init__(self, *args)
+
+ # Initialize data
+ self.x = arrayrange(0.0, 100.1, 0.5)
+ self.a1 = zeros(len(self.x), Float)
+ self.a2 = zeros(len(self.x), Float)
+
+ self.setTitle("Simple K8055 datascope")
+ self.setAutoLegend(True)
+
+ self.curve1 = self.insertCurve("Input 1")
+ self.curve2 = self.insertCurve("Input 2")
+
+ self.setCurvePen(self.curve1, QPen(Qt.red))
+ self.setCurvePen(self.curve2, QPen(Qt.blue))
+
+ # No automatic scaling, set y-scale 0-255
+ self.setAxisScale(QwtPlot.yLeft,0,255,50)
+
+ # set marker line in the middle - value 128
+ mY = self.insertLineMarker("", QwtPlot.yLeft)
+ self.setMarkerYPos(mY, 128.0)
+
+ self.setAxisTitle(QwtPlot.xBottom, "Time (seconds)")
+ self.setAxisTitle(QwtPlot.yLeft, "Values")
+
+ self.startTimer(50)
+
+ self.k = k8055(0)
+ # __init__()
+
+ def timerEvent(self, e):
+
+ # data moves from left to right:
+ # shift data array right and assign new value data[0]
+
+ self.a1 = concatenate((self.a1[:1], self.a1[:-1]), 1)
+ self.a1[0] = self.k.ReadAnalogChannel(1)
+
+ self.a2 = concatenate((self.a2[:1], self.a2[:-1]), 1)
+ self.a2[0] = self.k.ReadAnalogChannel(2)
+
+ self.setCurveData(self.curve1, self.x, self.a1)
+ self.setCurveData(self.curve2, self.x, self.a2)
+
+ self.replot()
+
+ # timerEvent()
+
+# class DataPlot
+
+def main(args):
+ app = QApplication(args)
+ demo = make()
+ app.setMainWidget(demo)
+ app.exec_loop()
+
+# main()
+
+def make():
+ demo = DataPlot()
+ demo.resize(500, 300)
+ demo.show()
+ return demo
+
+# make()
+
+# Admire
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/pyk8055/pyplotA_1.png b/pyk8055/pyplotA_1.png
new file mode 100644
index 0000000..56ed71d
--- /dev/null
+++ b/pyk8055/pyplotA_1.png
Binary files differ
diff --git a/pyk8055/pyplotD.py b/pyk8055/pyplotD.py
new file mode 100755
index 0000000..9145b37
--- /dev/null
+++ b/pyk8055/pyplotD.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+# $Id: pyplotD.py,v 1.2 2007/03/15 14:55:38 pjetur Exp $
+#
+# Simple plotting of digital input data from the K8055 board
+#
+# based on the running plot sample from pyQwt
+# The Python version of qwt-*/examples/data_plot/data_plot.cpp
+
+import random, sys
+from qt import *
+from qwt import *
+from Numeric import *
+from pyk8055 import *
+
+class DataPlot(QwtPlot):
+
+ def __init__(self, *args):
+ QwtPlot.__init__(self, *args)
+
+ # Initialize data
+ self.x = arrayrange(0.0, 100.1, 0.5)
+ self.d1 = 0.0 + zeros(len(self.x), Float)
+ self.d2 = 1.0 + zeros(len(self.x), Float) # shift data up 1
+ self.d3 = 2.0 + zeros(len(self.x), Float) # Shift data up 2...
+ self.d4 = 3.0 + zeros(len(self.x), Float)
+ self.d5 = 4.0 + zeros(len(self.x), Float)
+
+ self.setTitle("Simple K8055 datascope")
+ self.setAutoLegend(True)
+
+ self.curve1 = self.insertCurve("Input 1")
+ self.curve2 = self.insertCurve("Input 2")
+ self.curve3 = self.insertCurve("Input 3")
+ self.curve4 = self.insertCurve("Input 4")
+ self.curve5 = self.insertCurve("Input 5")
+
+ self.setCurvePen(self.curve1, QPen(Qt.red))
+ self.setCurvePen(self.curve2, QPen(Qt.blue))
+ self.setCurvePen(self.curve3, QPen(Qt.green))
+ self.setCurvePen(self.curve4, QPen(Qt.black))
+ self.setCurvePen(self.curve5, QPen(Qt.cyan))
+
+ # Make data plot shape square
+ self.setCurveStyle(self.curve1, QwtCurve.Steps)
+ self.setCurveStyle(self.curve2, QwtCurve.Steps)
+ self.setCurveStyle(self.curve3, QwtCurve.Steps)
+ self.setCurveStyle(self.curve4, QwtCurve.Steps)
+ self.setCurveStyle(self.curve5, QwtCurve.Steps)
+
+ # Fixed axis here from 0 to 5
+ self.setAxisScale(QwtPlot.yLeft,0,5,1)
+
+ self.setAxisTitle(QwtPlot.xBottom, "Time (seconds)")
+ self.setAxisTitle(QwtPlot.yLeft, "Values")
+
+ self.startTimer(50)
+
+ # init the K8055 board
+ self.k = k8055(0)
+ # __init__()
+
+ def timerEvent(self, e):
+
+ # data moves from left to right:
+ # shift data array right and assign new value data[0]
+
+ self.d1 = concatenate((self.d1[:1], self.d1[:-1]), 1)
+ self.d1[0] = self.k.ReadDigitalChannel(1) * 0.95
+
+ self.d2 = concatenate((self.d2[:1], self.d2[:-1]), 1)
+ self.d2[0] = self.k.ReadDigitalChannel(2) * 0.95 + 1 # Shift data up 1
+
+ self.d3 = concatenate((self.d3[:1], self.d3[:-1]), 1)
+ self.d3[0] = self.k.ReadDigitalChannel(3) * 0.95 + 2 # Shift data up 2...
+
+ self.d4 = concatenate((self.d4[:1], self.d4[:-1]), 1)
+ self.d4[0] = self.k.ReadDigitalChannel(4) * 0.95 + 3
+
+ self.d5 = concatenate((self.d5[:1], self.d5[:-1]), 1)
+ self.d5[0] = self.k.ReadDigitalChannel(5) * 0.95 + 4
+
+ self.setCurveData(self.curve1, self.x, self.d1)
+ self.setCurveData(self.curve2, self.x, self.d2)
+ self.setCurveData(self.curve3, self.x, self.d3)
+ self.setCurveData(self.curve4, self.x, self.d4)
+ self.setCurveData(self.curve5, self.x, self.d5)
+
+ self.replot()
+
+ # timerEvent()
+
+# class DataPlot
+
+def main(args):
+ app = QApplication(args)
+ demo = make()
+ app.setMainWidget(demo)
+ app.exec_loop()
+
+# main()
+
+def make():
+ demo = DataPlot()
+ demo.resize(500, 300)
+ demo.show()
+ return demo
+
+# make()
+
+# Admire
+if __name__ == '__main__':
+ main(sys.argv)
+
diff --git a/pyk8055/pyplotD_2.png b/pyk8055/pyplotD_2.png
new file mode 100644
index 0000000..1603cf4
--- /dev/null
+++ b/pyk8055/pyplotD_2.png
Binary files differ
diff --git a/pyk8055/setup.py b/pyk8055/setup.py
new file mode 100644
index 0000000..b1a1c85
--- /dev/null
+++ b/pyk8055/setup.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+import os,sys,string
+from distutils.core import setup, Extension
+
+__revision__ = "$Id: setup.py,v 1.3 2007/03/28 10:17:57 pjetur Exp $"
+
+if os.environ.has_key('VERSION'):
+ version=os.environ['VERSION']
+else:
+ from subprocess import *
+ try:
+ version = Popen(["grep ^VERSION ../Makefile | cut -d '=' -f 2 | tr -d '\n'"], stdout=PIPE, shell=True).communicate()[0]
+ except:
+ version='?.?'
+
+build_modules = [Extension('_pyk8055',
+ define_macros = [('VERSION', "\"%s\"" % str(version))],
+ libraries=["usb"],
+ sources=['libk8055.i',"../libk8055.c"])]
+
+setup(
+ name='pyk8055',
+ version=version,
+ author='Pjetur G. Hjaltason',
+ author_email='pjetur@pjetur.net',
+ description='K8055 library wrapper',
+ url='http://libk8055.sourceforge.net/',
+ ext_modules =build_modules,
+ py_modules=['pyk8055']
+)
diff --git a/velleman.rules b/velleman.rules
new file mode 100644
index 0000000..f1afc8f
--- /dev/null
+++ b/velleman.rules
@@ -0,0 +1,19 @@
+# velleman.rules a udev rules file for velleman K8055/VM110.
+# Put this file in /etc/udev/rules.d
+#
+# To access the devices under a regular user account, you must
+# be in the k8055 group.
+#
+# You can add a RUN="..." attribute to run some arbitrary script
+# when the device is plugged in.
+
+SUBSYSTEM !="usb_device", ACTION !="add", GOTO="velleman_rules_end"
+
+SYSFS{idVendor}=="10cf", SYSFS{idProduct}=="5500", SYMLINK+="k8055_0"
+SYSFS{idVendor}=="10cf", SYSFS{idProduct}=="5501", SYMLINK+="k8055_1"
+SYSFS{idVendor}=="10cf", SYSFS{idProduct}=="5502", SYMLINK+="k8055_2"
+SYSFS{idVendor}=="10cf", SYSFS{idProduct}=="5503", SYMLINK+="k8055_3"
+
+MODE="0660", GROUP="k8055"
+
+LABEL="velleman_rules_end"