initial import

This commit is contained in:
Steffen Vogel 2010-08-17 01:21:00 +02:00
commit 79f4719040
17 changed files with 1041 additions and 0 deletions

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
.settings
.cproject
.project
.classpath

BIN
DSC00102.JPG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

51
README Normal file
View file

@ -0,0 +1,51 @@
dmmut61e - UNI-TREND UT61E Digital Multimeter
---------------------------------------------
Copyright (C) 2009 Steffen Vogel (info@steffenvogel.de)
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Dieses Programm liest den seriellen Datenstrom eines UNI TREND UT61E Digitalmultimeters ein und gibt ihn als CSV aus.
In diesem Format können die Daten ausgewertet werden oder gleich mit dem mitgelieferten Skript (graph) und gnuplot dargestellt werden.
USAGE
---------------------------------------------
dmmut61e /dev/ttyS0
graph /dev/ttyS0
DEPENDENCIES
---------------------------------------------
grep, cut, gnuplot, tail, bash
CHANGELOG
---------------------------------------------
29.11.2009 - 0.01
- Initial version
CONTACT
---------------------------------------------
Steffen Vogel
info@steffenvogel.de
www.steffenvogel.de
Please send patches, bug reports, hints and donations via mail!

42
SerialPort.cpp Normal file
View file

@ -0,0 +1,42 @@
/*
* SerialPort.cpp
*
* Created on: 14.11.2009
* Author: steffen
*/
#include "SerialPort.h"
#include <exception>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <strings.h>
#include <stdio.h>
SerialPort::SerialPort(char port[]) {
fd = open(port, O_RDWR | O_NOCTTY);
if (fd < 0) {
perror("Unable to open port ");
}
tcgetattr(fd, &oldtio); /* save current serial port settings */
bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
newtio.c_cflag = B19200 | CS7 | PARENB | PARODD | CSTOPB | CREAD | CLOCAL;
newtio.c_iflag = 0;
newtio.c_oflag = 0;
newtio.c_lflag = ICANON;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);
int line_bits;
ioctl(fd, TIOCMGET, &line_bits);
line_bits |= TIOCM_DTR;
line_bits &= ~TIOCM_RTS;
ioctl(fd, TIOCMSET, &line_bits);
}
SerialPort::~SerialPort() {
/* restore the old port settings */
tcsetattr(fd, TCSANOW, &oldtio);
}

272
UT61E.cpp Normal file
View file

