Micropython POT class for quick and simple potentiometer interfacing

This post is for all who need to get a POT hooked up (one that provides analogue values) to their micropython project as quickly as possible. Probably you’ve seen my other post about how to read analogue values with the raspberry pi pico and thought: ‘My god, so much words for just reading POT values’. Well, I agree, that one probably is only for the readers who exactly want to know what’s happening.

Here in this one I just want to share my simple micropython POT class that will provide three basic functions to you and your project. I’ve made many comments in the code, so it should be pretty much self-explanatory. But wait! Before you copy the code and leave this site forever – you can find some examples beneath which you may find helpful. Also feel free to leave a comment!

The micropython POT class

Here you go, enjoy!

# made by coffeebreakpoint.com
import machine
import math

U16_MAX = math.pow(2,16)-1 # maximum value unsigned 'short' = 2^16-1

class POT:
    """
    A class used to interface with a POT that provides analogue values.

    Attributes
    ----------
    pin : int
        the ADC pin that the POT is connected to
    cm : dict
        used for a special method of the class, see documentation of cval()
        for more information. Keys should represent percentage-marks and thus
        need to be in range from 0.0 to 1.0

    Methods
    -------
    val()
        Returns the direct 'unsigned short' value on the ADC-Pin (see pin attribute)
    pct(precision = None):
        Returns the percentage of the current value on the ADC-Pin compared to the
        Max-value. The optional parameter can be used to directly round
        the result to the provided precision.
    cval()
        Returns the value of cm that is nearest to the current state (percentage-wise)
        on the ADC-Pin.
    """
    
    def __init__(self, ADC, clamping_map = None):
        self.pin = machine.ADC(ADC)
        
        if clamping_map != None:
            if not isinstance(clamping_map, dict):
                raise ValueError("Please provide a dictionary for the 'clamping_map' parameter")
            
            for k,v in clamping_map.items():
                if not isinstance(k,float) or k < 0.0 or k > 1.0:
                    raise ValueError("Please use Values between 0.0 and 1.0 for the 'clamping_map' dictionary keys")
        
            self.cm = clamping_map
    
    # direct value from the ADC-Pin as an 'unsigned short' 
    def val(self):
        return self.pin.read_u16()
    
    # value in percent (MIN:0V = 0.0; MAX:'VCC' = 1.0)
    def pct(self, precision = None):
        pct_val = self.pin.read_u16()/U16_MAX
        
        return pct_val if precision == None else round(pct_val,precision)
    
    # nearest value of cm
    def cval(self):
        if self.cm == None:
            return ""
        
        pct_val = self.pct()
        key = min (self.cm, key = lambda x:abs(x-pct_val))
        return str(self.cm[key])

Tip: You can also use this code for devices other than simple POTs if you find it fitting.

Example 1: POT percentage

The following example showcases how to use the pct() function of the class. This code is specific to the raspberry pi pico and uses its integrated LED. Feel free to change and test with your specific board.

import machine
import utime
import pot

led_pin = machine.Pin(25,machine.Pin.OUT) # internal LED of the Pico
pot = pot.POT(28)

while True:
    led_pin.toggle()
    
    # get percentage of the current POT value as rounded
    # float with precision of 3 decimal places.
    pot_pct = pot.pct(3)
    
    # set frequency with max. 1/100 second and min. 1 second
    # also avoid division through 0
    utime.sleep(1 if pot_pct == 0 else 1/(pot_pct*100))

Example 2: POT custom state query

Another example that shows how to use the state mechanism of the POT class. If you need to trigger specific functions in ‘value regions’ of the POT input, then probably the function cval() may be of help to you.

import machine
import utime
import pot

led_pin = machine.Pin(25,machine.Pin.OUT) # internal LED of the Pico
state_map = {0.0:"OFF", 0.3:"BLINK", 0.5:"BLINK", 0.8:"POWER!!"}
pot = pot.POT(28, state_map)

while True:
    
    current_state = pot.cval()
    # if the percentage of the current ADC-Input of the POT is closest
    # to 0.0 then pot.cval will return the state "OFF"
    if current_state == "OFF":
        led_pin.value(0)
    
    # same with "BLINK"...
    elif current_state == "BLINK":
        led_pin.toggle()
        pot_pct = pot.pct(3)
        utime.sleep(1 if pot_pct == 0 else 1/(pot_pct*100))
        
    # ..and "POWER!!"
    elif current_state == "POWER!!":
        led_pin.value(1)

1 thought on “Micropython POT class for quick and simple potentiometer interfacing”

  1. Pingback: Want to move something? Here's how to use a Micro Servo with Micropython (Including easy code) - Coffeebreakpoint

Leave a Comment

Your email address will not be published. Required fields are marked *