Teensy 3.2 ADC audio input with 11 analog reads - Possible?

Status
Not open for further replies.

dslocum

Well-known member
I know the docs on the ADC audio input block says you can't use any AnalogRead() - and correct me if I'm wrong (just guessing here), but the ADC block is interrupt based and the AnalogRead() is blocking and that's where the problem lays.

So would it be possible to use multiple ADC audio blocks - one for audio and the rest for potentiometer inputs?

I'm looking to have an audio input with lots of DC control pots for effects and would prefer not to use the Audio Shield.
 
Contrary to what they say, and the website says, you can use both AudioInputAnalog and analogRead().
I posted it a long time ago but I can't find that thread.
You can use ADC0 for audio, and ADC1 for analog readings.

How to change AudioInputAnalog pin?
AudioInputAnalog adc1(A0);

For Teensy 3.2:
A0 ADC0
A1 ADC0
A2 ADC0/ADC1 // don't use this
A3 ADC0/ADC1 // don't use this
A4 ADC0
A5 ADC0
A6 ADC0
A7 ADC0
A8 ADC0
A9 ADC0
A10 ADC0/ADC1 // don't use this
A11 ADC0/ADC1 // don't use this
A12 ADC0/ADC1 // don't use this
A13 ADC0/ADC1 // don't use this
A14 ADC0
A15 ADC1
A16 ADC1
A17 ADC1
A18 ADC1
A19 ADC1
A20 ADC1
 
Last edited:
Hi and thanks for your reply. But I'm confused....

Are you saying that this Teensy has 2 ADC cores? If so, how do I select what core to use for audio and which for AnalogReads?

Also, you list A0 thru A20 and the 3.2 only has 11 analog inputs. Why do you say "don't use this" on some?

Sorry to be confused. Would you be kind enough to clarify please?

Thanks

Doug
 