@ -0,0 +1,272 @@
/*
* UT61E.cpp
*
* Created on: 12.11.2009
* Author: steffen
*/
#include "UT61E.h"
#include <exception>
#include <cstdlib>
const char* UT61E::modelbl[] = { "V", "A", "Ohm", "-|>-", "Hz", "F", "H", "-/ -" };
const char* UT61E::fmodelbl[] = { "Duty" , "Frequence" };
const char* UT61E::powerlbl[] = {"AC", "DC" };
const char* UT61E::rangelbl[] = { "Auto", "Manual" };
const char* UT61E::loadlbl[] = { "Overload", "Normal", "Underload" };
const char* UT61E::peaklbl[] = { "Maximum", "Minimum" };
UT61E::UT61E() {
mode = VOLTAGE;
}
UT61E::~UT61E() {}
const char* UT61E::getMode() {
return UT61E::modelbl[mode];
}
const char* UT61E::getPower() {
return UT61E::powerlbl[power];
}
const char* UT61E::getRange() {
return UT61E::rangelbl[range];
}
bool UT61E::check(char * data) {
if ((data[0] & 0x30) == 0x30 && data[12] == 0x0d && data[13] == 0x0a) {
return true;
} else {
return false;
}
}
void UT61E::parse(char * data) {
char digits[] = { data[1], data[2], data[3], data[4], data[5] };
value = atof(digits);
lastmode = mode;
bat = (data[7] & 2) ? true : false;
rel = (data[8] & 2) ? true : false;
hold = (data[11] & 2) ? true : false;
if (data[7] & 0x04)
value *= -1;
if (data[10] & 8)
power = DC;
else if (data[10] & 4)
power = AC;
if (data[10] & 2)
range = AUTO;
else
range = MANUAL;
if (data[7] & 1)
load = OVERLOAD;
else if (data[9] & 8)
load = UNDERLOAD;
else
load = NORMAL;
if (data[9] & 4)
peak = MAX;
else if (data[9] & 2)
peak = MIN;
if (data[10] & 1)
fmode = FREQUENCE;
if (data[7] & 8)
fmode = DUTY;
double multp = 1;
switch (data[6]) {
case '1':
mode = DIODE;
break;
case '2':
mode = FREQUENCY;
switch (data[0]) {
case '0':
multp = 1e-2;
break;
case '1':
multp = 1e-1;
break;
case '3':
multp = 1;
break;
case '4':
multp = 1e1;
break;
case '5':
multp = 1e2;
break;
case '6':
multp = 1e3;
break;
case '7':
multp = 1e4;
break;
default:
throw std::exception();
}
break;
case '3':
mode = RESISTANCE;
switch (data[0]) {
case '0':
multp = 1e-2;
break;
case '1':
multp = 1e-1;
break;
case '2':
multp = 1;
break;
case '3':
multp = 1e1;
break;
case '4':
multp = 1e2;
break;
case '5':
multp = 1e3;
break;
case '6':
multp = 1e4;
break;
default:
throw std::exception();
}
break;
case '5':
mode = CONDUCTANCE;
break;
case '6':
mode = CAPACITANCE;
switch (data[0]) {
case '0':
multp = 1e-12;
break;
case '1':
multp = 1e-11;
break;
case '2':
multp = 1e-10;
break;
case '3':
multp = 1e-9;
break;
case '4':
multp = 1e-8;
break;
case '5':
multp = 1e-7;
break;
case '6':
multp = 1e-6;
break;
case '7':
multp = 1e-5;
break;
default:
throw std::exception();
}
break;
case 0x3b: // V
mode = VOLTAGE;
switch (data[0]) {
case '0':
multp = 1e-4;
break;
case '1':
multp = 1e-3;
break;
case '2':
multp = 1e-2;
break;
case '3':
multp = 1e-1;
break;
case '4':
multp = 1e-5;
break;
default:
throw std::exception();
}
break;
case '0': // A
mode = CURENT;
if (data[0] == '0')
multp = 1e-3;
else {
throw std::exception();
}
break;
case 0x3d: // uA
mode = CURENT;
switch (data[0]) {
case '0':
multp = 1e-8;
break;
case '1':
multp = 1e-7;
break;
default:
throw std::exception();
}
break;
case 0x3f: // mA
mode = CURENT;
switch (data[0]) {
case '0':
multp = 1e-6;
break;
case '1':
multp = 1e-5;
break;
default:
throw std::exception();
}
break;
default:
throw std::exception();
}
value *= multp;
if (mode != lastmode) {
max = 0;
min = 0;
sample = 0;
avarage = value;
}
if (value > max)
max = value;
if (value < min)
min = value;
avarage = (sample * avarage + value) / ++sample;
}

44
UT61E.h Normal file
View file

@ -0,0 +1,44 @@
/*
* UT61E.h
*
* Created on: 12.11.2009
* Author: steffen
*/
#ifndef UT61E_H_
#define UT61E_H_
class UT61E {
public:
UT61E();
virtual ~UT61E();
bool check(char * data);
void parse(char * data);
const char* getMode();
const char* getPower();
const char* getRange();
double value, max, min, avarage;
long sample;
char data[14];
bool hold, rel, bat;
enum { VOLTAGE, CURENT, RESISTANCE, DIODE, FREQUENCY, CAPACITANCE, INDUCTANCE, CONDUCTANCE } mode, lastmode;
enum { DUTY, FREQUENCE } fmode;
enum { AC, DC } power;
enum { AUTO, MANUAL } range;
enum { OVERLOAD, NORMAL, UNDERLOAD } load;
enum { MAX, MIN } peak;
private:
static const char* modelbl[];
static const char* fmodelbl[];
static const char* powerlbl[];
static const char* rangelbl[];
static const char* loadlbl[];
static const char* peaklbl[];
};
#endif /* UT61E_H_ */

