class ADC – analog to digital conversion


import pyb

adc = pyb.ADC(pin)                  # create an analog object from a pin
val =                    # read an analog value

adc = pyb.ADCAll(resolution)        # create an ADCAll object
adc = pyb.ADCAll(resolution, mask)  # create an ADCAll object for selected analog channels
val = adc.read_channel(channel)     # read the given channel
val = adc.read_core_temp()          # read MCU temperature
val = adc.read_core_vbat()          # read MCU VBAT
val = adc.read_core_vref()          # read MCU VREF
val = adc.read_vref()               # read MCU supply voltage


class pyb.ADC(pin)

Create an ADC object associated with the given pin. This allows you to then read analog values on that pin.


Read the value on the analog pin and return it. The returned value will be between 0 and 4095.

ADC.read_timed(buf, timer)

Read analog values into buf at a rate set by the timer object.

buf can be bytearray or array.array for example. The ADC values have 12-bit resolution and are stored directly into buf if its element size is 16 bits or greater. If buf has only 8-bit elements (eg a bytearray) then the sample resolution will be reduced to 8 bits.

timer should be a Timer object, and a sample is read each time the timer triggers. The timer must already be initialised and running at the desired sampling frequency.

To support previous behaviour of this function, timer can also be an integer which specifies the frequency (in Hz) to sample at. In this case Timer(6) will be automatically configured to run at the given frequency.

Example using a Timer object (preferred way):

adc = pyb.ADC(pyb.Pin("P5"))        # create an ADC on pin P5
tim = pyb.Timer(6, freq=10)         # create a timer running at 10Hz
buf = bytearray(100)                # creat a buffer to store the samples
adc.read_timed(buf, tim)            # sample 100 values, taking 10s

Example using an integer for the frequency:

adc = pyb.ADC(pyb.Pin("P5"))        # create an ADC on pin P5
buf = bytearray(100)                # create a buffer of 100 bytes
adc.read_timed(buf, 10)             # read analog values into buf at 10Hz
                                    #   this will take 10 seconds to finish
for val in buf:                     # loop over all values
    print(val)                      # print the value out

This function does not allocate any heap memory. It has blocking behaviour: it does not return to the calling program until the buffer is full.

The ADCAll Object

Instantiating this changes all masked ADC pins to analog inputs. The preprocessed MCU temperature, VREF and VBAT data can be accessed on ADC channels 16, 17 and 18 respectively. Appropriate scaling is handled according to reference voltage used (usually 3.3V). The temperature sensor on the chip is factory calibrated and allows to read the die temperature to +/- 1 degree centigrade. Although this sounds pretty accurate, don’t forget that the MCU’s internal temperature is measured. Depending on processing loads and I/O subsystems active the die temperature may easily be tens of degrees above ambient temperature. On the other hand a pyboard woken up after a long standby period will show correct ambient temperature within limits mentioned above.

The ADCAll read_core_vbat(), read_vref() and read_core_vref() methods read the backup battery voltage, reference voltage and the (1.21V nominal) reference voltage using the actual supply as a reference. All results are floating point numbers giving direct voltage values.

read_core_vbat() returns the voltage of the backup battery. This voltage is also adjusted according to the actual supply voltage. To avoid analog input overload the battery voltage is measured via a voltage divider and scaled according to the divider value. To prevent excessive loads to the backup battery, the voltage divider is only active during ADC conversion.

read_vref() is evaluated by measuring the internal voltage reference and backscale it using factory calibration value of the internal voltage reference. In most cases the reading would be close to 3.3V. If the pyboard is operated from a battery, the supply voltage may drop to values below 3.3V. The pyboard will still operate fine as long as the operating conditions are met. With proper settings of MCU clock, flash access speed and programming mode it is possible to run the pyboard down to 2 V and still get useful ADC conversion.

It is very important to make sure analog input voltages never exceed actual supply voltage.

Other analog input channels (0..15) will return unscaled integer values according to the selected precision.

To avoid unwanted activation of analog inputs (channel 0..15) a second parameter can be specified. This parameter is a binary pattern where each requested analog input has the corresponding bit set. The default value is 0xffffffff which means all analog inputs are active. If just the internal channels (16..18) are required, the mask value should be 0x70000.


adcall = pyb.ADCAll(12, 0x70000) # 12 bit resolution, internal channels
temp = adcall.read_core_temp()