Teensy 4.0 with MAX98357A, Stumped on what could be wrong

Jinxvar

Member
Hi, I've made a simple setup with a Teensy 4.0, a MAX98357A board and a small speaker.
I've tried numerous things to get it to work, but even the simple ToneSweep does not seem to work. Searched the
forums, but either I missed what could be wrong, or a component is not working.

Tried 2 different speakers. They both give a short sound when powered, but no output after that. They both work
on a Teensy 3.2 with propshield output.
Anyone any ideas?

Code:
/* */

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>

// GUItool: begin automatically generated code
AudioOutputI2S           i2s1;           //xy=1209,399
// GUItool: end automatically generated code

AudioSynthToneSweep myEffect;
// The tone sweep goes to left and right channels
AudioConnection c1(myEffect, 0, i2s1, 0);
AudioConnection c2(myEffect, 0, i2s1, 1);

float t_ampx = 0.8;
int t_lox = 10;
int t_hix = 22000;
// Length of time for the sweep in seconds
float t_timex = 10;

#define FRAMES_PER_SECOND 70

void setup() {
  delay(500); // sanity delay

  Serial.begin(6400);
  // wait up to 2 seconds for the Serial device to become available
  long unsigned debug_start = millis ();
  while (!Serial && ((millis () - debug_start) <= 3000))
    ;

  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(2);

  if(!myEffect.play(t_ampx,t_lox,t_hix,t_timex)) {
    Serial.println("AudioSynthToneSweep - begin failed");
    while(1);
  }
  // wait for the sweep to end
  while(myEffect.isPlaying());

  // and now reverse the sweep
  if(!myEffect.play(t_ampx,t_hix,t_lox,t_timex)) {
    Serial.println("AudioSynthToneSweep - begin failed");
    while(1);
  }
  // wait for the sweep to end
  while(myEffect.isPlaying());
  Serial.println("Done");

}

void loop () {

}
 

Attachments

  • IMG_7978.jpg
    IMG_7978.jpg
    310.7 KB · Views: 62
  • IMG_7979.jpg
    IMG_7979.jpg
    295.5 KB · Views: 62
  • IMG_7977 2.jpg
    IMG_7977 2.jpg
    292.8 KB · Views: 58
Your program uses AudioOutputI2S. On Teensy 4.x, AudioOutputI2S transmits data on pin 7.

Like all audio library features, it's documented in the design tool's right side panel. Scroll down to "Hardware" for the details.


Other audio outputs do use pins 9 and 6. For example, AudioOutputI2SOct transmits 8 audio channels using 4 data pins.


As you can see in the docs, pin 9 transmits channel 5 & 6, and pin 6 transmits channels 7 & 8.
 
Hi Paul, thank you a lot! I've learned something new.
Reason why I am trying this is because I want to combine it with a propshield. I've read quite some posts, but I am still not sure
how I could combine these as pin 7 is (also) used for addressing the LED strip.
 
Maybe use AudioOutputI2S2, which transmits on pins 2, 3, 4, 33.

Hi Paul, that's also an option. However, I noticed that the Propshield uses pin2 IRQ for motion sensors (which I also use).
Is my conclusion correct that I can not make this setup work in this combination, being:
- Teensy 4.0
- Propshield (LED, motion, flashmemory)
- Max98357A for sound output through I2S (1 or 2) from Teensy 4.0
because it conflicts with either LED (pin 7) or Motion (pin 2).
Or am I missing a potential solution here?
 
Teensy 4.1 uses the same pins as Teensy 4.0.

You might need to remove 1 or more of the pins connecting between Teensy and the Prop Shield, so that Teensy pin can be connected to your I2S device. Maybe inconvenient, but far from impossible.
 
Removing pins wouldn't be an issue, but I thought that the combination would always give conflicting pins:
- Max98357A for sound output through I2S(1 or 2) from Teensy 4.0 always conflicts with either LED (pin 7) or Motion (pin 2) to communicatie with the propshield right?

How would I solve this conflict?
 
How would I solve this conflict?

One way would connect to I2S to pins 2, 3, 4 on Teensy, and remove the connection between pin 2 on Teensy and the Prop Shield.

Alternately, you could connect to the normal I2S pins and resolve the pin 7 conflict by not connecting between Teensy and Prop Shield for pin 7, and then solder a wire from Prop Shield pin 7 to some other unused pin on Teensy.
 
Thx again Paul, what a great help and support.

Ahh, so pin 2 is not needed for the motion detection from propshield? That would definitely work.
And if I would go the route of pin 7, would that mean that I have to redefine the LED communication to another pin on Teensy right?
 
Ahh, it's just a matter of defining a different pin in the script I guess. Will try that one, thx Paul!
Will report back if it has succeeded. Thank you for your patience and help, much appreciated. :)
 
Ok, got it kinda working on pin 8. As in, sound plays when I try combining sounds in the setup() section.
However, when I combine it in the loop() section, where everything comes together, I do not hear any sound.
This setup used to work with a Teensy 3.2 and Propshield sound out. So it must have something to do with the I2S output.

What I am trying to do is to keep the sound going when the led strip is on and off. But the moment the led is on, no sounds.
Does below code work for this?

Note: when I println to check if the sound is playing, it does say it is playing, but the position is always 0

Code:
/*

*/

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SerialFlash.h>
#include <FastLED.h>
#include <NXPMotionSense.h>

// GUItool: begin automatically generated code
AudioPlaySerialflashRaw  playHUMraw;     //xy=674,347
AudioPlaySerialflashRaw  playSwingRaw;   //xy=677,431
AudioPlaySerialflashRaw  playFlashRaw1;  //xy=679,388
AudioMixer4              mixer1;         //xy=979,391
AudioOutputI2S           i2s1;           //xy=1209,399
AudioConnection          patchCord1(playHUMraw, 0, mixer1, 0);
AudioConnection          patchCord2(playSwingRaw, 0, mixer1, 2);
AudioConnection          patchCord3(playFlashRaw1, 0, mixer1, 1);
AudioConnection          patchCord4(mixer1, 0, i2s1, 0);
AudioConnection          patchCord5(mixer1, 0, i2s1, 1);
// GUItool: end automatically generated code

NXPMotionSense imu;
NXPSensorFusion filter;

int motionThreshold = 2;

float lastPitch = 0,  lastHeading = 0; // lastRoll = 0,

int buttonState = HIGH;
int bladeState = 0; //0 off, 1, fading up, 2 on, 3 fading down, 4 color change
int bladeUpDownDelay = 0; // 0 no delay, 1 wait for sound to load, before led shows, or more in case of blade down
bool flashRawPlaying = 0;
int fadeStep = 0;
int fadeStepSize = 2;
int selectedColor = 0;
int lastSelectedColor = 0;
bool isAnimating = 0;
bool bladeOn = 0;
uint32_t lastDebounceTime = 0;  // the last time the output pin was toggled
uint32_t debounceDelay = 50;
int lastButtonState = HIGH;
int pendingPress = 0;
int brightStep = 0; // used to dim brightness when color changes
int brightStepSize = 20;
bool isDimming = 0;
int brightGlitch = 0; // used to make the lightsaber glitch when switching colors

//BC = Blade Color
int BCbuttonState = HIGH;
uint32_t BClastDebounceTime = 0;  // the last time the output pin was toggled
uint32_t BCdebounceDelay = 50;
int BClastButtonState = HIGH;
int BCpendingPress = 0;
//int pendingColorPress = 0;

int BCbrightness = 180;

#define COLOR_BUTTON_PIN 1
#define POWER_BUTTON_PIN 0
#define COLOR_ORDER BGR
#define CHIPSET     APA102
#define NUM_LEDS   120 // actual amount
#define DATA_PIN 11
#define CLOCK_PIN 13
#define LED_ACCESS_PIN 8 //  8 ! because I2S1 output on 7, 20 and 21
#define FLASH_CHIP_SELECT 6

#define BRIGHTNESS  100
#define FRAMES_PER_SECOND 70

int outputValue = 0;

int presetColors[] = {CRGB::Blue, CRGB::Green};
int totalPresetColors = (sizeof(presetColors) / sizeof(int));
int selectedColorIndex = 0;

int swingSounds = 4;
int lastSwingSound = swingSounds;
int clashSounds = 0;

CRGB leds[NUM_LEDS];

void setup() {
  delay(500); // sanity delay

  FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(leds, NUM_LEDS);
  selectedColor = presetColors[selectedColorIndex];
  lastSelectedColor = selectedColor;

  // initiate motion sensor
  imu.begin();
  filter.begin(100);

  pinMode(POWER_BUTTON_PIN, INPUT_PULLUP);
  pinMode(COLOR_BUTTON_PIN, INPUT_PULLUP);
  pinMode(LED_ACCESS_PIN, OUTPUT);
  digitalWrite(LED_ACCESS_PIN, LOW);

  Serial.begin(6400);
  // wait up to 2 seconds for the Serial device to become available
  long unsigned debug_start = millis ();
  while (!Serial && ((millis () - debug_start) <= 3000))
    ;

  pinMode(LED_ACCESS_PIN, OUTPUT);
  digitalWrite(LED_ACCESS_PIN, HIGH);

  // Audio connections require memory to work.
  AudioMemory(12);

  // Set initial volume
  mixer1.gain(1, 1.5f); //other sounds
  mixer1.gain(0, 1.5f); //hum

  // Start SerialFlash
  if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
    while (1)
    {
      Serial.println ("Cannot access SPI Flash chip");
      delay (3000);
    }
  }

  // test sounds >> ALL WORK in setup
  playHUMraw.play("HUM.RAW");
  playFlashRaw1.play("OPEN.RAW");
  playSwingRaw.play("SWING.RAW");
  triggerSound("SPARK.RAW");

  // clear led strip
  FastLED.clear(true);
  delay(3000);
  powerUpBlade();

}

void powerUpBlade() {
  // animate UP
  isAnimating = 1;
  bladeState = 1;
  Serial.println("Turn on blade");
  bladeOn = 1;
  bladeUpDownDelay = 1;
  triggerSound("OPEN.RAW"); // does not work!
}

void powerDownBlade() {
  //animate DOWN
  fadeStep = NUM_LEDS;
  isAnimating = 1;
  bladeState = 3;
  Serial.println("Turn off blade");
  bladeOn = 0;
  // extra delay because close sound starts later
  bladeUpDownDelay = 40;
  triggerSound("CLOSE.RAW");
  stopHum();
}

void bladeIsOn() {
  // play hum when ON
  if (!playHUMraw.isPlaying()) {
    Serial.println("Hum reload");
    startHum();
  }
  //nothing needed here unless adding animation
}

void bladeIsAnimatingUp() {
  // part of loop animation UP
  Serial.println("bladeIsAnimatingUp");
  int midpoint = NUM_LEDS / 2;
 
  int newSection = fadeStep + fadeStepSize;
  for ( int j = fadeStep; j < newSection; j++) {
    leds[j] = selectedColor;
    leds[NUM_LEDS - j] = selectedColor;
  }
 
  fadeStep = newSection;
  if (fadeStep >= midpoint + fadeStepSize) {
    fadeStep = NUM_LEDS;
    isAnimating = 0;
    bladeState = 2;
    Serial.println("blade up complete");
    startHum();
  }
}

void bladeIsAnimatingDown() {
  // part of loop animation DOWN
  //Serial.println("bladeIsAnimatingDown");
  int midpoint = NUM_LEDS / 2;
  int newSection = fadeStep - fadeStepSize;
  for ( int j = fadeStep; j > newSection; j--) {
    leds[j - midpoint] = CRGB::Black;
    leds[midpoint + NUM_LEDS - j] = CRGB::Black;
  }
 
  fadeStep = newSection;
  if (fadeStep <= midpoint - fadeStepSize) {
    fadeStep = 0;
    isAnimating = 0;
    bladeState = 0;
  }
}


void bladeIsSwitchingColor() {
  // part of loop animation UP
  Serial.println("bladeIsSwitchingColor");

  if (isDimming) {
      // dimming
      if (brightStep > 0){
        brightStep = brightStep - brightStepSize - brightStepSize;
        if (brightStep < 0){
          brightStep = 0;
        }
      }else{
        brightStep = 0;
        // when reaching off, change color
        for ( int j = 0; j < NUM_LEDS; j++) {
          leds[j] = selectedColor;
        }
        // and set dimming to off to turn on brightness again
        isDimming = 0;
        brightGlitch = 13;
      }
  }else{
    if (brightGlitch > 0){
      brightGlitch = brightGlitch - 1;
      brightStep = random(20, 80) * (brightGlitch % 3);
      //Serial.println(brightStep);
    }else{
     
      // not dimming
      if (brightStep < BCbrightness){
        brightStep = brightStep + brightStepSize;
      }else{
        brightStep = BCbrightness; // back to standard brightness
        brightGlitch = 0;
        // done with color change
        bladeState = 2;
      }
    }
  } // end if else

  //strip.setBrightness(brightStep);   // Set global brightness 0-255
}


void detectMotion() {
  float ax, ay, az;
  float gx, gy, gz;
  float mx, my, mz;
  float pitch, heading; //roll,

  if (imu.available()) {
    // Read the motion sensors
    imu.readMotionSensor(ax, ay, az, gx, gy, gz, mx, my, mz);

    // Update the SensorFusion filter
    filter.update(gx, gy, gz, ax, ay, az, mx, my, mz);

    // print the heading, pitch and roll
    // roll = filter.getRoll();
    pitch = filter.getPitch();
    heading = filter.getYaw();

    float headingDiff = abs(lastHeading - heading);
    float pitchDiff = abs(lastPitch - pitch);
    if (lastHeading != 0) {
      if (pitchDiff > motionThreshold || headingDiff > motionThreshold) {
        //cyle through swing sounds
        lastSwingSound++;
        if (lastSwingSound > swingSounds) {
          lastSwingSound = 1;
        }
        String swingFile = "SWING.RAW";
        swingFile.replace("X", lastSwingSound);
        char charBuf[50];
        swingFile.toCharArray(charBuf, 50);
        triggerSwing(charBuf);  // needs sequence to iterate through
      }
    }
    lastHeading = heading;
    lastPitch = pitch;
  }

}

void loop() {
  // Add entropy to random number generator; we use a lot of it.
  // random16_add_entropy( random() );

  //handle color selector button
  int BCreading = digitalRead(COLOR_BUTTON_PIN);

  if (BCreading != BClastButtonState) {
    // reset the debouncing timer
    BClastDebounceTime = millis();
  }

  if ((millis() - BClastDebounceTime) > BCdebounceDelay) {
    if (BCreading != BCbuttonState) {
      BCbuttonState = BCreading;

      if (BCbuttonState == HIGH && bladeState != 4) {
        // only act when button is pressed and color change not active
        nextColor();
      }
    }
  }
  BClastButtonState = BCreading;

  selectedColor = presetColors[selectedColorIndex];
  if (selectedColor != lastSelectedColor && bladeState != 0) {
    Serial.println("COLOR CHANGE");
    //Serial.println(selectedColorIndex);
    //for ( int j = 0; j < NUMPIXELS; j++) {
    //  strip.setPixelColor(j, selectedColor);
    //}
    // color change
    isDimming = 1; // start dimming
    bladeState = 4;
  }
  lastSelectedColor = selectedColor;

  //handle blade on/off

  int reading = digitalRead(POWER_BUTTON_PIN);
  //debounce
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
    }
  }
  lastButtonState = reading;

  if ( pendingPress == 1 && buttonState != LOW) {
    buttonState = HIGH;
    pendingPress = 0;
    //Serial.print("execute pending blade press");

    if (bladeOn) {
      powerDownBlade();
    } else {
      powerUpBlade();
    }
  }

  if (buttonState == LOW && !isAnimating) {
    //Serial.println("BLADE BUTTON IS PRESSED");
    pendingPress = 1;
  }
  //Serial.println("before bladeState: ");
  switch (bladeState) {
    case 0:
      //blade is off
      break;
    case 1:
      //blade is animating up
      //check if sound is playing, only then can we animate
      if (bladeUpDownDelay == 1 && playFlashRaw1.isPlaying() == 1) {
        bladeUpDownDelay = 0;
      }

      if (bladeUpDownDelay == 0) {
        bladeIsAnimatingUp();
      }
      break;
    case 2:
      //blade is on
      bladeIsOn();
      break;
    case 3:
      //blade is animating down
      //check if sound is playing, only then can we animate
      flashRawPlaying = playFlashRaw1.isPlaying();

      if (bladeUpDownDelay > 1 && flashRawPlaying == 1) {
        bladeUpDownDelay = bladeUpDownDelay - 1;
      } else if (bladeUpDownDelay == 1 && flashRawPlaying == 1) {
        bladeUpDownDelay = 0;
      }

      if (bladeUpDownDelay == 0) {
        bladeIsAnimatingDown();
      }
      break;
    case 4:
      //blade is switching color
      bladeIsSwitchingColor();
      break;
  }
 
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  digitalWrite(LED_ACCESS_PIN, HIGH);    // enable access to LEDs
  // Refresh strip
  FastLED.show();
  digitalWrite(LED_ACCESS_PIN, LOW);
  SPI.endTransaction();                // allow other libs to use SPI again

  delay(10);

  if (bladeState == 2) {
    detectMotion();
  }

}

void nextColor() {
  selectedColorIndex++;
  if (selectedColorIndex >= totalPresetColors) {
    selectedColorIndex = 0;
  }
  triggerSound("SPARK.RAW");
}
void triggerSound(const char *filename) {
  playFlashRaw1.play(filename);
}
void triggerSwing(const char *filename) {
  if (playSwingRaw.isPlaying() == 0) {
    playSwingRaw.play(filename);
    Serial.println("Start swing");
  } else {
    Serial.print("  pos: ");
    Serial.println(playSwingRaw.positionMillis());
  }
}
void startHum() {
  Serial.println("startHum");
  playHUMraw.play("HUM.RAW");
  Serial.println(playHUMraw.isPlaying());
}
void stopHum() {
  playHUMraw.stop();
}
 
Ok, did a few additional tests. If I run the loop with just playing the Hum sound over and over it works. So there must be some conflict with the other items being Motion or LED. Could it be because of the SPI perhaps?
 
Solved it eventually by skipping the use of HW SPI for the LED strips. Hooked them up to regular pins, used the DotStar library, declared the data and clock pin and all worked again.
Still find it strange it didn't work properly.

Note: also tried with soldering the LED strip to pin 26/27. It flickered just a few leds but nothing more. Also tried with slower MHz, didnt work.
If anyone still has a clue towards the future I might try it. For now it works.

Thx all!
 
Solved it eventually by skipping the use of HW SPI for the LED strips. Hooked them up to regular pins, used the DotStar library, declared the data and clock pin and all worked again.
Still find it strange it didn't work properly.

Note: also tried with soldering the LED strip to pin 26/27. It flickered just a few leds but nothing more. Also tried with slower MHz, didnt work.
If anyone still has a clue towards the future I might try it. For now it works.

Thx all!

Hi all,
I am having the same problem playing a .raw file from Flash and pulsating an LED using the SoftPWM.h library.

If we consider the following code, which is a simplification from our application (link to the Doc at the end of this message), the LED functions well and the sound doesn't work.

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
//enable LED control
#include <SoftPWM.h>

// GUItool: begin automatically generated code
AudioPlaySerialflashRaw playFlashRaw1; //xy=149,388
AudioMixer4 mixer1; //xy=445,386
AudioOutputAnalog dac1; //xy=591,379
AudioConnection patchCord1(playFlashRaw1, 0, mixer1, 0);
AudioConnection patchCord2(mixer1, dac1);
// GUItool: end automatically generated code

#define PROP_AMP_ENABLE 5
#define FLASH_CHIP_SELECT 6

void setup() {

Serial.begin(9600);

// wait up to 3 seconds for the Serial device to become available
long unsigned debug_start = millis ();
while (!Serial && ((millis () - debug_start) <= 3000))
;
Serial.println ("Start prop shield RAW player");

// Enable the amplifier on the prop shield
pinMode(PROP_AMP_ENABLE, OUTPUT);
digitalWrite(PROP_AMP_ENABLE, HIGH);

// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(8);

// Set initial volume (comment if using a potentiometer on A1 below)
mixer1.gain(0, 0.5f);

// Start SerialFlash
if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
while (1)
{
Serial.println ("Cannot access SPI Flash chip");
delay (1000);
}
}
//Set pins for LED control
delay(2000); // sanity check delay
pinMode(7, OUTPUT);
digitalWrite(7, HIGH); // enable access to LEDs
SoftPWMBegin();
// Sets the PWM value to 0 for the built-in LED (WLED).
SoftPWMSet(11, 0);
//SoftPWMSetFadeTime(11, 200, 700);
SoftPWMSetFadeTime(11, 200, 700);
}

void playFile(const char *filename)
{
Serial.print("Playing file: ");
Serial.println(filename);

// Start playing the file. This sketch continues to run while the file plays.
playFlashRaw1.play(filename);
// A brief delay for the library read RAW info
delay(5);
// Simply wait for the file to finish playing.
while (playFlashRaw1.isPlaying()) {
}
}

void loop() {
playFile("1.raw"); // filenames are always uppercase 8.3 format
delay(500);
playFile("2.raw");
delay(500);

// Turn on WLED
SoftPWMSet(11, 255);
// Wait for the fade-up and some extra delay.
delay(900);
// Turn off WLED
SoftPWMSet(11, 0);
// Wait for the fade-down, and some extra delay.
delay(900);
}



I noticed that when I run the configuration of the LED in the setup loop before the configuration of the Flash chip, the sound works and the LED doesn't, the code is the following:

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
//enable LED control
#include <SoftPWM.h>

// GUItool: begin automatically generated code
AudioPlaySerialflashRaw playFlashRaw1; //xy=149,388
AudioMixer4 mixer1; //xy=445,386
AudioOutputAnalog dac1; //xy=591,379
AudioConnection patchCord1(playFlashRaw1, 0, mixer1, 0);
AudioConnection patchCord2(mixer1, dac1);
// GUItool: end automatically generated code

#define PROP_AMP_ENABLE 5
#define FLASH_CHIP_SELECT 6

void setup() {

Serial.begin(9600);

// wait up to 3 seconds for the Serial device to become available
long unsigned debug_start = millis ();
while (!Serial && ((millis () - debug_start) <= 3000))
;
Serial.println ("Start prop shield RAW player");

// Enable the amplifier on the prop shield
pinMode(PROP_AMP_ENABLE, OUTPUT);
digitalWrite(PROP_AMP_ENABLE, HIGH);

// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(8);

// Set initial volume (comment if using a potentiometer on A1 below)
mixer1.gain(0, 0.5f);

//Set pins for LED control
delay(2000); // sanity check delay
pinMode(7, OUTPUT);
digitalWrite(7, HIGH); // enable access to LEDs
SoftPWMBegin();
// Sets the PWM value to 0 for the built-in LED (WLED).
SoftPWMSet(11, 0);
//SoftPWMSetFadeTime(11, 200, 700);
SoftPWMSetFadeTime(11, 200, 700);

// Start SerialFlash
if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
while (1)
{
Serial.println ("Cannot access SPI Flash chip");
delay (1000);
}
}

}

void playFile(const char *filename)
{
Serial.print("Playing file: ");
Serial.println(filename);

// Start playing the file. This sketch continues to run while the file plays.
playFlashRaw1.play(filename);
// A brief delay for the library read RAW info
delay(5);
// Simply wait for the file to finish playing.
while (playFlashRaw1.isPlaying()) {
}
}

void loop() {
playFile("1.raw"); // filenames are always uppercase 8.3 format
delay(500);
playFile("2.raw");
delay(500);

// Turn on WLED
SoftPWMSet(11, 255);
// Wait for the fade-up and some extra delay.
delay(900);
// Turn off WLED
SoftPWMSet(11, 0);
// Wait for the fade-down, and some extra delay.
delay(900);
}



It looks like the following code could shed some light into this problem. If we put it before or after calling the SoftPWM function it makes a difference.

// Start SerialFlash
if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
while (1)
{
Serial.println ("Cannot access SPI Flash chip");
delay (1000);
}
}



I've read that there could be a pin conflict, but I don't understand that yet...
More about our project here, feel free to remix :)

Anyone has an idea about how to resolve this issue?
 
Hi all,
I am having the same problem playing a .raw file from Flash and pulsating an LED using the SoftPWM.h library.

If we consider the following code, which is a simplification from our application (link to the Doc at the end of this message), the LED functions well and the sound doesn't work.

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
//enable LED control
#include <SoftPWM.h>

// GUItool: begin automatically generated code
AudioPlaySerialflashRaw playFlashRaw1; //xy=149,388
AudioMixer4 mixer1; //xy=445,386
AudioOutputAnalog dac1; //xy=591,379
AudioConnection patchCord1(playFlashRaw1, 0, mixer1, 0);
AudioConnection patchCord2(mixer1, dac1);
// GUItool: end automatically generated code

#define PROP_AMP_ENABLE 5
#define FLASH_CHIP_SELECT 6

void setup() {


Serial.begin(9600);

// wait up to 3 seconds for the Serial device to become available
long unsigned debug_start = millis ();
while (!Serial && ((millis () - debug_start) <= 3000))
;

Serial.println ("Start prop shield RAW player");

// Enable the amplifier on the prop shield
pinMode(PROP_AMP_ENABLE, OUTPUT);
digitalWrite(PROP_AMP_ENABLE, HIGH);

// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(8);

// Set initial volume (comment if using a potentiometer on A1 below)
mixer1.gain(0, 0.5f);

// Start SerialFlash
if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
while (1)
{

Serial.println ("Cannot access SPI Flash chip");
delay (1000);
}

}
//Set pins for LED control
delay(2000); // sanity check delay
pinMode(7, OUTPUT);
digitalWrite(7, HIGH); // enable access to LEDs
SoftPWMBegin();
// Sets the PWM value to 0 for the built-in LED (WLED).
SoftPWMSet(11, 0);
//SoftPWMSetFadeTime(11, 200, 700);
SoftPWMSetFadeTime(11, 200, 700);
}

void playFile(const char *filename)
{

Serial.print("Playing file: ");
Serial.println(filename);

// Start playing the file. This sketch continues to run while the file plays.
playFlashRaw1.play(filename);
// A brief delay for the library read RAW info
delay(5);
// Simply wait for the file to finish playing.
while (playFlashRaw1.isPlaying()) {
}
}

void loop() {

playFile("1.raw"); // filenames are always uppercase 8.3 format
delay(500);
playFile("2.raw");
delay(500);

// Turn on WLED
SoftPWMSet(11, 255);
// Wait for the fade-up and some extra delay.
delay(900);
// Turn off WLED
SoftPWMSet(11, 0);
// Wait for the fade-down, and some extra delay.
delay(900);
}



I noticed that when I run the configuration of the LED in the setup loop before the configuration of the Flash chip, the sound works and the LED doesn't, the code is the following:

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
//enable LED control
#include <SoftPWM.h>

// GUItool: begin automatically generated code
AudioPlaySerialflashRaw playFlashRaw1; //xy=149,388
AudioMixer4 mixer1; //xy=445,386
AudioOutputAnalog dac1; //xy=591,379
AudioConnection patchCord1(playFlashRaw1, 0, mixer1, 0);
AudioConnection patchCord2(mixer1, dac1);
// GUItool: end automatically generated code

#define PROP_AMP_ENABLE 5
#define FLASH_CHIP_SELECT 6