112
UT61E.txt Normal file
View file

@ -0,0 +1,112 @@
UT61E: Handmultimeter der chinesischen Firma UNI-Trend
Vergleichbare Paketisierung: UT61B, identisch
Vergleichbares Protokoll: UT70B, aber verschieden genug
Counts: 22000 (5-stellig)
DCB: 19200 Baud,7,1,Odd,DTR+,RTS-
Paket: Länge 14, TotalTimeOut: 1000?, Markierung: "\r\n", eindeutig
UT61E.exe: HidD_SetFeature: magisches Byte immer noch 3 - Software geht nicht!
0 1 2 3 4 5 6 7 8 9 10 11 12 13
DC 0.0000 V AUTO BG 30 30 30 30 30 30 3B 30 30 30 3A 30 0D 0A
DC 0.0000 V MANU BG 30 30 30 30 30 30 3B 30 30 30 38 30 0D 0A
DC 0.000 V MANU BG 31 30 30 30 30 30 3B 30 30 30 38 30 0D 0A UT61E.EXE zeigt stets führende Nullen
DC 0.00 V MANU BG 32 30 30 30 30 30 3B 30 30 30 38 30 0D 0A
DC 0.0 V MANU BG 33 30 30 30 30 30 3B 30 30 30 38 30 0D 0A
DC -0.0000 V M. BG Rel 30 30 30 30 30 30 3B 30 32 30 38 30 0D 0A
DC 0.0197 V M. BG MAX 30 30 30 31 39 37 3B 30 30 34 38 30 0D 0A
DC -0.0222 V M. BG MIN 30 30 30 32 32 32 3B 34 30 32 38 30 0D 0A
DC 0.00 Hz AUTO 30 30 30 30 30 30 3B 30 30 30 3B 30 0D 0A
DC 0.0000 V A. LowBat 30 30 30 30 30 30 3B 32 30 30 3A 30 0D 0A
DC - 30.55 mV MANU BG 34 30 33 30 35 35 3B 34 30 30 38 30 0D 0A Keine Bereichsumschaltung!
AC 81.53 mV MANU BG 34 30 38 31 35 33 3B 30 30 30 34 30 0D 0A
DC 0.00 Hz AUTO 30 30 30 30 30 30 3B 30 30 30 3B 30 0D 0A unabhängig ob V- oder mV-Bereich!
DC 50.0 Hz AUTO 31 30 30 35 30 30 3B 30 30 30 3B 30 0D 0A
DC 49.4 % MANU 30 30 30 34 39 34 3B 38 30 30 39 30 0D 0A
UL . % MANU 30 30 30 30 30 30 3B 38 30 38 39 30 0D 0A
0L. MOhm AUTO 36 32 32 35 38 30 33 31 30 30 32 30 0D 0A
0L. MOhm MANU 36 32 32 35 38 30 33 31 30 30 30 30 0D 0A
0.00 MOhm MANU 36 30 30 30 30 30 33 30 30 30 30 30 0D 0A
0L. Ohm MANU 30 32 32 35 38 30 33 31 30 30 30 30 0D 0A
.0L kOhm MANU 31 32 32 35 38 30 33 31 30 30 30 30 0D 0A
0.L kOhm MANU 32 32 32 35 38 30 33 31 30 30 30 30 0D 0A
0L. kOhm MANU 33 32 32 35 38 30 33 31 30 30 30 30 0D 0A
.0L MOhm MANU 34 32 32 35 38 30 33 31 30 30 30 30 0D 0A
0.L MOhm MANU 35 32 32 35 38 30 33 31 30 30 30 30 0D 0A
0L. Ohm M. Pieps 30 32 32 35 38 30 35 31 30 30 30 30 0D 0A Keine Bereichsumschaltung!
.0L V MANU Diode 30 32 32 35 38 30 31 31 30 30 30 30 0D 0A Keine Bereichsumschaltung!
0.042 nF AUTO 30 30 30 30 34 32 36 30 30 30 32 30 0D 0A
0.03 nF MANU 31 30 30 30 30 33 36 30 30 30 30 30 0D 0A
0.0000 µF MANU 32 30 30 30 30 30 36 30 30 30 30 30 0D 0A
0.000 µF MANU 33 30 30 30 30 30 36 30 30 30 30 30 0D 0A
0.00 µF MANU 34 30 30 30 30 30 36 30 30 30 30 30 0D 0A
0.0000 mF MANU 35 30 30 30 30 30 36 30 30 30 30 30 0D 0A
0.000 mF MANU 36 30 30 30 30 30 36 30 30 30 30 30 0D 0A
0.00 mF MANU 37 30 30 30 30 30 36 30 30 30 30 30 0D 0A
0.00 Hz AUTO 30 30 30 30 30 30 32 30 30 30 32 30 0D 0A
0.0 Hz MANU 31 30 30 30 30 30 32 30 30 30 30 30 0D 0A
0.0000 kHz MANU Diesen Bereich gibt es nicht!
0.000 kHz MANU 33 30 30 30 30 30 32 30 30 30 30 30 0D 0A
0.00 kHz MANU 34 30 30 30 30 30 32 30 30 30 30 30 0D 0A
0.0000 MHz MANU 35 30 30 30 30 30 32 30 30 30 30 30 0D 0A
0.000 MHz MANU 36 30 30 30 30 30 32 30 30 30 30 30 0D 0A
0.00 MHz MANU 37 30 30 30 30 30 32 30 30 30 30 30 0D 0A
UL . % MANU 30 30 30 30 30 30 32 38 30 38 30 30 0D 0A UT61E.EXE zeigt "00L0.0 %"
16.3 % MANU 34 30 30 31 36 33 32 38 30 30 30 30 0D 0A
DC 0.00 µA AUTO 30 30 30 30 30 30 3D 30 30 30 3A 30 0D 0A UT61E.EXE zeigt u.a. auch den Bereich: ±220
DC 0.0 µA MANU 31 30 30 30 30 30 3D 30 30 30 38 30 0D 0A UT61E.EXE zeigt hier den Bereich falsch!
AC 0.9 µA MANU 31 30 30 30 30 39 3D 30 30 30 34 30 0D 0A
AC 0.00 Hz AUTO 30 30 30 30 30 30 3D 30 30 30 37 30 0D 0A
AC UL . % MANU 30 30 30 30 30 30 3D 38 30 38 35 30 0D 0A
AC 0.007 mA AUTO 30 30 30 30 30 37 3F 30 30 30 36 30 0D 0A
AC 0.03 mA AUTO 31 30 30 30 30 33 3F 30 30 30 34 30 0D 0A
AC 0.016 A MANU 30 30 30 30 31 36 30 30 30 30 34 30 0D 0A
AC 0.000 A MANU HOLD 30 30 30 30 30 30 30 30 30 30 34 32 0D 0A
Byte 6 5 4 3 2 1 0
[0] Bereich 0 1 1 0 ====siehe unten===
[1] 1. Ziffer 0 1 1 ===========Ziffer=========
[2] 2. Ziffer 0 1 1 ===========Ziffer=========
[3] 3. Ziffer 0 1 1 ===========Ziffer=========
[4] 4. Ziffer 0 1 1 ===========Ziffer=========
[5] 5. Ziffer 0 1 1 ===========Ziffer=========
[6] Schalterst. 0 1 1 ========siehe unten=======
[7] Info 0 1 1 % NEG LowBat OVL
[8] 0 1 1 0 0 Rel 0
[9] 0 1 1 UL MAX MIN 0 // MIN und MAX wird wechselweise übertragen
[10] Kopplung 0 1 1 DC AC AUTO Hz // DC und AC nie kombiniert
[11] 0 1 1 0 0 HOLD 0
[12] '\r' 0 0 0 1 1 0 1
[13] '\n' 0 0 0 1 0 1 0
Bereich (Byte[0]): V mV Ohm F Hz µA mA A %
'0' 2.2 - 220 22n 220 220µ 22m 10 *
'1' 22 - 2.2k 220n 2200 2200µ 220m - *
'2' 220 - 22k 2.2µ - - - - -
'3' 1000 - 220k 22µ 22k - - - *
'4' - 220m 2.2M 220µ 220k - - - *
'5' - - 22M 2.2m 2.2M - - - *
'6' - - 220M 22m 22M - - - *
'7' - - - 220m 220M - - - *
*: Tastverhältnis-Anzeige: Bereichsangabe bezieht sich auf Frequenzmessung
Schalterstellung (Byte[6]):
'0' A
'1' Diode
'2' Hz
'3' Ohm
'5' Pieps
'6' F
';'(3B) V, mV
'='(3D) µA
'?'(3F) mA

