]> sigrok.org Git - libsigrok.git/commitdiff
brymen-dmm: unbreak dBm reference impedance interpretation
authorGerhard Sittig <redacted>
Mon, 21 Sep 2020 19:08:27 +0000 (21:08 +0200)
committerGerhard Sittig <redacted>
Mon, 21 Sep 2020 19:37:06 +0000 (21:37 +0200)
The reference impedance for dBm measurements comes in an unexpected
format. Isolate the 4..1200 Ohms value, ignore the (inappropriate?)
"0." and exponent parts of the response. Clearly reflect that Ohms
values are seen in different contexts (dBm reference, continuity,
resistance).

Reword comments in the BM850 response parser's code path for dBm
measurements. The reference value is shown when the function is entered
(verified here) or when the reference value changes (haven't seen this
here but a comment in the previous implementation said so).

src/hardware/brymen-dmm/parser.c

index 40ca6c86074084cd6bf320627e1e725c70c6bf15..cc0a05c60c25dd44a0cfb8cca26415b93f22d89e 100644 (file)
@@ -223,6 +223,7 @@ SR_PRIV int brymen_parse(const uint8_t *buf, float *floatval,
        uint8_t *bfunc;
        const char *txt;
        int txtlen;
+       char *p;
        char *unit;
        int ret;
 
@@ -237,6 +238,22 @@ SR_PRIV int brymen_parse(const uint8_t *buf, float *floatval,
 
        memset(&flags, 0, sizeof(flags));
        parse_flags(bfunc, &flags);
+       if (flags.is_decibel && flags.is_ohm) {
+               /*
+                * The reference impedance for the dBm function is in an
+                * unexpected format. Naive conversion of non-space chars
+                * gives incorrect results. Isolate the 4..1200 Ohms value
+                * instead, ignore the "0." and exponent parts of the
+                * response text.
+                */
+               if (strncmp(txt, " 0.", strlen(" 0.")) == 0 && strstr(txt, " E")) {
+                       txt = &txt[strlen(" 0.")];
+                       txtlen -= strlen(" 0.");
+                       p = strchr(txt, 'E');
+                       if (p)
+                               *p = '\0';
+               }
+       }
        if (flags.is_fahrenheit || flags.is_celsius) {
                /*
                 * The value text in temperature mode includes the C/F
@@ -264,7 +281,9 @@ SR_PRIV int brymen_parse(const uint8_t *buf, float *floatval,
                analog->meaning->unit = SR_UNIT_AMPERE;
        }
        if (flags.is_ohm) {
-               if (flags.is_beep)
+               if (flags.is_decibel)
+                       analog->meaning->mq = SR_MQ_RESISTANCE;
+               else if (flags.is_beep)
                        analog->meaning->mq = SR_MQ_CONTINUITY;
                else
                        analog->meaning->mq = SR_MQ_RESISTANCE;
@@ -296,20 +315,25 @@ SR_PRIV int brymen_parse(const uint8_t *buf, float *floatval,
        }
 
        /*
-        * The high-end Brymen models have a configurable reference impedance.
-        * When the reference impedance is changed, the DMM sends one packet
-        * with the value of the new reference impedance. Both decibel and ohm
-        * flags are set in this case, so we must be careful to correctly
-        * identify the value as ohm, not dBmW.
+        * The high-end Brymen models have a configurable reference
+        * impedance for dBm measurements. When the meter's function
+        * is entered, or when the reference impedance is changed, the
+        * meter sends one packet with the value of the new reference.
+        * Both decibel and ohm flags are set in this case, so we must
+        * be careful to not clobber the resistance value from above,
+        * and only provide dBm when the measurement is shown and not
+        * its reference.
+        *
+        * The meter's response values also use an unexpected scale
+        * (always off by factor 1000, as if it was Watts not mW).
+        *
+        * Example responses:
+        * bfunc: 00 00 20 80, text ' 0. 800 E+1' (reference)
+        * bfunc: 00 00 20 00, text '-0.3702 E-1' (measurement)
         */
        if (flags.is_decibel && !flags.is_ohm) {
                analog->meaning->mq = SR_MQ_POWER;
                analog->meaning->unit = SR_UNIT_DECIBEL_MW;
-               /*
-                * For some reason, dBm measurements are sent by the multimeter
-                * with a value three orders of magnitude smaller than the
-                * displayed value.
-                */
                *floatval *= 1000;
        }