From dd46a48cd1526582b32cb331f70b5af6041270b7 Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Fri, 8 Sep 2023 16:02:53 +0200 Subject: [PATCH] Improved conversion law in MD-3x0 and MD-UV3x0 platform_getVolumeLevel(). Rewritten the conversion law from ADC measurement in mV and normalized 0-255 output, adding a linearization if the pseudo-logarithmic output curve of the potentiometer. Signed-off-by: Silvano Seva --- platform/targets/MD-3x0/platform.c | 31 +++++++++++++++++++------ platform/targets/MD-UV3x0/platform.c | 34 ++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/platform/targets/MD-3x0/platform.c b/platform/targets/MD-3x0/platform.c index 0f555aa6..f5396225 100644 --- a/platform/targets/MD-3x0/platform.c +++ b/platform/targets/MD-3x0/platform.c @@ -100,15 +100,32 @@ uint8_t platform_getMicLevel() uint8_t platform_getVolumeLevel() { /* - * Knob position corresponds to an analog signal in the range 0 - 1600mV, - * converted to a value in range 0 - 255 using fixed point math: divide by - * 1600 and then multiply by 256. + * Volume level corresponds to an analog signal in the range 0 - 1650mV. + * Potentiometer has pseudo-logarithmic law, well described with two straight + * lines with a breakpoint around 270mV. + * Output value has range 0 - 255 with breakpoint at 150. */ uint16_t value = adc1_getMeasurement(ADC_VOL_CH); - if(value > 1599) value = 1599; - uint32_t level = value << 16; - level /= 1600; - return ((uint8_t) (level >> 8)); + uint32_t output; + + if(value <= 270) + { + // First line: offset zero, slope 0.556 + output = value; + output = (output * 556) / 1000; + } + else + { + // Second line: offset 270, slope 0.076 + output = value - 270; + output = (output * 76) / 1000; + output += 150; + } + + if(output > 255) + output = 255; + + return output; } int8_t platform_getChSelector() diff --git a/platform/targets/MD-UV3x0/platform.c b/platform/targets/MD-UV3x0/platform.c index a6bf227d..9348e231 100644 --- a/platform/targets/MD-UV3x0/platform.c +++ b/platform/targets/MD-UV3x0/platform.c @@ -104,15 +104,35 @@ uint8_t platform_getMicLevel() uint8_t platform_getVolumeLevel() { /* - * Knob position corresponds to an analog signal in the range 0 - 1600mV, - * converted to a value in range 0 - 255 using fixed point math: divide by - * 1600 and then multiply by 256. + * Volume level corresponds to an analog signal in the range 20 - 1650mV. + * Potentiometer has pseudo-logarithmic law, well described with two straight + * lines with a breakpoint around 270mV. + * Output value has range 0 - 255 with breakpoint at 150. */ uint16_t value = adc1_getMeasurement(ADC_VOL_CH); - if(value > 1599) value = 1599; - uint32_t level = value << 16; - level /= 1600; - return ((uint8_t) (level >> 8)); + uint32_t output; + + if(value < 20) + return 0; + + if(value <= 270) + { + // First line: offset zero, slope 0.556 + output = value; + output = (output * 556) / 1000; + } + else + { + // Second line: offset 270, slope 0.076 + output = value - 270; + output = (output * 76) / 1000; + output += 150; + } + + if(output > 255) + output = 255; + + return output; } bool platform_getPttStatus()