BIN
bin/dmmut61e Executable file

Binary file not shown.

58
bin/graph Executable file
View file

@ -0,0 +1,58 @@
#!/bin/bash
PORT=/dev/ttyUSB0
./Debug/DMM $1 > /tmp/dmm_data.csv &
echo "Start sampling"
sleep 3
cat > /tmp/dmm_plot.cmd << EOF
unit = "\`tail -1 /tmp/dmm_data.csv | cut -d ";" -f 6 -s\`"
set terminal x11
set terminal x11 enhanced font "arial,15"
set terminal x11 title "Digital Multimeter"
set terminal x11 noraise
unset label
set key nobox at character 125, 5
set border 3
set grid
set autoscale y
set xrange [0:50]
set grid noxtics back
set ylabel unit
set label " \`tail -1 /tmp/dmm_data.csv | cut -d ";" -f 2 -s\` " . unit at character 1, 2 font "arial,60"
set label "Min: \`tail -1 /tmp/dmm_data.csv | cut -d ";" -f 4 -s\` " . unit at character 45, 3
set label "Max: \`tail -1 /tmp/dmm_data.csv | cut -d ";" -f 3 -s\` " . unit at character 45, 2
set label "Avg: \`tail -1 /tmp/dmm_data.csv | cut -d ";" -f 5 -s\` " . unit at character 45, 1
set label "AC/DC: \`tail -1 /tmp/dmm_data.csv | cut -d ";" -f 7 -s\` " at character 80, 3
set label "Range: \`tail -1 /tmp/dmm_data.csv | cut -d ";" -f 8 -s\` " at character 80, 2
set label "Sample: \`tail -1 /tmp/dmm_data.csv | cut -d ";" -f 1 -s\` " at character 80, 1
set label "by Steffen Vogel" at character 100, 2
set label "www.steffenvogel.de" at character 100, 1
set bmargin 7
set datafile separator ";"
plot "< tail -n 50 /tmp/dmm_data.csv" using 0:2 title "Value" smooth unique,\
"< tail -n 50 /tmp/dmm_data.csv" using 0:5 title "Avarage" smooth csplines
reread
EOF
echo "Start plotting..."
gnuplot -geometry 1000x600 /tmp/dmm_plot.cmd
echo "Remove temporary files"
rm /tmp/dmm_data.csv
rm /tmp/dmm_plot.cmd
killall DMM

