Embedded-linuX/uniX-Devices office[at]exd.at heimo.schoen @ exd.at
Telefon : 0676 316 34 72
privat : heimo @ schoen.priv.at




Velleman Board K8043 reader on linux system

Produktbeschreibung

Der Velleman Bausatz K8043 besitzt einen PIC Controller der sich beim Betriebssystem LINUX als HID Device anmeldet. Linux präsentiert das Board als Deivce /dev/hidraw1 bis /dev/hidraw4 In unserem Fall war /dev/hidraw0 bereits von einer Tastatur vergeben. Daher wurde das K8043 mit den genannten 4 Nummern im dev-Filesystem eingebunden

Nachfolgend zeigen wir das Makefile und das C-Sourcefile, mit dem wir das Velleman K8043 ausgelesen haben:

Hier sehen Sie die C-Sourcen des Leseprogramms mit dem wir das Velleman K8043 unter Linux ausgelesen haben:

/*
**   $Id: velleman.c,v 0.01
**
**   File:     velleman-k8043.c
**   Author:   Heimo Schoen / heimo.schoen@exd.at
**
# Makefile for the velleman K8043 Reader
#
# abstract:
#     the velleman Board K8043 is a USB-Board with a PIC Controller
#     which registers under Linux with Vendor Vendor=10cf and
#     Product=8047 as HID Devices.
#     Linux creates the following Devices when you connect the
#     K8043 to your PC:
#     crw------- 1 root root 250, 1  3. Feb 10:51 /dev/hidraw1
#     crw------- 1 root root 250, 2  3. Feb 10:36 /dev/hidraw2
#     crw------- 1 root root 250, 3  3. Feb 10:36 /dev/hidraw3
#     crw------- 1 root root 250, 4  3. Feb 17:53 /dev/hidraw4
#     in our case there was a /dev/hidraw0 registered allready as 
#     the PC-Keyboard.
#     The interesting device was in our case the /dev/hidraw4 where
#     we could read sequnces of 8 bytes with:
#          TN TN ch1 ch2 ch3 ch4 00 00
#     where TN TN ist a 16 Bit number (lowbyte first) counting up
#     from 0x0000 to 0xffff. Sometimes TN is sent more then once
#     and this application filters the double ones.
#     It seems that K8043 is sending 100 telegrams per second. So
#     we made a counter up to 100 to become new Values all seconds.
#     We calculate an average value over all received 100 values
#     during one second.
#     
#     if you have any questions, feel free to contact us here
#     in Austria / Europe
#     
# executing:
#     sudo velleman-k8043 /dev/hidraw4
#     
#     where the parameter 1 (in our case /dev/hidraw4) should
#     be the device where your K8043 sends his values 100 times
#     per second.
#
#
# Copyright (C) 2017 by Heimo Schön  
#
# 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; version 2 and NOT 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
*/

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define DEBUG 0

