Page 1 of 1

[STM32F411] ADC.read resolution problem

Posted: Thu Apr 01, 2021 7:53 pm
by nesergen
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?

Re: [STM32F411] ADC.read resolution problem

Posted: Thu Apr 01, 2021 9:18 pm
by davef
Maybe show the code for adc.read_timed(buf, tim)

Re: [STM32F411] ADC.read resolution problem

Posted: Fri Apr 02, 2021 6:06 am
by nesergen
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: .

Re: [STM32F411] ADC.read resolution problem

Posted: Fri Apr 02, 2021 6:24 am
by davef
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.

Re: [STM32F411] ADC.read resolution problem

Posted: Fri Apr 02, 2021 6:26 am
by Roberthh
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.