Teensy 3.6 Sine -> DAC cannot change frequency

Status
Not open for further replies.

kramer

Member
I have started experimenting with the Audio library. My experiment is to connect a very low frequency sine wave to the DAC0 and "listen" to it on a breadboard with an LED (ie: the LED blinks in time to the oscillations).

Here is the code:

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

// GUItool: begin automatically generated code
AudioSynthWaveformSine   sine1;          //xy=236,269
AudioOutputAnalog        dac1;           //xy=406,263
AudioConnection          patchCord1(sine1, dac1);
// GUItool: end automatically generated code

void setup() {
  AudioMemory(20);
  sine1.frequency(5); // -- this does nothing
}

void loop() {
}

I have an LED wired between DAC0 (pin A21 on the supplied pin sheet) and Vin.

The LED blinks at a rate about 1HZ or slightly faster. I then added the line to set it to 5HZ, but this changes nothing.

Strangely, if I comment out the AudioSynthWaveformSine and AudioConnection declarations, leaving only the dac1, it keeps blinking. It seems like there's some kind of default signal running?

I plan to do some audio processing and wire up input / output audio jacks, but don't have the parts yet, so figured I'd start getting familiar with the Audio library. Also, I don't want to use the audio-shield board.
 
Thanks for the reply. I made that change, but it has no effect:

Code:
void setup() {
  AudioMemory(20);
  sine1.amplitude(1.0);
  sine1.frequency(5); // -- this does nothing
}
 
I'm running it here. Works fine.

Here's what my scope sees on the DAC0 pin.

file.png

Here's the complete code from the Arduino window.

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

// GUItool: begin automatically generated code
AudioSynthWaveformSine   sine1;          //xy=236,269
AudioOutputAnalog        dac1;           //xy=406,263
AudioConnection          patchCord1(sine1, dac1);
// GUItool: end automatically generated code

void setup() {
  AudioMemory(20);
  sine1.amplitude(1.0);
  sine1.frequency(5);
}

void loop() {
}
 
Okay, well that's really weird then, cos I have the exact code above. Here's a video showing my wiring and the flash frequency, just in case I'm doing something wrong there:

[video]https://photos.app.goo.gl/C6Dv6MJ2j6CVej5u6[/video]
 
You killed most probably the DAC with your LED connected between Vin and DAC0...

Vin is 5V, thus, depending on the LED's forward voltage (Vf between 1.6 and 2.2V), you are forcing the DAC output to 5V - Vf = 2.8 to 3.4V, while its output amplitude (set with the reference from the audio lib) is between 0 and 1.2V, centered around 0.6V. In that case, the LED will source a current (min. 5mA when lit) into the DAC output, while the latter is intended not to absorb external currents, but to feed a current of max. 1mA into a load towards GND. Testing a DAC output means connecting a load of typical 10kOhm or more from the DAC0 to GND and to check the voltage (as Paul did) with an oscilloscope (which has an input impedance of >= 1MegOhm). If you want to drive more current consuming (power hungry) devices like a LED or a speaker, you need to add an external amplifier stage.
 
Sighs... well that sucks... and raises a few questions:

1) If I decided to use the Audio shield, would it still function with the blown DAC on the Teensy?

2) Could I repurpose some of the analog input / output pins for audio processing? ie: analogRead a mono signal on one, do some work programmatically with it (I realize the Audio library and its GUI are not an option here), and analogWrite to another?
 
The T_3.6 has two DACS. You can test them wiring them to an another pin and doing analog read as the output is varied and see if it follows and works.
 
You guys are going to laugh at me... I found out that red LED I had was one of those self-blinking ones - hence why the frequency was stuck!

I took defragster's advice and wired the dac0 and dac1 to A0 and A1, respectively. I also removed all other wires / LED.

This program creates the output below (which looks wrong to me):
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveformSine   sine1;          //xy=236,269
//AudioSynthWaveformSine   sine2;          //xy=247,377
AudioOutputAnalog        dac1;           //xy=406,263
//AudioOutputAnalog        dac2;           //xy=424,389
AudioConnection          patchCord1(sine1, dac1);
//AudioConnection          patchCord2(sine2, dac2);
// GUItool: end automatically generated code