// ----------------------------------------------------------
int main(int argc, char *argv[], char *envp[])
{
  int           gelesen           = 0;
  unsigned char readbuffer[10]    = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  int           fh                = 0;
  char          devicename[100]   = "/dev/hidraw4";
  unsigned long summe[4]          = { 0, 0, 0, 0};
  unsigned long sumcounter        = 0;
  unsigned char i                 = 0;
  float         konstante         = (float)30 / (float)255;
  unsigned long stored_last_number= 0xffffff; /* Speicher der letzten
Telegrammnummer mit Vorbelegung beim ersten mal nicht prüfen */
  unsigned long new_number        = 0;        /* Zwischenspeicher für die
aktuelle Telegrammnummer */

  if (argc >= 2) {
    if (strlen(argv[1]) > 1)
      sprintf(devicename, "%s", argv[1]);
  }

  fh  = open(devicename, O_RDONLY);

  if (fh < 3) {

    printf("\n");
    printf("velleman had a problem opening %s\n", devicename);
    printf("\n");
    printf("\n");
    printf("usage of velleman:\n");
    printf("\n");
    printf("    velleman [devicename] [test]\n");
    printf("\n");
    printf("    if parameter devicename is not given, velleman will try to
    open\n");
    printf("    /dev/hidraw4.\n");
    printf("\n");
    printf("example:  velleman /dev/hidraw4\n");
    printf("\n");
    printf("(c) 2017 by Heimo Schön / heimo.schoen@exd.at / http://exd.at\n");
    printf("\n");
    printf("       have a lot fun ...\n");
    printf("\n");

    exit (1);

  } else {

    while (1) {
      gelesen = read(fh, readbuffer, 8);

      if (gelesen != 8) {
	   fprintf(stderr, "Lesefehler: gelesen:%d\n", gelesen);
	   continue;
      }

      /* step 1: header check
	    wir prüfen ob die fortlaufende Nummer in den ersten beiden Bytes
	    ansteigt;
	    wenn nicht, dann wird geprüft ob das Telegramm doppelt war und wir
	    verwerfen das doppelte
	    Telegramm */
      new_number = (readbuffer[1] << 8) + readbuffer[0];
      if ( ( new_number != stored_last_number ) &&  (stored_last_number <
	    0xffffff) ) {
									   /*
	    wenn es die vorige Nummer ist, die nochmal gesendet wurde */
									   if
	    (new_number == stored_last_number - 1) {
#if DEBUG
									     /*
	    dann wird dieses doppelt erhalten Telegramm diagnostiziert und
	    verworfen */
									     fprintf(stderr,
	    "die letzte gespeicherte Nummer war: stored_last_number:%ld und
	    die neue Nummer:%ld %02x %02x %02x %02x %02x %02x %02x %02x :
	    ERROR\n",
									     stored_last_number,
	    new_number,
									     readbuffer[0], 
									     readbuffer[1], 
									     readbuffer[2], 
									     readbuffer[3], 
									     readbuffer[4], 
									     readbuffer[5], 
									     readbuffer[6], 
									     readbuffer[7]);
#endif
									     stored_last_number
	    = new_number + 1;
									     /*
	    dann ignorieren wir dieses Telegramm */
									     continue;
									   }
	    else {
									     fprintf(stderr,
	    "die letzte gespeicherte Nummer war: stored_last_number:%ld und
	    die neue Nummer:%ld %02x %02x %02x %02x %02x %02x %02x %02x :
	    ERROR\n",
									     stored_last_number,
	    new_number,
									     readbuffer[0], 
									     readbuffer[1], 
									     readbuffer[2], 
									     readbuffer[3], 
									     readbuffer[4], 
									     readbuffer[5], 
									     readbuffer[6], 
									     readbuffer[7]);
									     stored_last_number
	    = new_number + 1;
									     continue;
									   }
      } else {
#if DEBUG
									   fprintf(stderr,
	    "die letzte gespeicherte Nummer war: stored_last_number:%ld und
	    die neue Nummer:%ld %02x %02x %02x %02x %02x %02x %02x %02x :
	    O.K.\n",
									   stored_last_number,
	    new_number,
									   readbuffer[0], 
									   readbuffer[1], 
									   readbuffer[2], 
									   readbuffer[3], 
									   readbuffer[4], 
									   readbuffer[5], 
									   readbuffer[6], 
									   readbuffer[7]);
#endif
      }
      /* den Zähler auf die nächste zu erwartende Nummer stellen */
      stored_last_number = new_number + 1;
      /* den wrap-around der fortlaufenden Nummer beachten */
      if (stored_last_number > 0xffff)
				     stored_last_number = 0;


      /* step 2:
				      wir summieren die Werte in bytes 2,3,4
				      und 5 in einem Array für die
				      Mittelwertbildung */
      for (i=0; i<4; i++) {
		     summe[i] += readbuffer[2+i];
		     }

      /* step 3:
		      den Zähler für die Mittelwertbildung erhöhen */
      sumcounter ++;

      /* step 4:
		      trailercheck. There should be 0x00 and 0x00 as trailing
		      bytes */
      if ( (readbuffer[6] != 0x00) || (readbuffer[7] != 0x00) ) {
		     fprintf(stderr, "das empfangene Telegramm hat nicht 0x00
		      0x00 als Trailer:  %02x %02x %02x %02x %02x %02x %02x
		      %02x\n",
		     readbuffer[0], 
		     readbuffer[1], 
		     readbuffer[2], 
		     readbuffer[3], 
		     readbuffer[4], 
		     readbuffer[5], 
		     readbuffer[6], 
		     readbuffer[7]);
		     continue;
      }

      /* step 5: we have data
		      wenn 100 Meßwerte gelesen wurden dann machen wir die
		      Mittelwerbildung
		      und geben die Werte mit printf aus. */
      if (sumcounter >= 100) {

#if DEBUG
				     fprintf(stdout, "gelesen: %d bytes: %02x
				     %02x %02x %02x %02x %02x %02x %02x   val:
				     %2.2f %2.2f %2.2f %2.2f\n", 
				     gelesen, 
				     readbuffer[0], 
				     readbuffer[1], 
				     readbuffer[2], 
				     readbuffer[3], 
				     readbuffer[4], 
				     readbuffer[5], 
				     readbuffer[6], 
				     readbuffer[7],
				     konstante * (float)((float)summe[0] /
				     (float)sumcounter), 
				     konstante * (float)((float)summe[1] /
				     (float)sumcounter), 
				     konstante * (float)((float)summe[2] /
				     (float)sumcounter), 
				     konstante * (float)((float)summe[3] /
				     (float)sumcounter));
#else
				     fprintf(stdout, "%5.2fV %5.2fV %5.2fV
				     %5.2fV\n", 
				     konstante * (float)((float)summe[0] /
				     (float)sumcounter), 
				     konstante * (float)((float)summe[1] /
				     (float)sumcounter), 
				     konstante * (float)((float)summe[2] /
				     (float)sumcounter), 
				     konstante * (float)((float)summe[3] /
				     (float)sumcounter));
#endif
				     /* Zurücksetzen der Mittelwertbildung */
				     sumcounter = 0;
				     for (i=0; i<4; i++) {
						      summe[i] = 0;
						    }

      } /* if sumcounter >= 100 */

    } /* while (1) */
  }

  return 0;
}

      


Hier das dazu gehörige Makefile:
#
# Makefile for the velleman K8043 Reader
#
# abstract:
#     the velleman Board K8043 is a USB-Board with a PIC Controller
#     which registers under Linux with Vendor Vendor=10cf and
#     Product=8047 as HID Devices.
#     Linux creates the following Devices when you connect the
#     K8043 to your PC:
#     crw------- 1 root root 250, 1  3. Feb 10:51 /dev/hidraw1
#     crw------- 1 root root 250, 2  3. Feb 10:36 /dev/hidraw2
#     crw------- 1 root root 250, 3  3. Feb 10:36 /dev/hidraw3
#     crw------- 1 root root 250, 4  3. Feb 17:53 /dev/hidraw4
#     in our case there was a /dev/hidraw0 registered allready as 
#     the PC-Keyboard.
#     The interesting device was in our case the /dev/hidraw4 where
#     we could read sequnces of 8 bytes with:
#          TN TN ch1 ch2 ch3 ch4 00 00
#     where TN TN ist a 16 Bit number (lowbyte first) counting up
#     from 0x0000 to 0xffff. Sometimes TN is sent more then once
#     and this application filters the double ones.
#     It seems that K8043 is sending 100 telegrams per second. So
#     we made a counter up to 100 to become new Values all seconds.
#     We calculate an average value over all received 100 values
#     during one second.
#     
#     if you have any questions, feel free to contact us here
#     in Austria / Europe
#     
# executing:
#     sudo velleman-k8043 /dev/hidraw4
#     
#     where the parameter 1 (in our case /dev/hidraw4) should
#     be the device where your K8043 sends his values 100 times
#     per second.
#
# Copyright (C) 2017 Heimo Schön 
#
# 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; version 2 and NOT 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#

           CFLAGS        =  -std=gnu99 -pedantic -Wall -O0 -g

           LDOPTIONS     = -g
         RM            = rm -f

           VELLEMANSRCS = velleman-k8043.c
           VELLEMANOBJS = $(patsubst %.c,%.o,$(VELLEMANSRCS))

all:: velleman-k8043 

tags: 
      etags *.[hc]

velleman-k8043 :  $(VELLEMANOBJS) $(DEPLIBS)
      $(RM) $@
      $(CC) -o $@ $(VELLEMANOBJS) $(LDOPTIONS)

clean::
      $(RM) velleman-k8043  *.o *~

depend::
      @if [ -n "$(VELLEMANSRCS)" ] ; then set -x;\
        $(DEPEND) $(DEPENDFLAGS) $(VELLEMANSRCS);\
      fi
Die weitere Verarbeitung der Daten erfolgte mit rrd-tool unter python, wurden die Messdaten alle Sekunden in eine rrd-Datenbank gespeichert und dann mit rrd-tool graphisch aufbereitet.

Damit haben wir mit wenig Aufwand einen Graphischen Datenlogger bzw. einen Messdaten-Schreiber gebaut um lange dauernde Prozesse zu protokollieren.

Die Idee bei unserem Projekt war, dass wir uns keinen Messdatenlogger leisten wollten um die Kapazitäten von Bleiakkus zu messen. Daher habe wir den Entladezyklus mit einem Velleman K8043 und obigem Programm mitgeschrieben um die Akkukapazität messen zu können.

Die Genauigkeit spielt bei solchen Projekten keine Rolle, da bei der Blei-Nasszellen Kapazitätsmessung egal ist ob die Messung auf einige Prozent genau sind, weil defekte Akkus viel größere Abweichungen von den Solldaten haben, so dass die Meßfehler eher verschwinden.


© 1997-2016 by Dipl.-HTL-Ing. Heimo SCHÖN
Zur Homepage von EXD - embedded linux devices / Heimo Schön / August Hörandl . Ein E-Mail senden. Den Disclaimer oder die AGB lesen.