BIN
dmmut61e-0.01.tar.gz Normal file

Binary file not shown.

38
main.cpp Normal file
View file

@ -0,0 +1,38 @@
#include "UT61E.h"
#include "SerialPort.h"
#include <iostream>
#include <cstdlib>
void usage(void) {
std::cout << "Usage: dmmut61e <serialport>" << std::endl;
}
int main(int argc, char *argv[]) {
if (argc == 1) {
usage();
exit(0);
}
UT61E * dmm = new UT61E();
SerialPort * port = new SerialPort(argv[1]);
int res;
char buf[14];
while (true) {
res = read(port->fd, buf, 14);
if (dmm->check(buf) && res == 14) {
dmm->parse(buf);
if (!dmm->hold)
std::cout << dmm->sample << ";" << dmm->value << ";" << dmm->max << ";" << dmm->min << ";" << dmm->avarage << ";" << dmm->getMode() << ";" << dmm->getPower() << ";" << dmm->getRange() << std::endl;
} else {
std::cerr << "Invalid data!" << std::endl;
}
}
}

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

42
src/SerialPort.cpp Normal file
View file

@ -0,0 +1,42 @@
/*
* SerialPort.cpp
*
* Created on: 14.11.2009
* Author: steffen
*/
#include "SerialPort.h"
#include <exception>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <strings.h>
#include <stdio.h>
SerialPort::SerialPort(char port[]) {
fd = open(port, O_RDWR | O_NOCTTY);
if (fd < 0) {
perror("Unable to open port ");
}
tcgetattr(fd, &oldtio); /* save current serial port settings */
bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
newtio.c_cflag = B19200 | CS7 | PARENB | PARODD | CSTOPB | CREAD | CLOCAL;
newtio.c_iflag = 0;
newtio.c_oflag = 0;
newtio.c_lflag = ICANON;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);
int line_bits;
ioctl(fd, TIOCMGET, &line_bits);
line_bits |= TIOCM_DTR;
line_bits &= ~TIOCM_RTS;
ioctl(fd, TIOCMSET, &line_bits);
}
SerialPort::~SerialPort() {
/* restore the old port settings */
tcsetattr(fd, TCSANOW, &oldtio);
}

