initial import
This commit is contained in:
commit
79f4719040
17 changed files with 1041 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
.settings
|
||||
.cproject
|
||||
.project
|
||||
.classpath
|
||||
|
BIN
DSC00102.JPG
Normal file
BIN
DSC00102.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 384 KiB |
51
README
Normal file
51
README
Normal 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
42
SerialPort.cpp
Normal 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
272
UT61E.cpp
Normal 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
44
UT61E.h
Normal 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
112
UT61E.txt
Normal 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
BIN
bin/dmmut61e
Executable file
Binary file not shown.
58
bin/graph
Executable file
58
bin/graph
Executable 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
BIN
dmmut61e-0.01.tar.gz
Normal file
Binary file not shown.
38
main.cpp
Normal file
38
main.cpp
Normal 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
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
42
src/SerialPort.cpp
Normal file
42
src/SerialPort.cpp
Normal 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
23
src/SerialPort.h
Normal 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
272
src/UT61E.cpp
Normal 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
44
src/UT61E.h
Normal 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
38
src/main.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue