Hello-
First post here. I have a problem with rapid ticking on top of a WAV being played, listening with earbuds through the audio plug of a Teensy soundboard. Equipment: Teensy 4, Audio Board Rev. D, I2C OLED screen, Neopixel 8x5 matrix (with 74AHCT125 level shifter). The Teensy is powered by USB from a dock, Neopixels are powered by an Adafruit 5V power supply. Grounds are tied together.
The project is a light board like at the end of Close Encounters. The Teensy reads a WAV off the micro-SD, plays the audio through the earphone jack on the audio board, calculates the FFT of the sound, displays the FFT on a 1.3" OLED monitor, and maps the FFT onto the Neopixel matrix. Though I'm pretty new with Arduinos and brand new with Teensy, the code works, with one little problem.
When I was building the code, up through computing and displaying the FFT on the OLED, the sound through the earphones was perfect. However, a problem with the audio showed up when I introduced the Neopixels. When I'm using the Neopixels, there's a rapid ticking that I think is connected to the Neopixel updating; putting in a delay after the updating (delaying the next run through the loop that assigns brightnesses and updates the OLED) results in a change to the ticking frequency (greater delay means more time between ticks). Ticking is there with a small powered speaker as well, so it's not just the earphones.
I'd like to be able to get rid of the ticking. Not sure what I'm doing wrong, if the problem is in the code or if I'm missing some component in the circuit. I don't have any resistors or capacitors in the circuit (except for one in the power supply line) and maybe I need to put some somewhere, but I don't know where to start on that.
Thank you for whatever ideas you have.
First post here. I have a problem with rapid ticking on top of a WAV being played, listening with earbuds through the audio plug of a Teensy soundboard. Equipment: Teensy 4, Audio Board Rev. D, I2C OLED screen, Neopixel 8x5 matrix (with 74AHCT125 level shifter). The Teensy is powered by USB from a dock, Neopixels are powered by an Adafruit 5V power supply. Grounds are tied together.
The project is a light board like at the end of Close Encounters. The Teensy reads a WAV off the micro-SD, plays the audio through the earphone jack on the audio board, calculates the FFT of the sound, displays the FFT on a 1.3" OLED monitor, and maps the FFT onto the Neopixel matrix. Though I'm pretty new with Arduinos and brand new with Teensy, the code works, with one little problem.
When I was building the code, up through computing and displaying the FFT on the OLED, the sound through the earphones was perfect. However, a problem with the audio showed up when I introduced the Neopixels. When I'm using the Neopixels, there's a rapid ticking that I think is connected to the Neopixel updating; putting in a delay after the updating (delaying the next run through the loop that assigns brightnesses and updates the OLED) results in a change to the ticking frequency (greater delay means more time between ticks). Ticking is there with a small powered speaker as well, so it's not just the earphones.
I'd like to be able to get rid of the ticking. Not sure what I'm doing wrong, if the problem is in the code or if I'm missing some component in the circuit. I don't have any resistors or capacitors in the circuit (except for one in the power supply line) and maybe I need to put some somewhere, but I don't know where to start on that.
Thank you for whatever ideas you have.
Code:
//
//Based mainly on:
// 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
//
//
#include <Adafruit_NeoPixel.h> //For the Neopixels
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// OLED routines here
#include <Adafruit_GFX.h> // graphics library for display
#include <Adafruit_SSD1306.h> // SSD1306 OLED display library
#define OLED_RESET 5 // OLED library likes to see this but it isn't used here with I2C, changed to deconflict with sound board
#define OLED_ADDR 0x3D // OLED I2C address
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // create instance of OLED display
byte ylim = 60; //sets vertical pixel limit of histogram
//below, do Neopixel setup, to CE3K light board colors
#define PIN 6 // Which pin on the Arduino is connected to the NeoPixels?
#define NUMPIXELS 40 //There are 40 Neopixels on the board
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
//set up color mapping for the Neopixels
int redc[] ={255,255,175,50,0,96,168,218,255,255,150,25,0,128,178,228,255,255,125,0,0,138,288,238,255,230,100,0,32,148,198,248,255,200,75,0,64,158,208,255};
int greenc[]={128,218,255,255,102,0,0,0,146,236,255,255,51,0,0,0,164,255,255,255,0,0,0,0,182,255,255,204,0,0,0,0,200,255,255,153,0,0,0,0};
int bluec[]={0,0,0,0,153,255,155,55,0,0,0,0,202,255,135,35,0,0,0,0,255,235,115,15,0,0,0,51,255,205,95,0,0,0,0,102,255,185,75,0};
int MAXBRIGHT=10;
//for storing the Neopixel brightnesses
int reds[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int greens[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int blues[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//
//next code initializes many things, taken from the graphical audio configurator
AudioPlaySdWav playWav1;
AudioMixer4 mixer1;
AudioOutputI2S audioOutput; //plays through 3.5mm jack
AudioControlSGTL5000 sgtl5000_1;
AudioAnalyzeFFT1024 fft1024_1; //xy=562,298
AudioConnection patchCord1(playWav1, 0, audioOutput, 0);
AudioConnection patchCord2(playWav1, 1, audioOutput, 1);
AudioConnection patchCord3(playWav1, 0, mixer1, 0);
AudioConnection patchCord4(playWav1, 1, mixer1, 1);
AudioConnection patchCord5(mixer1, fft1024_1);
// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7 //changing these from their defaults to deconflict with the I2C display
#define SDCARD_SCK_PIN 14 //changing these from their defaults to deconflict with the I2C display
void setup() {
//OLED setup information
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); // initialize OLED display
display.clearDisplay(); // blank the display
display.setTextSize(1); // configure text properties
display.setTextColor(WHITE);
//Neopixel setup information
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pixels.clear(); // Set all pixel colors to 'off'
Serial.begin(9600);
AudioMemory(100);
sgtl5000_1.enable();
sgtl5000_1.volume(0.2);
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!(SD.begin(SDCARD_CS_PIN))) {
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
mixer1.gain(0, 2.0);
mixer1.gain(1, 2.0);
mixer1.gain(2, 0.0);
mixer1.gain(3, 0.0);
// Uncomment one these to try other window functions
fft1024_1.windowFunction(AudioWindowHanning1024);
// fft1024_1.windowFunction(NULL);
// fft1024_1.windowFunction(AudioWindowBartlett1024);
// fft1024_1.windowFunction(AudioWindowFlattop1024);
delay(1000);
// playWav1.play("DIALOGUE.WAV");
Serial.print("Finishing setup");
Serial.println();
}
void loop() { // begin the master loop
pixels.clear(); // Set all Neopixels to 'off'
playWav1.play("DIALOGUE.WAV"); // "Play the five tones..."
display.clearDisplay(); // clear the OLED display
display.display(); // send the data to the OLED display
delay(10); // give time for the music to start
while (playWav1.isPlaying()) { //while the music is playing, compute and display the FFT
// uncomment these lines if you audio shield
// has the optional volume pot soldered
//float vol = analogRead(15);
//vol = vol / 1024;
// sgtl5000_1.volume(vol)
// print Fourier Transform data to the Arduino Serial Monitor and OLED
if (fft1024_1.available()) {
display.clearDisplay(); // clear the OLED display
display.setCursor(0, 0); // set cursor to top left corner of the display
display.print("Audio Spectrum"); // print a header on the top row of the display
// Serial.print("FFT: ");
for (int i=0; i<40; i++) { // 0-60 --> DC to 23409 Hz at 39 Hz/bin
float n = fft1024_1.read(i);
// printNumber((n));
display.drawLine(i*2, ylim, i*2, ylim - (512*n), WHITE);
// calculate the brightnesses of the pixels
reds[i]=redc[i]*((512*n)/64)*MAXBRIGHT/255;
greens[i]=greenc[i]*((512*n)/64)*MAXBRIGHT/255;
blues[i]=bluec[i]*((512*n)/64)*MAXBRIGHT/255;
//below are sanity checks for LED brightness
if(reds[i]>=250) {
reds[i]=250;
}
if(greens[i]>=250) {
greens[i]=250;
}
if(blues[i]>=250) {
blues[i]=250;
}
pixels.setPixelColor(i, pixels.Color(reds[i], greens[i], blues[i]));
}
}
// Serial.println();
display.display(); //send the FFT data to the OLED display
pixels.show(); // Send the updated pixel colors to the Neopixels
} //This loop finishes when the music stops; then the master loop repeats, restarting the music
}
void printNumber(float n) { //this function sets up the format for printing output to the serial line
if (n >= 0.003) {
Serial.print(n, 3);
Serial.print(" ");
} else {
Serial.print(" - "); // don't print "0.00"
}
}