|
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.
|
|