Description
The Teensy 4.1 is popular for audio projects due to its processing power. The Mini Platform Audio Tutorial Adapter can be used in conjunction with the Mini Platform for Teensy 4.1 and the PJRC Advanced Microcontroller Audio Workshop to learn about the audio capabilities of the Teensy 4.1. It can also be used to provide general purpose potentiometers and pushbuttons for other experiments as well.
The PJRC workshop PDF can be found here: https://www.pjrc.com/store/workshop_t4.pdf
Additional workshop information including a video tutorial can be found at this link: https://www.pjrc.com/store/audio_tutorial_kit.html
PACKAGE INCLUDES:
- Mini Platform Audio Tutorial Adapter – Fully assembled
KEY FEATURES OF AUDIO TUTORIAL ADAPTER:
- Uses the same Teensy 4.1 pins used in the original workshop
- User controls
- 2 Linear audio 10K potentiometers
- 1 Linear volume 10K potentiometer
- 3 User pushbuttons
- Mini Platform baseboard includes green LED on pin 5
- Fully assembled
USING THE AUDIO TUTORIAL ADAPTER:
The Mini Platform Audio Tutorial Adapter plugs into the IDC GPIO connector on the Mini Platform for Teensy 4.1 and provides the controls needed to work through the full audio workshop.
These are the Teensy 4.1 pins accessible using the IDC GPIO connector. This adapter makes use of analog pins 15/A1, 16/A2, 17/A3 and digital pins 0, 1 and 2. In addition, it uses the green LED portion of the RGB LED on the baseboard which is on pin 5
The tutorial sketches are available in the IDE under Files / Examples / Examples for Teensy 4.1 – Audio / Tutorial.
Changes to the Tutorial:
Board type:
Be sure to select Teensy 4.1 as the board type instead of Teensy 4.0 as described in the tutorial.
SD Card Slot:
For examples that use the SD card, we are going to be using the SD card slot built into the Teensy 4.1. The Mini Platform has the audio circuit built into the baseboard and doesn’t use a separate Audio Adapter with it’s own SD card slot. You will need to comment out this line which is for the Audio Adapter SD card slot.
#define SDCARD_CS_PIN 10
and uncomment this line to enable the Teensy 4.1 SD card slot
#define SDCARD_CS_PIN BUILTIN_SDCARD
The SD card that ships with the Mini Platform already includes the WAV files needed to complete the tutorial.
Part 3-3: Add a TFT Display
The one tutorial section that needs to completely change to work with the Mini Platform is the Part 3-3: Add a TFT display since we are using a different display. The example provided here also makes use of some of the other items covered in previous lessons, including adding the ability to select the WAV file being played and adding volume control.
The LCD uses the ST7796 display controller chip that communicates over SPI and is attached to the main SPI bus on the Teensy 4.1. The released version of Teensyduino (1.59) does not yet support this display chip, but support has been added to the latest Teensyduino 1.60 Beta #4 release. Instructions for installing the beta version of Teensyduino can be found at the following link if it has not already been installed: https://forum.pjrc.com/index.php?threads/teensyduino-1-60-beta-4.76907/
You can copy the code below and paste it into a new sketch in the IDE. Then add the Design Tool code to complete the sketch as per the tutorial example.
There is a known bug in the Teensy Audio Library that distorts the audio playback when displaying a lot of fast graphics as is used in this example. This will hopefully be fixed in an upcoming release of Teensyduino, but until then, it is easy to make a small change to the ST7735_t3 library to work around it by running the LCD at a faster speed.
To locate the installation path of the ST7735_t3 library, go to the IDE Preferences and select ‘ Show verbose output during compile’
Next, compile the example program below after it has been completed by adding the Design Tool code and then near the end of the verbose output, you will see a list of the libraries used. Look for the ST7735_t3 library. On my system it is located here: C:\Users\name\AppData\Local\Arduino15\packages\teensy\hardware\avr\0.60.4\libraries\ST7735_t3
Open the SRC folder, then open the ST7735_t3.h file with a text editor like Notepad or you can use something like Microsoft Visual Studio if you have that installed on your computer.
Scroll down to around line 45 of the file and find and comment out #define ST7735_SPICLOCK 16000000 and add a new line #define ST7735_SPICLOCK 80000000
The edit should look something like this once you are done.
#define ST7735_SPICLOCK 80000000
//#define ST7735_SPICLOCK 24000000
//#define ST7735_SPICLOCK 16000000
Select Save to save the file.
This change increases the SPI data rate for the LCD from 16MHz all the way up to 80MHz. This allows the display to be updated fast enough to avoid conflicts with the Audio Library. Note that a more comprehensive fix is being worked on to add to Teensyduino and this information will be updated once it is available. Check out the link in Further Reading down below if you are interested in the details on this.
// Advanced Microcontroller-based Audio Workshop // // http://www.pjrc.com/store/audio_tutorial_kit.html // https://hackaday.io/project/8292-microcontroller-audio-workshop-had-supercon-2015 // // Part 3-3: Add a TFT Display // // This is modified to work with the Mini Platform for Teensy 4.1 ST7796 LCD #include <ST7796_t3.h> #include <st7735_t3_font_Arial.h> #include <Audio.h> #include <Wire.h> #include <SPI.h> #include <SD.h> #include <SerialFlash.h> #include <Bounce.h> /////////////////////////////////// // copy the Design Tool code here /////////////////////////////////// // GUItool: end automatically generated code // TFT pin definitions #define TFT_DC 9 #define TFT_CS 10 ST7796_t3 tft = ST7796_t3(TFT_CS, TFT_DC); #define SDCARD_CS_PIN BUILTIN_SDCARD Bounce button0 = Bounce(0, 15); Bounce button2 = Bounce(2, 15); // 15 = 15 ms debounce time void setup() { Serial.begin(9600); delay(500); //tft.setSPISpeed(80000000); // Setup the LCD screen tft.init(320, 480); tft.invertDisplay(true); // LCD requires colors to be inverted tft.setRotation(3); // Rotates screen to match the baseboard orientation tft.fillScreen(ST7735_BLACK); tft.setTextColor(ST7735_YELLOW); tft.setFont(Arial_24); //tft.setTextSize(3); tft.setCursor(60, 8); tft.println("Peak Meter"); tft.setFont(Arial_14); tft.setCursor(5, 60); tft.println("File: "); tft.setCursor(5, 100); tft.println("Vol: "); tft.drawTriangle(40, 240, 60, 260, 80, 240, ST7735_YELLOW); tft.drawTriangle(150, 260, 170, 240, 190, 260,ST7735_YELLOW); tft.setCursor(30,280); tft.println("BTN 0 BTN 2"); AudioMemory(10); sgtl5000_1.enable(); sgtl5000_1.volume(0.1); if (!(SD.begin(SDCARD_CS_PIN))) { while (1) { Serial.println("Unable to access the SD card"); delay(500); } } pinMode(0, INPUT_PULLUP); pinMode(2, INPUT_PULLUP); delay(1000); } int filenumber = 0; // which file to play // List of files we can play const char * filelist[4] = { "SDTEST1.WAV", "SDTEST2.WAV", "SDTEST3.WAV", "SDTEST4.WAV" }; int knob = 0; int knobOld = 128; elapsedMillis msecs; void loop() { if (playSdWav1.isPlaying() == false) { const char *filename = filelist[filenumber]; filenumber = filenumber + 1; if (filenumber >= 4) filenumber = 0; Serial.print("Start playing "); Serial.println(filename); playSdWav1.play(filename); tft.fillRect(50, 60, 240, 16, ST7735_BLACK); tft.setCursor(50, 60); tft.print(filename); delay(10); // wait for library to parse WAV info } if (msecs > 15) { if (peak1.available() && peak2.available()) { float leftNumber = peak1.read(); float rightNumber = peak2.read(); static int leftNumberOld = 0; static int rightNumberOld = 0; // draw the vertical bars int height = leftNumber * 260; if ( height > leftNumberOld ) tft.fillRect(320, 290 - height, 40, height, ST7735_GREEN); else tft.fillRect(320, 290 - 280, 40, 280 - height, ST7735_BLACK); leftNumberOld = height; height = rightNumber * 260; if ( height > rightNumberOld ) tft.fillRect(400, 290 - height, 40, height, ST7735_GREEN); else tft.fillRect(400, 290 - 280, 40, 280 - height, ST7735_BLACK); rightNumberOld = height; // a smarter approach would redraw only the changed portion... // draw numbers underneath each bar tft.setFont(Arial_14); tft.fillRect(320, 300, 40, 16, ST7735_BLACK); tft.setCursor(320, 300); tft.print(leftNumber); tft.fillRect(400, 300, 40, 16, ST7735_BLACK); tft.setCursor(400, 300); tft.print(rightNumber); msecs = 0; } } // read pushbuttons button0.update(); if (button0.fallingEdge()) { tft.fillTriangle(40, 240, 60, 260, 80, 240, ST7735_YELLOW); playSdWav1.stop(); delay(100); tft.fillRect(40, 240, 40, 20, ST7735_BLACK); tft.drawTriangle(40, 240, 60, 260, 80, 240, ST7735_YELLOW); } button2.update(); if (button2.fallingEdge()) { tft.fillTriangle(150, 260, 170, 240, 190, 260, ST7735_YELLOW); playSdWav1.stop(); filenumber = filenumber - 2; if (filenumber < 0) filenumber = filenumber + 4; delay(100); tft.fillRect(150, 240, 40, 20, ST7735_BLACK); tft.drawTriangle(150, 260, 170, 240, 190, 260, ST7735_YELLOW); } // read the knob position (analog input A1) knob = analogRead(A1); float vol = (float)knob / 1280.0; if(abs(knob-knobOld)>= 20) { sgtl5000_1.volume(vol); tft.fillRect(50, 100, 40, 16, ST7735_BLACK); tft.setCursor(50, 100); tft.print(vol); knobOld = knob; } }
Further Reading:
PJRC Audio Forum – Excellent source of technical information for using audio with Teensy.
ST7796 Thread on PJRC Form – This thread tracks the discussion around fixing the bug in the Teensy Audio Library and also provides alternative ways for working around the problem.
Notes:
- The female mating header is 24-pins on the Audio Tutorial Adapter while the male IDC connector is 20-pins on the Mini Platform board. This ensures that the connectors cannot accidentally be offset when they are mated since the female header is not keyed. The fit will tend to be snug by design.
Operating Voltage | 3.3V | |
Dimensions | Board outline (excluding female header) | 50.8 x 76.2mm (2.0 x 3.0″) |
Country of Origin | Designed and final assembly in USA | Manufactured in China |