23
src/SerialPort.h Normal file
View file

@ -0,0 +1,23 @@
/*
* SerialPort.h
*
* Created on: 14.11.2009
* Author: steffen
*/
#ifndef SERIALPORT_H_
#define SERIALPORT_H_
#include <termios.h>
class SerialPort {
public:
SerialPort(char port[]);
virtual ~SerialPort();
int fd;
private:
struct termios oldtio, newtio;
};
#endif /* SERIALPORT_H_ */

272
src/UT61E.cpp Normal file
View file

@ -0,0 +1,272 @@
/*
* UT61E.cpp
*
* Created on: 12.11.2009
* Author: steffen
*/
#include "UT61E.h"
#include <exception>
#include <cstdlib>
const char* UT61E::modelbl[] = { "V", "A", "Ohm", "-|>-", "Hz", "F", "H", "-/ -" };
const char* UT61E::fmodelbl[] = { "Duty" , "Frequence" };
const char* UT61E::powerlbl[] = {"AC", "DC" };
const char* UT61E::rangelbl[] = { "Auto", "Manual" };
const char* UT61E::loadlbl[] = { "Overload", "Normal", "Underload" };
const char* UT61E::peaklbl[] = { "Maximum", "Minimum" };
UT61E::UT61E() {
mode = VOLTAGE;
}
UT61E::~UT61E() {}
const char* UT61E::getMode() {
return UT61E::modelbl[mode];
}
const char* UT61E::getPower() {
return UT61E::powerlbl[power];
}
const char* UT61E::getRange() {
return UT61E::rangelbl[range];
}
bool UT61E::check(char * data) {
if ((data[0] & 0x30) == 0x30 && data[12] == 0x0d && data[13] == 0x0a) {
return true;
} else {
return false;
}
}
void UT61E::parse(char * data) {
char digits[] = { data[1], data[2], data[3], data[4], data[5] };
value = atof(digits);
lastmode = mode;
bat = (data[7] & 2) ? true : false;
rel = (data[8] & 2) ? true : false;
hold = (data[11] & 2) ? true : false;
if (data[7] & 0x04)
value *= -1;
if (data[10] & 8)
power = DC;
else if (data[10] & 4)
power = AC;
if (data[10] & 2)
range = AUTO;
else
range = MANUAL;
if (data[7] & 1)
load = OVERLOAD;
else if (data[9] & 8)
load = UNDERLOAD;
else
load = NORMAL;
if (data[9] & 4)
peak = MAX;
else if (data[9] & 2)
peak = MIN;
if (data[10] & 1)
fmode = FREQUENCE;
if (data[7] & 8)
fmode = DUTY;
double multp = 1;
switch (data[6]) {
case '1':
mode = DIODE;
break;
case '2':
mode = FREQUENCY;
switch (data[0]) {
case '0':
multp = 1e-2;
break;
case '1':
multp = 1e-1;
break;
case '3':
multp = 1;
break;
case '4':
multp = 1e1;
break;
case '5':
multp = 1e2;
break;
case '6':
multp = 1e3;
break;
case '7':
multp = 1e4;
break;
default:
throw std::exception();
}
break;
case '3':
mode = RESISTANCE;
switch (data[0]) {
case '0':
multp = 1e-2;
break;
case '1':
multp = 1e-1;
break;
case '2':
multp = 1;
break;
case '3':
multp = 1e1;
break;
case '4':
multp = 1e2;
break;
case '5':
multp = 1e3;
break;
case '6':
multp = 1e4;
break;
default:
throw std::exception();
}
break;
case '5':
mode = CONDUCTANCE;
break;
case '6':
mode = CAPACITANCE;
switch (data[0]) {
case '0':
multp = 1e-12;
break;
case '1':
multp = 1e-11;
break;
case '2':
multp = 1e-10;
break;
case '3':
multp = 1e-9;
break;
case '4':
multp = 1e-8;
break;
case '5':
multp = 1e-7;
break;
case '6':
multp = 1e-6;
break;
case '7':
multp = 1e-5;
break;
default:
throw std::exception();
}
break;
case 0x3b: // V
mode = VOLTAGE;
switch (data[0]) {
case '0':
multp = 1e-4;
break;
case '1':
multp = 1e-3;
break;
case '2':
multp = 1e-2;
break;
case '3':
multp = 1e-1;
break;
case '4':
multp = 1e-5;
break;
default:
throw std::exception();
}
break;
case '0': // A
mode = CURENT;
if (data[0] == '0')
multp = 1e-3;
else {
throw std::exception();
}
break;
case 0x3d: // uA
mode = CURENT;
switch (data[0]) {
case '0':
multp = 1e-8;
break;
case '1':
multp = 1e-7;
break;
default:
throw std::exception();
}
break;
case 0x3f: // mA
mode = CURENT;
switch (data[0]) {
case '0':
multp = 1e-6;
break;
case '1':
multp = 1e-5;
break;
default:
throw std::exception();
}
break;
default:
throw std::exception();
}
value *= multp;
if (mode != lastmode) {
max = 0;
min = 0;
sample = 0;
avarage = value;
}
if (value > max)
max = value;
if (value < min)
min = value;
avarage = (sample * avarage + value) / ++sample;
}

