PaulStoffregen
Well-known member
Posted today to the Arduino developers mail list, and reposting so we can discuss it here, if anyone's interested?
------------------------------------
Sometime next year I'm planning to implement an improved analog input API for Teensy. If possible, I'd like to build consensus on the API, to (hopefully) someday bring these improvements to all Arduino users. I also want to maximize compatibility across all Arduino compatible boards, if a well defined API can be agreed upon?
At this early stage, I really only have a rough wish-list, not a detailed proposal. Here are some of the things I want to accomplish:
1: Non-blocking functions: Functions similar to Serial.available() or serialEvent() can receive data without waiting. Or perhaps new functions are better than following the familiar Stream API? Or maybe the Stream base class ought to be extended slightly? Or perhaps a new base class for multi-byte streams or very specifically focused on analog input should be added? If the core library provides a capable base class, maybe it could be useful for libraries to support external ADC chips?
2: Low-jitter sampling: Both single-shot triggering and automatic sampling are needed. For many applications, the timing accuracy of sampling is as important as the analog measurement accuracy. With analogRead(), achieving low jitter timing is nearly impossible, even for experts. The API should make setting up automatic repetitive measurements simple and easy for novices.
3: Input sequencing: For sampling, often users need to read more than one input. The setup function for sampling should provide a way to specify a list of inputs to read. Repeating an input in the list should be legal, so certain inputs can be sampled more regularly than others. For receiving the data with the usual Stream model, perhaps a 3 function could work, Analog.available(), Analog.channel(), Analog.read()? Or maybe the available() function could report which channel is the next that read() will return, but somehow also work with the zero-based numbering scheme? For event-based reception, passing the channel number to the event function seems pretty simple. Another minor question involves whether to use the A0-A15 numbers (which actually correspond to the digital pin numbers), or to use zero-based numbers in the API?
4: Multi-ADC capable: Today, most microcontrollers have a single ADC with an analog mux. But multi-ADC chips are already entering the market and are likely to become common over the next 10 years. Ideally, the API should "just work" with these more capable chips. I honestly haven't thought much about how this ought to work.
5: Handling different resolutions: I know this is a thorny issue. Arduino already has analogReadResolution, which defaults to 10 bits. Perhaps it's best to just stick with that? Or maybe always left-justifying data to some high res is best for long-term use? Even left-justified, should the return type be able to accommodate more than 16 bits? Some microcontrollers available today from Analog Devices have > 16 bit delta-sigma ADCs. Certainly the return should be signed, since many chips, even some AVRs, support differential inputs. Maybe the return should be "int" that defaults to 16 bits on AVR and 32 bits on ARM? (locking AVR out of higher than 16 res, but also making the code more efficient...)
Did I miss important features?
I know this is a large and complex topics. Even relatively simple API stuff tends to result in huge conversations on this mail list, so please try to keep replies on-topic?
Ultimately, I want to bring more analog input capabilities to as many users as possible with the sort of easy-to-use API everyone expects from Arduino. My hope is to build consensus, so long-term all users can benefit from a more capable API that's highly compatible across many boards.
------------------------------------
Sometime next year I'm planning to implement an improved analog input API for Teensy. If possible, I'd like to build consensus on the API, to (hopefully) someday bring these improvements to all Arduino users. I also want to maximize compatibility across all Arduino compatible boards, if a well defined API can be agreed upon?
At this early stage, I really only have a rough wish-list, not a detailed proposal. Here are some of the things I want to accomplish:
1: Non-blocking functions: Functions similar to Serial.available() or serialEvent() can receive data without waiting. Or perhaps new functions are better than following the familiar Stream API? Or maybe the Stream base class ought to be extended slightly? Or perhaps a new base class for multi-byte streams or very specifically focused on analog input should be added? If the core library provides a capable base class, maybe it could be useful for libraries to support external ADC chips?
2: Low-jitter sampling: Both single-shot triggering and automatic sampling are needed. For many applications, the timing accuracy of sampling is as important as the analog measurement accuracy. With analogRead(), achieving low jitter timing is nearly impossible, even for experts. The API should make setting up automatic repetitive measurements simple and easy for novices.
3: Input sequencing: For sampling, often users need to read more than one input. The setup function for sampling should provide a way to specify a list of inputs to read. Repeating an input in the list should be legal, so certain inputs can be sampled more regularly than others. For receiving the data with the usual Stream model, perhaps a 3 function could work, Analog.available(), Analog.channel(), Analog.read()? Or maybe the available() function could report which channel is the next that read() will return, but somehow also work with the zero-based numbering scheme? For event-based reception, passing the channel number to the event function seems pretty simple. Another minor question involves whether to use the A0-A15 numbers (which actually correspond to the digital pin numbers), or to use zero-based numbers in the API?
4: Multi-ADC capable: Today, most microcontrollers have a single ADC with an analog mux. But multi-ADC chips are already entering the market and are likely to become common over the next 10 years. Ideally, the API should "just work" with these more capable chips. I honestly haven't thought much about how this ought to work.
5: Handling different resolutions: I know this is a thorny issue. Arduino already has analogReadResolution, which defaults to 10 bits. Perhaps it's best to just stick with that? Or maybe always left-justifying data to some high res is best for long-term use? Even left-justified, should the return type be able to accommodate more than 16 bits? Some microcontrollers available today from Analog Devices have > 16 bit delta-sigma ADCs. Certainly the return should be signed, since many chips, even some AVRs, support differential inputs. Maybe the return should be "int" that defaults to 16 bits on AVR and 32 bits on ARM? (locking AVR out of higher than 16 res, but also making the code more efficient...)
Did I miss important features?
I know this is a large and complex topics. Even relatively simple API stuff tends to result in huge conversations on this mail list, so please try to keep replies on-topic?
Ultimately, I want to bring more analog input capabilities to as many users as possible with the sort of easy-to-use API everyone expects from Arduino. My hope is to build consensus, so long-term all users can benefit from a more capable API that's highly compatible across many boards.