From: schuma-gta02 Date: Fri, 24 Nov 2023 15:56:25 +0000 (+0100) Subject: dmm/vc96: Fixed wrong detection and calculation. X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=54903a8640ccd05dc1b9d99b8fd9f66a29a2e098;p=libsigrok.git dmm/vc96: Fixed wrong detection and calculation. - check against " " (two spaces) for info->is_unitless (line 137) - introduced the handling of the returncode of sr_atof_ascii (line 73) - explanation for ignoring case in line 132 added --- diff --git a/src/dmm/vc96.c b/src/dmm/vc96.c index 8e51097e..0abc4a00 100644 --- a/src/dmm/vc96.c +++ b/src/dmm/vc96.c @@ -2,7 +2,7 @@ * This file is part of the libsigrok project. * * Copyright (C) 2012-2013 Uwe Hermann - * Copyright (C) 2018 Matthias Schulz + * Copyright (C) 2018 Matthias Schulz * * 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 @@ -20,6 +20,7 @@ /* * Voltcraft 13-bytes ASCII protocol parser. + * derived from metex14.c * * Bytes 1-3 measuring mode, byte 4 '-' for negative, * bytes 5-9 value, bytes 10-11 unit, bytes 12-13 CRLF 0d 0a. @@ -37,20 +38,21 @@ #define LOG_PREFIX "vc96" /** Parse value from buf, byte 3-8. */ -static int parse_value(const uint8_t *buf, struct vc96_info *info, +static int parse_value(const uint8_t *buf, float *result, int *exponent) { - int i, is_ol, cnt, dot_pos; - char valstr[8 + 1]; - - (void)info; + int i, is_ol, cnt, dot_pos, ret; + ret = SR_ERR; // to be overwritten with SR_OK + char valstr[6 + 1]; + sr_spew("parse_value buf still with spaces \"%.12s\".", buf); /* Strip all spaces from bytes 3-8. */ memset(&valstr, 0, 6 + 1); for (i = 0, cnt = 0; i < 6; i++) { if (buf[3 + i] != ' ') valstr[cnt++] = buf[3 + i]; } + sr_spew("parse_value valstr without spaces \"%.7s\".", valstr); /* Bytes 5-7: Over limit (various forms) */ is_ol = 0; @@ -63,25 +65,26 @@ static int parse_value(const uint8_t *buf, struct vc96_info *info, is_ol += (!g_ascii_strcasecmp((const char *)&valstr, "-OL.")) ? 1 : 0; is_ol += (!g_ascii_strcasecmp((const char *)&valstr, "-OL")) ? 1 : 0; if (is_ol != 0) { - sr_spew("Over limit."); *result = INFINITY; - return SR_OK; - } - - /* Bytes 3-10: Sign, value (up to 5 digits) and decimal point */ - sr_atof_ascii((const char *)&valstr, result); - - dot_pos = strcspn(valstr, "."); - if (dot_pos < cnt) - *exponent = -(cnt - dot_pos - 1); - else - *exponent = 0; - - sr_spew("The display value is %f.", *result); - - return SR_OK; + sr_spew("parse_value Over limit."); + ret = SR_OK; + }else{ + /* Bytes 3-10: Sign, value (up to 5 digits including decimal point) */ + if ((ret = sr_atof_ascii((const char *)&valstr, result)) != SR_OK) + sr_dbg("parse_value Error sr_atof_ascii: %d.", ret); + sr_spew("parse_value value %f.", *result); + + dot_pos = strcspn(valstr, "."); + if (dot_pos < cnt) + *exponent = -(cnt - dot_pos - 1); + else + *exponent = 0; + sr_spew("parse_value Exponent %i", *exponent); + }; + return ret; } + static void parse_flags(const char *buf, struct vc96_info *info) { int i, cnt; @@ -92,54 +95,47 @@ static void parse_flags(const char *buf, struct vc96_info *info) info->is_ac = !strncmp(buf, "AC", 2); info->is_dc = !strncmp(buf, "DC", 2); - /* Bytes 0-2: Measurement mode DIO, OHM */ - info->is_ohm = !strncmp(buf, "OHM", 3); + /* + * Note: + * - Protocol doesn't distinguish "resistance" from "beep" mode. + */ + /* Bytes 0-2: Measurement mode, except AC/DC */ + info->is_ohm = !strncmp(buf, "OHM", 3) || !strncmp(buf, "BEP", 3); info->is_diode = !strncmp(buf, "DIO", 3); info->is_hfe = !strncmp(buf, "hfe", 3); /* Bytes 3-8: See parse_value(). */ + sr_spew("parse_flags buf still with spaces \"%.12s\".", buf); /* Strip all spaces from bytes 9-10. */ memset(&unit, 0, 2 + 1); for (i = 0, cnt = 0; i < 2; i++) { if (buf[9 + i] != ' ') unit[cnt++] = buf[9 + i]; } - sr_spew("Bytes 9..10 without spaces \"%.4s\".", unit); + sr_spew("parse_flags Bytes 9..10 (unit) without spaces \"%.4s\".", unit); /* Bytes 9-10: Unit */ u = (const char *)&unit; - if (!g_ascii_strcasecmp(u, "A")) - info->is_ampere = TRUE; - else if (!g_ascii_strcasecmp(u, "mA")) + + if (!g_ascii_strcasecmp(u, "mA")) info->is_milli = info->is_ampere = TRUE; else if (!g_ascii_strcasecmp(u, "uA")) info->is_micro = info->is_ampere = TRUE; - else if (!g_ascii_strcasecmp(u, "V")) - info->is_volt = TRUE; + else if (!g_ascii_strcasecmp(u, "A")) + info->is_ampere = TRUE; else if (!g_ascii_strcasecmp(u, "mV")) info->is_milli = info->is_volt = TRUE; - else if (!g_ascii_strcasecmp(u, "K")) + else if (!g_ascii_strcasecmp(u, "V")) + info->is_volt = TRUE; + /* VC96 sends wrong upper case "K", ignore case, for devices maybe doing this correct */ + else if (!g_ascii_strncasecmp(u, "K", 1)) info->is_kilo = TRUE; - else if (!g_ascii_strcasecmp(u, "M")) + else if (strchr(u, (int)'M')) info->is_mega = TRUE; - else if (!g_ascii_strcasecmp(u, "")) + else if (!g_ascii_strcasecmp(u, " ")) info->is_unitless = TRUE; - /* Bytes 0-2: Measurement mode, except AC/DC */ - info->is_resistance = !strncmp(buf, "OHM", 3) || - (!strncmp(buf, " ", 3) && info->is_ohm); - info->is_diode = !strncmp(buf, "DIO", 3) || - (!strncmp(buf, " ", 3) && info->is_volt && info->is_milli); - info->is_hfe = !strncmp(buf, "hfe", 3) || - (!strncmp(buf, " ", 3) && !info->is_ampere && !info->is_volt && - !info->is_resistance && !info->is_diode); - - /* - * Note: - * - Protocol doesn't distinguish "resistance" from "beep" mode. - */ - /* Byte 12: Always '\r' (carriage return, 0x0d, 12) */ /* Byte 13: Always '\n' (carriage return, 0x0a, 13) */ } @@ -151,7 +147,7 @@ static void handle_flags(struct sr_datafeed_analog *analog, float *floatval, (void)exponent; - /* Factors */ + /* Factors representing the exponent of 123Exx */ factor = 0; if (info->is_micro) factor -= 6; @@ -161,7 +157,9 @@ static void handle_flags(struct sr_datafeed_analog *analog, float *floatval, factor += 3; if (info->is_mega) factor += 6; + *floatval *= powf(10, factor); + *exponent += factor; /* Measurement modes */ if (info->is_volt) { @@ -273,7 +271,7 @@ SR_PRIV int sr_vc96_parse(const uint8_t *buf, float *floatval, memset(info_local, 0x00, sizeof(struct vc96_info)); - if ((ret = parse_value(buf, info_local, floatval, &exponent)) < 0) { + if ((ret = parse_value(buf, floatval, &exponent)) != SR_OK) { sr_dbg("Error parsing value: %d.", ret); return ret; } @@ -281,6 +279,7 @@ SR_PRIV int sr_vc96_parse(const uint8_t *buf, float *floatval, parse_flags((const char *)buf, info_local); handle_flags(analog, floatval, &exponent, info_local); + sr_spew("sr_vc96_parse Exponent %i", exponent); analog->encoding->digits = -exponent; analog->spec->spec_digits = -exponent;