void setup() {
  Serial.println("hi");

  sine1.frequency(1);
  sine1.amplitude(1.0);
//  sine2.frequency(1);
//  sine2.amplitude(1.0);
}

void loop() {
  int val0 = analogRead(0);
  int val1 = analogRead(1);
  Serial.printf("A0: %d  A1: %d\n", val0, val1);
  delay(100);
}

Code:
23:47:51.924 -> hi
23:47:51.924 -> A0: 184  A1: 558
23:47:51.924 -> A0: 184  A1: 442
23:47:51.924 -> A0: 184  A1: 366
23:47:51.956 -> A0: 184  A1: 394
23:47:52.066 -> A0: 184  A1: 390
23:47:52.176 -> A0: 184  A1: 413
23:47:52.249 -> A0: 184  A1: 396
23:47:52.358 -> A0: 184  A1: 368
23:47:52.471 -> A0: 184  A1: 387
23:47:52.584 -> A0: 184  A1: 410
23:47:52.657 -> A0: 184  A1: 425
23:47:52.769 -> A0: 184  A1: 404
23:47:52.881 -> A0: 184  A1: 391
23:47:52.956 -> A0: 184  A1: 388
23:47:53.065 -> A0: 184  A1: 423
23:47:53.177 -> A0: 184  A1: 414
23:47:53.252 -> A0: 184  A1: 378
23:47:53.364 -> A0: 184  A1: 373
23:47:53.476 -> A0: 184  A1: 405
23:47:53.552 -> A0: 184  A1: 384
23:47:53.665 -> A0: 184  A1: 416
23:47:53.775 -> A0: 184  A1: 418
23:47:53.848 -> A0: 184  A1: 442
23:47:53.959 -> A0: 184  A1: 395
23:47:54.065 -> A0: 184  A1: 428
23:47:54.176 -> A0: 184  A1: 388
23:47:54.283 -> A0: 184  A1: 410
23:47:54.350 -> A0: 184  A1: 410
23:47:54.456 -> A0: 184  A1: 433
23:47:54.566 -> A0: 184  A1: 446
23:47:54.676 -> A0: 184  A1: 427
23:47:54.749 -> A0: 184  A1: 425
23:47:54.855 -> A0: 184  A1: 380
23:47:54.968 -> A0: 184  A1: 402

This program, compiles, but does not run:

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

// GUItool: begin automatically generated code
AudioSynthWaveformSine   sine1;          //xy=236,269
AudioSynthWaveformSine   sine2;          //xy=247,377
AudioOutputAnalog        dac1;           //xy=406,263
AudioOutputAnalog        dac2;           //xy=424,389
AudioConnection          patchCord1(sine1, dac1);
AudioConnection          patchCord2(sine2, dac2);
// GUItool: end automatically generated code

void setup() {
  Serial.println("hi");

  sine1.frequency(1);
  sine1.amplitude(1.0);
  sine2.frequency(1);
  sine2.amplitude(1.0);
}

void loop() {
  int val0 = analogRead(0);
  int val1 = analogRead(1);
  Serial.printf("A0: %d  A1: %d\n", val0, val1);
  delay(100);
}

So I'm guessing I'm screwed at this point?

One thing I'm confused about is how the GUI generated code associates the variables 'dac1' and 'dac2' to the actual hardware, as I can name these 'dacblahblah' if I want... I see no other identifiers in the generated code.
 
This has a few changes and seems to show on both DACS where 1 is 10x faster:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveformSine   sine2;          //xy=392,304
AudioSynthWaveformSine   sine1;          //xy=398,239
AudioOutputAnalogStereo  dacs1;          //xy=694,207
AudioConnection          patchCord1(sine2, 0, dacs1, 1);
AudioConnection          patchCord2(sine1, 0, dacs1, 0);
// GUItool: end automatically generated code

int AudMM = 0;
void setup() {
	AudioMemory(20);
	sine1.frequency(1);
	sine1.amplitude(1.0);
	sine2.frequency(10);
	sine2.amplitude(1.0);
	while ( !Serial && millis() < 2500);
	Serial.print("hi ------------ @ ms=");
	Serial.println(millis());
	AudMM = 0;
}

