Calculate percent value

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
soggycashew
Posts: 55
Joined: Sat Sep 18, 2021 10:21 pm

Calculate percent value

Post by soggycashew » Wed Dec 29, 2021 12:51 am

Hello, I have a Capacitive Soil Moisture Sensor and I want to give a percent value of a min and max value from adc0. The code below gives be an error that is from the print line. What am I doing wrong? Thanks!
Error:
TypeError: unsupported types for __sub__: 'ADC', 'int'

Code: Select all

from machine import ADC
import utime

#Capacitive Soil Moisture Sensor
adc0 = machine.ADC(machine.Pin(26))

wet = 60000
dry = 24854

def scale_value(value, in_min, out_max, out_min):
  scaled_value = ((value - in_min) * 100) / (out_max - out_min)
  return scaled_value

while True:
        
    print(scale_value(adc0, dry, wet, dry))
    utime.sleep(0.5)

hlovatt
Posts: 68
Joined: Thu Aug 15, 2019 3:52 am
Location: Sydney

Re: Calculate percent value

Post by hlovatt » Wed Dec 29, 2021 2:58 am

I think you need `adc0.read()` when you call `scale_value`, not just `adc0`. The error message looks like it is expecting an `int`, but you are giving it an `ADC`.

soggycashew
Posts: 55
Joined: Sat Sep 18, 2021 10:21 pm

Re: Calculate percent value

Post by soggycashew » Wed Dec 29, 2021 3:11 am

Thank you.. the below #2 worked but its giving a decimal like 89.29324. How do I round that? would the below #1 be correct and can I add it to the scaled_value instead to avoid it in my print?

1) print(str(round(scale_value(adc0.read_u16(), dry, wet, dry))))

2) print(scale_value(adc0.read_u16(), dry, wet, dry))

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: Calculate percent value

Post by davef » Wed Dec 29, 2021 3:24 am

Rounding sometimes gives you more "significant" digits than the stated rounding parameter.

I have found that string formatting:

Code: Select all

 HWT_temp = "{:.1f}".format(HWT_temp)
battery_26V = "{:.2f}".format(battery_26V)
at least controls the number of displayed digits, if not any supposed benefit from rounding up or down.

bulletmark
Posts: 59
Joined: Mon Mar 29, 2021 1:36 am
Location: Brisbane Australia

Re: Calculate percent value

Post by bulletmark » Wed Dec 29, 2021 7:21 am

Modern way is to prefer f-strings over .format():

Code: Select all

print(f"{HWT_temp:.1f}")
print(f"{battery_26v:.2f}")

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: Calculate percent value

Post by davef » Wed Dec 29, 2021 8:29 am

About a month ago I "discovered" .format after the rounding issue raised its ugly-head. I read through RealPython's string formatting tutorial ending with this:
https://realpython.com/python-string-fo ... ld-you-use and perhaps decided for the wrong reason that .format applied to me.
Python String Formatting Rule of Thumb: If your format strings are user-supplied, use Template Strings (#4) to avoid security issues. Otherwise, use Literal String Interpolation/f-Strings (#3) if you’re on Python 3.6+, and “New Style” str.format (#2) if you’re not.
Are strings that I want to format in my code not user-supplied? The word "security" suggests that these strings are coming from the outside world. What does user-supplied mean?

bulletmark
Posts: 59
Joined: Mon Mar 29, 2021 1:36 am
Location: Brisbane Australia

Re: Calculate percent value

Post by bulletmark » Wed Dec 29, 2021 9:48 am

davef wrote:
Wed Dec 29, 2021 8:29 am
What does user-supplied mean?
It means externally entered by a user of your program. E.g, you may have an app which uses a web page to accept text input from your users. The app should check the raw text field (e,.g limit the length, limit the range of chars input, etc) before using that string.

You potentially can't trust all external users, but you can trust yourself when writing your own code! So this concern does not apply here.

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: Calculate percent value

Post by davef » Wed Dec 29, 2021 7:03 pm

Thank you. Looks like my next learning opportunity!

nekomatic
Posts: 37
Joined: Thu May 08, 2014 9:31 pm

Re: Calculate percent value

Post by nekomatic » Wed Jan 05, 2022 5:01 pm

davef wrote:
Wed Dec 29, 2021 3:24 am
Rounding sometimes gives you more "significant" digits than the stated rounding parameter.
Python's round calculates the result of rounding the input to the specified number of decimal places, not significant figures.

If you want to round to significant figures there are several methods suggested here, although not all will work in MicroPython.

Or did I misunderstand you and you find round misbehaves in some other way? Can you give an example?

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: Calculate percent value

Post by davef » Wed Jan 05, 2022 6:52 pm

Maybe I should have said "decimal" places. Especially with 1-wire measurements and using round 1 on the returned floating point number, I would often get:
66.4
66.30001
66.2

Post Reply