metex14: Support DMMs with slightly different protocol.

This adds support for DMMs with 5 digits in the protocol (instead of 4)
and some more whitespace variants.
This commit is contained in:
Uwe Hermann 2013-10-20 14:45:20 +02:00
parent 71f1302b4b
commit 1a807c13fc
1 changed files with 18 additions and 58 deletions

View File

@ -45,72 +45,32 @@
static int parse_value(const uint8_t *buf, float *result) static int parse_value(const uint8_t *buf, float *result)
{ {
int i, sign, intval = 0, factor, decimal_point = 0, is_ol; int i, is_ol, cnt;
float floatval; char valstr[7 + 1];
uint8_t digit;
/* Byte 3: Sign (' ' or '-') */ /* Strip all spaces from bytes 2-8. */
if (buf[3] == ' ') { memset(&valstr, 0, 7 + 1);
sign = 1; for (i = 0, cnt = 0; i < 7; i++) {
} else if (buf[3] == '-') { if (buf[2 + i] != ' ')
sign = -1; valstr[cnt++] = buf[2 + i];
} else {
sr_err("Invalid sign byte: 0x%02x.", buf[3]);
return SR_ERR;
} }
/* Bytes 5-7: Over limit (various forms) */ /* Bytes 5-7: Over limit (various forms) */
is_ol = 0; is_ol = 0;
is_ol += (!strncmp((char *)&buf[5], ".OL", 3)) ? 1 : 0; is_ol += (!strcmp((const char *)&valstr, ".OL")) ? 1 : 0;
is_ol += (!strncmp((char *)&buf[5], "O.L", 3)) ? 1 : 0; is_ol += (!strcmp((const char *)&valstr, "O.L")) ? 1 : 0;
is_ol += (!strncmp((char *)&buf[5], "OL.", 3)) ? 1 : 0; is_ol += (!strcmp((const char *)&valstr, "OL.")) ? 1 : 0;
is_ol += (!strncmp((char *)&buf[5], " OL", 3)) ? 1 : 0; is_ol += (!strcmp((const char *)&valstr, "OL")) ? 1 : 0;
if (is_ol != 0) { if (is_ol != 0) {
sr_spew("Over limit."); sr_spew("Over limit.");
*result = INFINITY; *result = INFINITY;
return SR_OK; return SR_OK;
} }
/* Bytes 4-8: Value (up to 4 digits) and decimal point */ /* Bytes 2-8: Sign, value (up to 5 digits) and decimal point */
factor = 1000; sscanf((const char *)&valstr, "%f", result);
for (i = 0; i < 5; i++) {
digit = buf[4 + i];
/* Convert spaces to '0', so that we can parse them. */
if (digit == ' ')
digit = '0';
if (digit == '.') {
decimal_point = i;
} else if (isdigit(digit)) {
intval += (digit - '0') * factor;
factor /= 10;
} else {
sr_err("Invalid digit byte: 0x%02x.", digit);
return SR_ERR;
}
}
floatval = (float)intval; sr_spew("The display value is %f.", *result);
/* Decimal point position */
if (decimal_point == 0 || decimal_point == 4) {
/* TODO: Doesn't happen? */
} else if (decimal_point == 1) {
floatval /= 1000;
} else if (decimal_point == 2) {
floatval /= 100;
} else if (decimal_point == 3) {
floatval /= 10;
} else {
sr_err("Invalid decimal point position: %d.", decimal_point);
return SR_ERR;
}
/* Apply sign. */
floatval *= sign;
sr_spew("The display value is %f.", floatval);
*result = floatval;
return SR_OK; return SR_OK;
} }
@ -141,16 +101,16 @@ static void parse_flags(const char *buf, struct metex14_info *info)
if (info->is_dc || info->is_ac) if (info->is_dc || info->is_ac)
info->is_volt = TRUE; info->is_volt = TRUE;
/* Byte 2: Always space (0x20). */ /* Bytes 2-8: See parse_value(). */
/* Bytes 3-8: See parse_value(). */ /* Strip all spaces from bytes 9-12. */
/* Bytes 9-12: Unit */
memset(&unit, 0, 4 + 1); memset(&unit, 0, 4 + 1);
for (i = 0, cnt = 0; i < 4; i++) { for (i = 0, cnt = 0; i < 4; i++) {
if (buf[9 + i] != ' ') if (buf[9 + i] != ' ')
unit[cnt++] = buf[9 + i]; unit[cnt++] = buf[9 + i];
} }
/* Bytes 9-12: Unit */
u = (const char *)&unit; u = (const char *)&unit;
if (!strcmp(u, "A")) if (!strcmp(u, "A"))
info->is_ampere = TRUE; info->is_ampere = TRUE;