sensorium/Mozzi

mozziAnalogRead doesn't work on SAMD21 boards

infovore opened this issue · 2 comments

See title.

Not hugely surprising, looking at mozzi_analog.cpp - we don't quite have a special case to handle it, and I think we do. Right now I'm not sure what the right answer is.

https://www.avdweb.nl/arduino/adc-dac/fast-10-bit-adc might be a useful point of reference for implementation. Does anybody else have recommendations of where to start looking into an implementation? I'm not necessarily asking somebody else to do this, but I'm not the world's best cpp programmer. For now, reporting it for now, and will continue to investigate (and use alternative AnalogRead methods in the menatime).

That would certainly help some. The analog read implementation in Mozzi goes one step further, however (on those platforms where it exists): Working on the assumption that you're not going to need the values once, but repeatedly (probably in updateControl()), the readings are actually done asynchronously:

  1. The first call to mozziAnalogRead(pinX) simply returns a dummy, however, it inits an ADC read for pinX.
  2. Once the ADC reading is ready, it is written into a buffer.
  3. On the next call to mozziAnalogRead(pinX), that cached value is returned (and the next reading is triggered).

This allows mozziAnalogRead() to return pretty much instantaneous, even without compromising the read quality. Obviously, the implementation is a bit convoluted (and there's even more: apparently, the first analog reading after switching pin is not reliable, and thus is discarded; not sure, whether that is needed for SAMD21, too), but with the above explanation, I hope it will make sense.

For SAMD21, after a quick search, the following seems like a page to look at more closely: https://borkedlabs.com/blog/2014/06-20-asf-samd20-adc-callback-setup/ (in particular the section on setting a callback).

Ah, that helps a lot. Yeah, the 'first analog read after switching pin' is usually funky because really, all of these MCUs only have a limited number of ADCs and they're muxing internally - so you're firing off a new read after switching a multiplexer, and it might still be settling.

Will let you know if I progress this at all! But the borkedlabs page is a great start, and thanks for clarifying how things work.