adc.read() returns a value between 0 and 4095 (12bits) ... the pyb module documentation shows a bytearray being used as a buffer for values from adc.read_timed ... but a bytearray is an array of 8 bit integers.
I am reading a TMP36 and (buf[0]<<4) + (buf[1]>>4) appears to give a value in the range expected by adc.read().
But, is this a valid way to interpret the data output by adc.read_timed? and is there a smarter pythonic way of constructing a buffer for adc.read_timed that will make the output easier to interpret?
adc.read_timed buffer problem ...
Re: adc.read_timed buffer problem ...
If you want to increase chance to get good answer and make this topic useful for other people, please consider adding links to docs you quote.
Anyway, looking at the source, adc.read_timed() will happily accept array.array of element size you want (like 'H'). If you pass bytearray, the resolution will be just reduced to 8 bits.
Anyway, looking at the source, adc.read_timed() will happily accept array.array of element size you want (like 'H'). If you pass bytearray, the resolution will be just reduced to 8 bits.
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Re: adc.read_timed buffer problem ...
Hi @pfalcon, thanks - the referenced documentation is at https://micropython.org/doc/module/pyb/ADC
I've tried what you suggest (using build pybv10-2014-06-29-v1.1.1-98-g8139494.dfu from https://micropython.org/download/) but pyb.read_timed doesn't like the array object, In my naivety I presume "because a Python array doesn't have a fixed length therefore timed_read won't know when to stop filling it" or thereabouts?
If I understand https://docs.python.org/3/library/stdty ... #binaryseq correctly native Python doesn't have a base type (supporting 'buffer protocol') that is appropriate for values read from the pyboard's ADC - perhaps one should be added to the pyb module to keep it separate from the base microPython implementation?
I've tried what you suggest (using build pybv10-2014-06-29-v1.1.1-98-g8139494.dfu from https://micropython.org/download/) but pyb.read_timed doesn't like the array object, In my naivety I presume "because a Python array doesn't have a fixed length therefore timed_read won't know when to stop filling it" or thereabouts?
Code: Select all
>>> import pyb, array
>>> adc=pyb.ADC(pyb.Pin.board.X5)
>>> buf=array.array('H')
>>> adc.read_timed(buf,10)
Traceback (most recent call last):
File "<stdin>", line 0, in <module>
TypeError: object with buffer protocol required
Re: adc.read_timed buffer problem ...
OK, reading further this https://docs.python.org/3/c-api/buffer. ... ferobjects seems to suggest that array.array should support the buffer protocol, therefore should work in this context, guess it just doesn't yet in microPython.
I'll just leave this and 'try again later', my 20 yr latent C 'skills' are absolutely not up to contributing a patch, before you suggest that I do
I'll just leave this and 'try again later', my 20 yr latent C 'skills' are absolutely not up to contributing a patch, before you suggest that I do
Re: adc.read_timed buffer problem ...
Ahhh ... prefilling an array seems to work, bingo?!
(X5 wasn't connected to anything)
Code: Select all
>>> import pyb,array
>>> adc=pyb.ADC(pyb.Pin.board.X5)
>>> buf=array.array('H')
>>> for i in range(10): buf.append(0)
...
>>> adc.read_timed(buf,10)
20
>>> buf
array('H', [3666, 3664, 3673, 3671, 3671, 3669, 3672, 3671, 3666, 3671])
>>>
Re: adc.read_timed buffer problem ...
Good research work.
More concise, but much less efficient way to create an zero-filled array of needed size is. Again, good for quick hacks, very inefficient on memory - it will first create a list of 1000 entries, then array from it.
I also was sure I implemented shortcut for creating empty array like (compare that with bytearray), but apparently I didn't. I went figuring out why CPython doesn't offer that, and got dragged into http://forum.micropython.org/viewtopic.php?f=3&t=59 . I guess, I will implement it after all - while they deal with that PEP, let us have efficient way to create buffers .
More concise, but much less efficient way to create an zero-filled array of needed size is
Code: Select all
array.array('H', [0] * 1000)
I also was sure I implemented shortcut for creating empty array like
Code: Select all
array.array('H', 1000)
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Re: adc.read_timed buffer problem ...
I guess a generator is a more microPythonic (aka efficient) way of doing it? i.e.
Which could theoretically be appended to the initialiser of a subclass of array.array I assume, excellent; an excuse to play with Python subclasses for the first time.
Code: Select all
>>> def fillbuf(l):
... for i in range(l): yield 0
...
>>> import array
>>> buf=array.array('H',fillbuf(10))
>>> buf
array('H', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])