void setup() {


Serial.begin(9600);

// wait up to 3 seconds for the Serial device to become available
long unsigned debug_start = millis ();
while (!Serial && ((millis () - debug_start) <= 3000))
;

Serial.println ("Start prop shield RAW player");

// Enable the amplifier on the prop shield
pinMode(PROP_AMP_ENABLE, OUTPUT);
digitalWrite(PROP_AMP_ENABLE, HIGH);

// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(8);

// Set initial volume (comment if using a potentiometer on A1 below)
mixer1.gain(0, 0.5f);

//Set pins for LED control
delay(2000); // sanity check delay
pinMode(7, OUTPUT);
digitalWrite(7, HIGH); // enable access to LEDs
SoftPWMBegin();
// Sets the PWM value to 0 for the built-in LED (WLED).
SoftPWMSet(11, 0);
//SoftPWMSetFadeTime(11, 200, 700);
SoftPWMSetFadeTime(11, 200, 700);

// Start SerialFlash

if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
while (1)
{

Serial.println ("Cannot access SPI Flash chip");
delay (1000);
}

}
}

void playFile(const char *filename)
{

Serial.print("Playing file: ");
Serial.println(filename);

// Start playing the file. This sketch continues to run while the file plays.
playFlashRaw1.play(filename);
// A brief delay for the library read RAW info
delay(5);
// Simply wait for the file to finish playing.
while (playFlashRaw1.isPlaying()) {
}
}

void loop() {

playFile("1.raw"); // filenames are always uppercase 8.3 format
delay(500);
playFile("2.raw");
delay(500);

// Turn on WLED
SoftPWMSet(11, 255);
// Wait for the fade-up and some extra delay.
delay(900);
// Turn off WLED
SoftPWMSet(11, 0);
// Wait for the fade-down, and some extra delay.
delay(900);
}



It looks like the following code could shed some light into this problem. If we put it before or after calling the SoftPWM function it makes a difference.

// Start SerialFlash
if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
while (1)
{

Serial.println ("Cannot access SPI Flash chip");
delay (1000);
}

}


I've read that there could be a pin conflict, but I don't understand that yet...
More about our project here, feel free to remix :)

Anyone has an idea about how to resolve this issue?
Hi all, I wonder is anyone has had a chance to look at this ...
 
Your program has AudioOutputAnalog. That can't possibly work with MAX98357 which needs I2S digital data. You need to use AudioOutputI2S (docs on the right side, scroll down to "Hardware"). Notice the pins needed for connection are different for Teensy 4.x and Teensy 3.x.

If this doesn't solve your problem, please clearly say which Teensy you're using, which MAX98357 board you have (or if DIY, show us the design), and most important, please show photos of how you actually connected the wires!

MAX98357 definitely does work if the wires are connected properly and AudioOutputI2S is used with proper code. If you show us the wiring and code, maybe we can spot what's wrong (if just changing AudioOutputAnalog to AudioOutputI2S doesn't magically fix everything).
 
Your program has AudioOutputAnalog. That can't possibly work with MAX98357 which needs I2S digital data. You need to use AudioOutputI2S (docs on the right side, scroll down to "Hardware"). Notice the pins needed for connection are different for Teensy 4.x and Teensy 3.x.

If this doesn't solve your problem, please clearly say which Teensy you're using, which MAX98357 board you have (or if DIY, show us the design), and most important, please show photos of how you actually connected the wires!

MAX98357 definitely does work if the wires are connected properly and AudioOutputI2S is used with proper code. If you show us the wiring and code, maybe we can spot what's wrong (if just changing AudioOutputAnalog to AudioOutputI2S doesn't magically fix everything).

Hi Paul,
I don't know if your message is a reply to my previous message. I suppose so since you mentioned AudioOutputAnalog.
I am using a Teensy 3.2 and a ProShield, probably the same as described here.
The audio and the LED control work very well separately, I tested them before the integration.
The layout and the code are all described in this doc. Actually, you can see what pins I used in the code, for the wire connections, I just placed the PropShield on top of the Teensy, didn't mess with the pins.
Again, controlling the LED using the SoftPWM.h library and playing sound file (raw format) from flask memory work well when executed separately.
 
I am using a Teensy 3.2 and a ProShield, probably the same as described here.

I answered about MAX98357 because you wrote "I am having the same problem", and so far this thread was only about MAX98357. Maybe I missed a previous message where you said which hardware you were using?

Looking at your code again, I see you seem to be using pin 11 with SoftPWM. But Prop Shield needs pin 11 for SPI to access the flash memory chip. You should choose a different pin which doesn't conflict.
 
Back
Top