[STM32F411] ADC.read resolution problem

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
Post Reply
nesergen
Posts: 23
Joined: Mon Oct 26, 2020 9:17 pm

[STM32F411] ADC.read resolution problem

Post by nesergen » Thu Apr 01, 2021 7:53 pm

Good day!
I am trying to read an analog signal. I do it in two ways and they give different results.
Using the ADC.read () function, I get the result with a resolution of 12 bits without any problems.

Code: Select all

pin = pyb.Pin(pyb.Pin.board.PA4, pyb.Pin.ANALOG)
adc = pyb.ADC(pin) # пин датчик ванны
ls = []
def printer(x):
	val = adc.read()
	RealVolt = (val * 3.3) / 4096.0
	if len(ls)<20:
		ls.append(RealVolt)
	else:
		ls.pop(0)
		ls.append(RealVolt)
	print(val, RealVolt, min(ls),max(ls), "delta=",max(ls)-min(ls))


machine.Timer(mode=machine.Timer.PERIODIC,period = 100, callback = printer)
But if I use the ADC.read_timed (buf.tim) function, then the result is saved to a buffer with a resolution of 8 bits.

Code: Select all

pin = pyb.Pin(pyb.Pin.board.PA4, pyb.Pin.ANALOG)
adc = pyb.ADC(pin) # пин датчик ванны
ls = []


def myMultiplyFunction ():
#""" расчет значения напряжения датчика .
#Делитель напряжения с входным напряжением 26В и выходным напряжения до 3.33 В """
	R1 = 68000.0
	R2 = 10000.0


	tim = pyb.Timer(4, freq=10)         # create a timer running at 10Hz
	buf = bytearray(10)                # creat a buffer to store the samples
	adc.read_timed(buf, tim)            # sample 100 values, taking 10s
	print("buf ", list(buf))
	
	test_average = sum(list(buf)) / len(list(buf))
	
	print("test_average ",test_average)
	arduino_IN = (test_average * 3.3) / 256.0
	voltage = arduino_IN / (R2/(R1+R2))
	print("voltage",voltage)
	return voltage

machine.Timer(mode=machine.Timer.PERIODIC,period = 100, callback = myMultiplyFunction() )
I can't understand why this is happening?

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

Re: [STM32F411] ADC.read resolution problem

Post by davef » Thu Apr 01, 2021 9:18 pm

Maybe show the code for adc.read_timed(buf, tim)

nesergen
Posts: 23
Joined: Mon Oct 26, 2020 9:17 pm

Re: [STM32F411] ADC.read resolution problem

Post by nesergen » Fri Apr 02, 2021 6:06 am

In the previous post, I showed a complete working program. read_timed () is a function built into MicroPython.
https://docs.micropython.org/en/latest/ ... read_timed
I initiate it as follows:

Code: Select all

pin = pyb.Pin(pyb.Pin.board.PA4, pyb.Pin.ANALOG)
adc = pyb.ADC(pin)
Then I read several values from the pin into the buffer using the timer built into the board:

Code: Select all

tim = pyb.Timer(4, freq=10)         # create a timer running at 10Hz
buf = bytearray(10)                # creat a buffer to store the samples
adc.read_timed(buf, tim)            # sample 10 values, taking 1s
No magic, I did everything according to the instructions on the site https://docs.micropython.org/ .
Although I could be wrong somewhere :roll: .

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

Re: [STM32F411] ADC.read resolution problem

Post by davef » Fri Apr 02, 2021 6:24 am

Had a look at the link you provided:
If buf has only 8-bit elements (eg a bytearray) then the sample resolution will be reduced to 8 bits.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: [STM32F411] ADC.read resolution problem

Post by Roberthh » Fri Apr 02, 2021 6:26 am

You read the data into a bytearray, which is, as the name tells, an array of 8 bit quantities. If you want to get 12 bit resolution, you have to use an array type for the buffer. See also the documentation of read_timed.
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.

Post Reply