The Teensy 3.2 has 2 ADC cores (see tech specs: https://www.pjrc.com/teensy/techspecs.html ). By configuring the audio library with AudioInputAnalog adc1(A0); it will use the ADC0 core because A0 can only work with the ADC0 core through the multiplexer (see reference manual: https://www.pjrc.com/teensy/K20P64M72SF1RM.pdf ). Thus, you might use the ADC1 core for analogRead. Or vice-versa if you select an ADC1 core only pin to initiate the audio library adcX object.

The Teensy has more than 11 analog inputs. Some of these are not brought out to the pin headers but can be accessed via bottom pads as you can see on the little card which came with the Teensy or here: https://www.pjrc.com/teensy/pinout.html.

Some of the analog pins can be MUXed to either the ADC0 or the ADC1 core. This can lead to ambiguous situations when using analogRead() because the latter will most times route the pin MUX towards ADC0 by default. And I think it is the same for the audio library, so it is best to avoid these pins to avoid conflicts as long as you can not write your own analogRead function with an additional parameter for the MUX.

No reason to be confused. But thorough study of the available documentation on the PJRC website would have greatly helped.
 
The Teensy 3.2 has 2 ADC cores (see tech specs: https://www.pjrc.com/teensy/techspecs.html ). By configuring the audio library with AudioInputAnalog adc1(A0); it will use the ADC0 core because A0 can only work with the ADC0 core through the multiplexer (see reference manual: https://www.pjrc.com/teensy/K20P64M72SF1RM.pdf ). Thus, you might use the ADC1 core for analogRead. Or vice-versa if you select an ADC1 core only pin to initiate the audio library adcX object.

The Teensy has more than 11 analog inputs. Some of these are not brought out to the pin headers but can be accessed via bottom pads as you can see on the little card which came with the Teensy or here: https://www.pjrc.com/teensy/pinout.html.

Some of the analog pins can be MUXed to either the ADC0 or the ADC1 core. This can lead to ambiguous situations when using analogRead() because the latter will most times route the pin MUX towards ADC0 by default. And I think it is the same for the audio library, so it is best to avoid these pins to avoid conflicts as long as you can not write your own analogRead function with an additional parameter for the MUX.

No reason to be confused. But thorough study of the available documentation on the PJRC website would have greatly helped.

No problem, and thanks for your details. I actually tried to search the PJRC website, but it can be difficult to find things sometimes.

Off topic.... Great to see another Theremin player. I've got a Paia Theremax, modified with Moog antennas. Still learning. I'm a synth designer (www.steamsynth.com)

Question - Because I need at least 9 DC analog inputs, plus 1 audio and a DAC output, do you think this is possible with a 3.2? From what you are saying, I can not get without using the bottom pads.
 
The simplest way to get to the underneath solder pads is perhaps this PCB designed by Frank B:

It costs $3.45 (or $6.90 for rush service where it is shipped in 5 days) for 3 PCB's. There are other methods, but this doesn't need to have other parts like SMT headers to bring out the 10 pins underneath.
 
That's a cool solution, but it limits the options for pin lengths and plugging into sockets I would think.

Maybe I should just go for the 3.5 or 3.6 instead of the 3.2? It would probably be severe overkill, but I would have way more than I could ever need.
 
That makes me think...

Sorry to go off topic here... If I develop on the 3.2 and get a prototype working, couldn't I design my own PCB with the same CPU? Is it possible to load a HEX file into the CPU without the bootloader using ICSP? I've looked around a little, but can't seem to find an answer.
 
That's a cool solution, but it limits the options for pin lengths and plugging into sockets I would think.

Maybe I should just go for the 3.5 or 3.6 instead of the 3.2? It would probably be severe overkill, but I would have way more than I could ever need.

As I said, there are other solutions that bring out the pins. Most of those solutions were developed before the Teensy 3.5/3.6 came out, and are probably more expensive than the difference between the 3.2 and 3.5 or 3.6.

You get 11 more analog inputs that are useful in a breadboard with the 3.5/3.6 (A12-A22). There are two more in solder pads underneath the 3.5/3.6 (A23-A24). The 3.5 has an additional 2 analog inputs (A25-26) on the inside where the 2nd USB is. And there are the two on the inside of the Teensys (A10-A11).
 
That makes me think...

Sorry to go off topic here... If I develop on the 3.2 and get a prototype working, couldn't I design my own PCB with the same CPU? Is it possible to load a HEX file into the CPU without the bootloader using ICSP? I've looked around a little, but can't seem to find an answer.
You can buy the bootloader from PJRC.COM if you want to design your own system using the same chips.
 
As I said, there are other solutions that bring out the pins. Most of those solutions were developed before the Teensy 3.5/3.6 came out, and are probably more expensive than the difference between the 3.2 and 3.5 or 3.6.

You get 11 more analog inputs that are useful in a breadboard with the 3.5/3.6 (A12-A22). There are two more in solder pads underneath the 3.5/3.6 (A23-A24). The 3.5 has an additional 2 analog inputs (A25-26) on the inside where the 2nd USB is. And there are the two on the inside of the Teensys (A10-A11).

I went ahead and ordered a Teensy 3.5. I'm looking at Revalogics Teensy 3.2 table a few posts ago and it looks like ADC1 is only free on 6 pins (A15 thru A20). What about the Teensy 3.5? Can I get the additional 3 or 4 ADC1 pins that I need on the 3.5 without going under the board? I'm really trying to understand the K20 Reference manual, but it's a little over my head. I'm used to Microchip CPUs, but this thing is a monster.
 
I'm not sure what the "(A0)" in the lines below do.

"How to change AudioInputAnalog pin?
AudioInputAnalog adc1(A0);"

Do they force input A0 to ADC1 core ? Once ADC1 core is used for audio, I assume that it can no longer be used for AnalogRead(); Is that correct?

Is there any way to force AudioInputAnalog to read from ADC2 core? That way ADC1 core could be used for AnalogRead().

I'm trying to understand the multiplexing that's going on, but it's tough. The bottom line is that I need one audio input, a 12 bit DAC audio output, and at least 9 or 10 AnalogRead() inputs. I don't want to resort to going under the Teesy PCB. Just too messy for my taste.
 
If I were a German grammar teacher, I’d say that you are confounding subject and object...

Declaring the AudioInputAnalog object by the name “adc1” has nothing to do with the ADC1 core, it’s just a name! You could call it adc4711. When you look at the source code of that object in the audio library, you’ll see that everything depends on the chosen pin, in that case A0. As Revalogics wrote, A0 can only be muxed to the ADC0 core, thus the object will do exactly that automatically. That’s also the case for the ambiguous pins for which he wrote “Don’t use” because the the AudioInputAnalog object code would mux these to ADC0, too. If you want the audio library to use the ADC1 core (to have the ADC0 core and its corresponding input pins free for analog read, you should instantiate the audio library object with an ADC1 only pin to force that association. Then, everything is automatic and you do not have to care about multiplexing since the AudioInputAnalog object and the AnalogRead() function do that automatically as long as you chose appropriate pins.

Generally, I’d recommend to not to use whatever library or function as long as one hasn’t studied their source code to understand what happens behind the scenes. That’s a great learning exercise. Next step is then to abandon readily built in functions and libraries in favor of self written highly optimized and specialized functions and objects (still inspired by the code which you studied before) for your project.
 
If I were a German grammar teacher, I’d say that you are confounding subject and object...
Ha ha. I don't speak German, but I'm sure you are correct. In the Thai language however, this would not be so much a problem, as these terms are rarely conflated. :)

Declaring the AudioInputAnalog object by the name “adc1” has nothing to do with the ADC1 core, it’s just a name! You could call it adc4711.
Thanks. I understand that, and I'm happy to learn new things, but.... I see in the Github source that the constructor allows for an overload - with and without a pin number, but without diving into a deep "rabbit-hole" of code, I would still not be able to decypher how the analog input multiplexing works on these chips.

When you look at the source code of that object in the audio library....
I was honestly hoping that I would not have to dig that deeply into the underlaying code.

My hope is that I can write relatively simple Arduino code to accomplish my goals.

I would greatly appreciate if someone could provide a snippet of code that would initialize my AudioInputAnalog to use ADC2 core so that I can use ADC1 core for my 9 or 10 AnalogRead() inputs.
 
Here's my update on this...

I've decided to use the Teensy 3.5, but use a 74HC4051 analog multiplexer to read my 8 pots into ADC2 core on A15. It's a relatively small change and an additional part, but now I don't need to worry about pulling analog signals off the bottom of the board - just because I want to use AudioInputAnalog. I've tested it on my 3.2 board using A0 as audio input and A15 for my analog pot input so that ADC2 core is used. Works fine. I'll add the 4051 mux and code later now that I know I can input audio and analog separately. I just had to remember to connect AGND to GND at some point.

This platform is incredibly powerful. Many thanks to Paul, etal, for putting this audio coding environment together. Also thanks for those who have contributed suggestions and wisdom.
 
Status
Not open for further replies.
Back
Top