]> sigrok.org Git - libsigrok.git/commitdiff
dmm/vc96: Fixed wrong detection and calculation.
authorschuma-gta02 <redacted>
Fri, 24 Nov 2023 15:56:25 +0000 (16:56 +0100)
committerSoeren Apel <redacted>
Sat, 8 Nov 2025 22:11:29 +0000 (23:11 +0100)
- 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

src/dmm/vc96.c

index 8e51097effcda8073ac5f97dbf789565a923a111..0abc4a00ade579224f6f70978d3ab74694252930 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the libsigrok project.
  *
  * Copyright (C) 2012-2013 Uwe Hermann <uwe@hermann-uwe.de>
- * Copyright (C) 2018 Matthias Schulz <matthschulz@arcor.de>
+ * Copyright (C) 2018 Matthias Schulz <matthias.schulz@mailbox.org>
  *
  * 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.
 #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;