Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 17 of 17

Thread: Teensy 3.6 Sine -> DAC cannot change frequency

  1. #1
    Junior Member
    Join Date
    Mar 2019
    Posts
    12

    Teensy 3.6 Sine -> DAC cannot change frequency

    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.

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,506
    You need this:

    Code:
      sine1.amplitude(1.0);

  3. #3
    Junior Member
    Join Date
    Mar 2019
    Posts
    12
    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
    }

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,506
    I'm running it here. Works fine.

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

    Click image for larger version. 

Name:	file.png 
Views:	7 
Size:	26.0 KB 
ID:	16049

    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() {
    }

  5. #5
    Junior Member
    Join Date
    Mar 2019
    Posts
    12
    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:

    https://photos.app.goo.gl/C6Dv6MJ2j6CVej5u6

  6. #6
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,277
    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.

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,506
    I wasn't able to view the video. Maybe upload on youtube?

  8. #8
    Junior Member
    Join Date
    Mar 2019
    Posts
    12
    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?

  9. #9
    Junior Member
    Join Date
    Mar 2019
    Posts
    12
    Quote Originally Posted by PaulStoffregen View Post
    I wasn't able to view the video. Maybe upload on youtube?
    Here is a photo of the same:

    Click image for larger version. 

Name:	IMG_20190303_154802.jpg 
Views:	3 
Size:	225.0 KB 
ID:	16051

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,807
    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.

  11. #11
    Junior Member
    Join Date
    Mar 2019
    Posts
    12
    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.

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,807
    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.

  13. #13
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,506
    Quote Originally Posted by kramer View Post
    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.

    Click image for larger version. 

Name:	sc.png 
Views:	6 
Size:	57.0 KB 
ID:	16069

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

  14. #14
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,506
    Regarding your other questions...

    Quote Originally Posted by kramer View Post
    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.

  15. #15
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,277
    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.

  16. #16
    Junior Member
    Join Date
    Mar 2019
    Posts
    12
    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.

  17. #17
    Junior Member
    Join Date
    Mar 2019
    Posts
    12
    Quote Originally Posted by Theremingenieur View Post
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •