Crash when using analogRead on Teensy 3.6

Status
Not open for further replies.

unicornpower

Well-known member
I've just soldered up my Teensy 3.6 and have moved my current audio project over to it. I'm loving having 256k but my code was crashing as soon I was trying to read values from my pots. I've managed to recreate this issue in a small test program, and isolated the problem to only happening if I have an AudioInputAnalog defined and call analogRead(). I'm not actually using the analog input at the moment, as I'm playing audio from an SD card instead, so it's not patched to anything, I wouldn't expect this to cause a crash though?

Below is the code, if I comment out the AudioInputAnalog object, everything works fine, but I leave it in, it crashes immediately. Any ideas?


Code:
#include <Audio.h>
#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include <SerialFlash.h>
#include <Bounce.h>

// Use these with the audio adaptor board
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14

AudioPlaySdRaw           raw_player;
AudioInputAnalog         audio_input;   // PROGRAM CRASHES IMMEDIATELY UNLESS I COMMENT THIS OUT (or I comment out the analogRead)
AudioOutputAnalog        audio_output;
AudioConnection          patch_cord( raw_player, 0, audio_output, 0 );

int count = 0;

void setup()
{
  AudioMemory(10);

  Serial.begin(115200);

  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);

  if (!(SD.begin(BUILTIN_SDCARD)))
  {
    // stop here, but print a message repetitively
    while (1)
    {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
}

void loop()
{
  if( !raw_player.isPlaying() )
  {
    Serial.println("START RAW");
    raw_player.play( "GUITAR.RAW" ); 
  }

  int value = analogRead( 20);
  if( ++count % 1000 == 0 )
  {
    Serial.print(value);
    Serial.print("\n");
  }
}
 
Ah, I had actually looked at that, but misinterpreted it. I thought it meant you couldn't read the DAC pins (A22/A21) with analogRead whilst using audio input. So you can't use analogRead at all? That makes sense. I guess I just need to disable interrupts when I want to read the potentiometers? Thanks Paul!
 
No, you *really* can't use the ADC while the audio library is using it. Disabling interrupts won't work. The audio lib sets the ADC up to be automatically triggered by the PDB timer and automatically read by DMA, so it's being used automatically without any interrupts, except the DMA interrupt when many readings have been stored in memory. This is how the audio library manages to be so efficient!

If you mess with the ADC while the timer is triggering and DMA is reading, things will go badly.
 
Oh, I see, thanks for the explanation. I guess I need to rethink then. I was trying to get my audio project working without the audio shield, as I plan to store the audio at 12-bit resolution the built-in ADCs seemed sufficient, but it seems I can't do that and have the effect controlled by potentiometers.
 
No, you *really* can't use the ADC while the audio library is using it.

Does the DAC have similar restrictions? I am having weird things happen with the second DAC output while my full synth program is running. The main loop spends most of its time reading 48 pots, and 4 encoders. Breaking this down into small chunks at a time causes no unusual operation. I will eventually figure out just what combinations break the second DAC, but I haven't had much time to work on it lately.

When the second DAC fails the output is still there, but sometimes corrupted by other events happening in the synth. I can just send a "DC" level of .5 to the DAC and get the expected output, but the voltage output will rise when there are too many other things going on. DAC 1 remains unaffected.
 
With the DACs, writing to them while in use by the audio library isn't as bad as trying to read the ADCs. But future versions may change to other triggering methods, so it's still a terrible idea to use analogWrite() or direct register writes to the DACs while the audio library is also using them.

Even if you do successfully write to the DAC from your Arduino sketch, what does it matter? The audio library is writing to the DAC 44100 times per second. Your change will only last at most about 22 microseconds.
 
I am not directly writing to the DACs. I connected each DAC output to a waveform object using the GUI in the audio library to create analog output LFO's (low frequency oscillators) for use elsewhere in my synth. All DAC writing is controlled by the audio library. The audio library also sends the stereo synth output to the audio adapter, so I have 4 total analog outputs from the synth. All worked fine when there was only one DAC output (3 total outputs), but when the second DAC output became available in the TD beta version, I added another waveform object and connected it to the second DAC. It never worked right and most of the time artifacts from the audio board outputs can be seen on the internal second DAC output.

I stripped this all down to 4 waveform objects connected to the 4 available DAC's, (2 internal 12 bit, 2 external 16 bit on audio adapter) This works fine. Over the next few days I plan to add back all the synth stuff bit by bit to see what breaks the second internal DAC. Any clues as to possible suspects could save me some time. There is a lot of stuff going on in the main loop, but mostly 4 encoders and 5 switches are read using the encoder library and digital Read, 48 multiplexed pots are read using analogRead, and 3 digital writes to control the muxes. 4 keyboard control voltages are read using analogRead. and a math library is used to perform the log conversion for a 1V/ octave input.
 
I connected each DAC output to a waveform object using the GUI in the audio library to create analog output LFO's

This makes no sense to me. In the design tool, the DAC object has no outputs. It has only an input, which is the data it will turn into an analog voltage.

Maybe post a screenshot of what you're doing?
 
but when the second DAC output became available in the TD beta version, I added another waveform object and connected it to the second DAC.

If the original DAC object is still in your design, you must delete it. The new stereo DAC sends to both pins. If must not be used together with the old one which sends to only DAC0.

It's also possible there's a bug in the new code. But I can't investigate unless you create a (hopefully small & simple) program to reproduce the problem. The less it depends on encoders and other stuff I don't have here, the better I can look into this and try to solve whatever's wrong.
 
the DAC object has no outputs. It has only an input, which is the data it will turn into an analog voltage.

Yes, I feed the DAC the output of a waveform object. The DAC outputs an analog voltage through a pin on the Teensy which I use externally in some analog hardware. The output of this hardware does get applied back to an analog pin on the Teensy to modulate a VCO by changing the frequency number sent to the waveform object. All of this works stand alone, and as a complete system in the Teensy 3.2 or the Teensy 3.6 with one DAC.

If the original DAC object is still in your design, you must delete it.

I replaced the original DAC object with the new DACS object and added a new waveform object which I connected to the second input connection. The DAC0 output still functions normally, but DAC1 often gets corrupted, or outputs something unusual.

It's also possible there's a bug in the new code. But I can't investigate unless you create a (hopefully small & simple) program to reproduce the problem.

I am a hardware guy, so it's entirely possible that I have something messed up in my code, and possibly in the hardware. I am attempting to divide and conquer, both by starting with something simple (2 waveforms, one connected to each input on DACS) which works and expanding it. I have also tried commenting blocks out of my complex synth code (always broken). The idea it to find the absolute simplest setup (both SW and HW) that demonstrates the issue, or find my mistake and fix it.
 
Status
Not open for further replies.
Back
Top