44
src/UT61E.h Normal file
View file

@ -0,0 +1,44 @@
/*
* UT61E.h
*
* Created on: 12.11.2009
* Author: steffen
*/
#ifndef UT61E_H_
#define UT61E_H_
class UT61E {
public:
UT61E();
virtual ~UT61E();
bool check(char * data);
void parse(char * data);
const char* getMode();
const char* getPower();
const char* getRange();
double value, max, min, avarage;
long sample;
char data[14];
bool hold, rel, bat;
enum { VOLTAGE, CURENT, RESISTANCE, DIODE, FREQUENCY, CAPACITANCE, INDUCTANCE, CONDUCTANCE } mode, lastmode;
enum { DUTY, FREQUENCE } fmode;
enum { AC, DC } power;
enum { AUTO, MANUAL } range;
enum { OVERLOAD, NORMAL, UNDERLOAD } load;
enum { MAX, MIN } peak;
private:
static const char* modelbl[];
static const char* fmodelbl[];
static const char* powerlbl[];
static const char* rangelbl[];
static const char* loadlbl[];
static const char* peaklbl[];
};
#endif /* UT61E_H_ */

38
src/main.cpp Normal file
View file

@ -0,0 +1,38 @@
#include "UT61E.h"
#include "SerialPort.h"
#include <iostream>
#include <cstdlib>
void usage(void) {
std::cout << "Usage: dmmut61e <serialport>" << std::endl;
}
int main(int argc, char *argv[]) {
if (argc == 1) {
usage();
exit(0);
}
UT61E * dmm = new UT61E();
SerialPort * port = new SerialPort(argv[1]);
int res;
char buf[14];
while (true) {
res = read(port->fd, buf, 14);
if (dmm->check(buf) && res == 14) {
dmm->parse(buf);
if (!dmm->hold)
std::cout << dmm->sample << ";" << dmm->value << ";" << dmm->max << ";" << dmm->min << ";" << dmm->avarage << ";" << dmm->getMode() << ";" << dmm->getPower() << ";" << dmm->getRange() << std::endl;
} else {
std::cerr << "Invalid data!" << std::endl;
}
}
}