#include "dmm.h"
#include <string.h>
/* This plugin assumes following presets:
* Communication 9600 baud, no parity, 1 stopbit, no echo
* Trigger mode: auto or some external trigger > 0,3 Hz
* No decibel mode, no minmax mode
* The plugin cannot distinct between Continuity Test
* vs. Diode Test from Ohmmeter vs. Voltage meter
* Some combinations of readouts don't work,
* for currently unknown reason.
*/
EXTERN_C void _cdecl _fltused(){};
struct Fluke_8808A:INDATA{
void _stdcall Handler();
};
static char getunit(char c) {
switch (c) {
case 'V': return 1; // VAC, VDC, VACDC
case 'A': return 5; // AAC, ADC, AACDC
case 'O': return 2; // OHMS
case 'H': return 4; // HZ
default: return 0; // unknown code
}
}
void Fluke_8808A::Handler() {
switch (msg) {
case init:{
rmax=64;
counts=199999;
// baud=9600; // currently, default baudrate cannot be changed,
}break; // sorry for high-speed (100 Sa/s) data acquisition
case open:{
SendBytes("FORMAT 2\rVAL?\r",14); // set verbose format (including unit) and query current display value
}break;
case data:{
if (rlen<4) {ok=true; return;}
char*p=(char*)rbuf;
char*k=(char*)memchr(p,'\r',rlen); // get end of string
if (!k) {ok=true; return;} // not enough characters received
*k=0;
READOUT ro[4]; // Accept up to 4 readouts
ZeroMemory(ro,sizeof ro);
DWORD flags=0;
int i;
for (i=0; k && i<elemof(ro); p=k+1,i++) {
k=strchr(p,','); // further value available?
char *s;
ro[i].value=strtod(p,&s);
size_t l=s-p;
while (*s==' ') s++;
if (ro[i].unitcode=getunit(*s)) { // Have valid unit?
for(;;) { // Scan for AC/DC suffixes
switch (*++s) {
case 'A': flags|=1<<F_AC; break;
case 'D': flags|=1<<F_DC; break;
default: goto breakloop;
}
++s; // skip 'C' character
}
breakloop:
// Convert exponent value to unit prefix
char*e=(char*)memchr(p,'E',l);
if (e) {
int ex=atoi(e+1); // get exponent value (always multiple of 3?)
if (!(ex%3)) { // don't generate prefix if suddenly not multiple of 3
ro[i].unitprefix=ex; // set exponent (possibly 0)
l=e-p; // shorter digit string length
}
}
// TODO: Other flags require extra processing:
// F_AUTO: Querying "AUTO?"
// F_MIN, F_MAX, F_DIODE, F_CONT: how??
// Decibel ??
}
if (l>sizeof ro[i].digits-1) l=sizeof ro[i].digits-1;
memcpy(ro[i].digits,p,l); // copy digit string (with or without exponent)
ro[i].digits[l]=0;
}
SetData(flags,ro,i);
rlen=0; // reset buffer
ok=true;
}goto meas; // send next MEAS command which will return data after next trigger
case tout:{ // after timeout (for some reason) repeat MEAS command
meas:
SendBytes("MEAS?\r",6);
}break;
}
}
EXTERN_C bool /*_declspec(dllexport)*/ WINAPI EnumAll(int n, ENUMINFO* ei) {
if (n) return false;
strcpy(ei->ManufName,"Fluke");
strcpy(ei->ModelName,"8808A");
ei->IconIndex=2; // desktop multimeter
ei->ExtraAlloc=0;
ei->pHandler=(void(_stdcall INDATA::*)())&Fluke_8808A::Handler;
ei->lParam=0;
return true;
}
Detected encoding: UTF-8 | 0
|