#define MaxUpdate_ms 10
elapsedMillis slowerOut = 0;
int val0p = 6553500;
int val1p = 6553500;
void loop() {
	int val0 = analogRead(39);
	int val1 = analogRead(38);
	if ( (val0 != val0p || val1 != val1p) && slowerOut > MaxUpdate_ms ) {
		val0p = val0;
		val1p = val1;
		if ( 100 > val0 )
			Serial.printf("A0: %d  \t\tA1: %d\n", val0, val1);
		else
			Serial.printf("A0: %d  \tA1: %d\n", val0, val1);
		slowerOut = 0;
	}
	if ( AudMM != AudioMemoryUsageMax() ) {
		Serial.print("Memory: ");
		Serial.println(AudioMemoryUsageMax());
		AudMM = AudioMemoryUsageMax();
	}
}

You can see DACS jumpered to alternate pins - that is my choice.
 
So I'm guessing I'm screwed at this point?

Not necessarily. Your program is missing AudioMemory(), so it does nothing even on perfectly good hardware.

Here's is a fixed copy of your program.

Code:
#include <Audio.h>

AudioSynthWaveformSine   sine1;          //xy=236,269
AudioOutputAnalog        dac1;           //xy=406,263
AudioConnection          patchCord1(sine1, dac1);

void setup() {
  Serial.println("hi");
  AudioMemory(10);
  sine1.frequency(1);
  sine1.amplitude(1.0);
}

void loop() {
  int val0 = analogRead(0);
  int val1 = analogRead(1);
  Serial.printf("A0: %d  A1: %d\n", val0, val1);
  delay(100);
}

Here is the output when running on working hardware, with DAC0 wired to A0 and DAC1 wires to A1.

sc.png

Hopefully this helps, and maybe with a little luck your hardware will still be ok?
 
Regarding your other questions...

1) If I decided to use the Audio shield, would it still function with the blown DAC on the Teensy?

Very hard to say with confidence what partially damaged hardware will do.

But I can say 2 things.

1 - The audio shield uses different & independent pins and peripherals inside the chip, so if your chip has damage limited to only the DAC pin, then yes, or probably, or maybe.

2 - Hardware damage is usually all-or-nothing. Some people have reported just 1 pin damaged, so it is possible. But it's also pretty rare. If you're still able to upload programs, odds are in your favor that your hardware wasn't damaged.


2) Could I repurpose some of the analog input / output pins for audio processing? ie: analogRead a mono signal on one, do some work programmatically with it (I realize the Audio library and its GUI are not an option here), and analogWrite to another?

This only works if the audio library isn't using the hardware. You can use analogRead while the audio shield is running. In fact, nearly all the tutorials do this. But you can't use analogRead() if the audio library is using the ADC.
 
I'll add some "old fart" advice:

So called "ooooops moments" or even "magic smoke" happen to everybody, even to very experienced engineers and developers. That's one of the reasons you should never rely on only one single piece of hardware during an active development. Buy your Teensys in batches of 3. Another reason is debugging: Sometimes you can't be sure if it's a hardware or a software problem. Having a second (or third) Teensy in the drawer allows always a quick differential diagnose. Finally, most Teensy MCUs fall into the pocket money budget category and ordering 3 at a time will on top of that reduce the shipping cost part.
 
Guys, thank you so much.

Both Paul and defragster's programs show that both my DACs are still functional and working as expected. It was just the missing AudioMemory line (which was silly, as I had that in earlier programs).

This has been a valuable learning experience, and the support I've received as an electronics newbie has been outstanding.
 
I'll add some "old fart" advice:

So called "ooooops moments" or even "magic smoke" happen to everybody, even to very experienced engineers and developers. That's one of the reasons you should never rely on only one single piece of hardware during an active development. Buy your Teensys in batches of 3. Another reason is debugging: Sometimes you can't be sure if it's a hardware or a software problem. Having a second (or third) Teensy in the drawer allows always a quick differential diagnose. Finally, most Teensy MCUs fall into the pocket money budget category and ordering 3 at a time will on top of that reduce the shipping cost part.

That's good advice, thanks.
 
Status
Not open for further replies.
Back
Top