Audio plus FastLED/DOTSTAR not working

Status
Not open for further replies.

agoslinski

New member
Hello,

I am working on lightsaber using Teensy 3.2 + prop shield and I have a problem playing sounds from SD card when I use FastLED or Adafruit DOTSTAR library to drive APA 102 LEDS
I tested LEDS and playing sounds in separate sketches and they work fine.
Below is the code that I am using, commenting/uncommenting indicated lines switches between working LEDS or working sound.

LEDS are connected to appropriate pads on prop shield.
SD card is connected to hardware spi pins.
I think something can be wrong with CS pin because writing something like:

Code:
 digitalWrite(SS, HIGH);
   SOUNDS.play("beep.wav"); 
   while(SOUNDS.isPlaying());
   digitalWrite(SS, LOW);
or
Code:
 digitalWrite(SS, LOW);
   SOUNDS.play("beep.wav"); 
   while(SOUNDS.isPlaying());
   digitalWrite(SS, HIGH);

does NOT disable sound.

Here is the link to my sd card adapter pinout: http://www.haoyuelectronics.com/Attachment/HY-MicroSD/HY-MicroSD-Schematic.pdf


FastLED test:
Code:
#include <SPI.h>

// SD CARD =========================
#include <SD.h>
#define CS_pin          10

// SOUND =========================
#include <Audio.h>
#include <SerialFlash.h>

#define AMP             5
#define SOUNDS_VOLUME        0.04f  
#define HUM_VOLUME           0.4f

// GUItool: begin automatically generated code
AudioPlaySdWav           HUM;     //xy=605,422
AudioPlaySdWav           SOUNDS;     //xy=628,310
AudioMixer4              MIXER;         //xy=789,380
AudioOutputAnalog        DAC;           //xy=939,296
AudioConnection          patchCord1(HUM, 0, MIXER, 1);
AudioConnection          patchCord2(SOUNDS, 0, MIXER, 0);
AudioConnection          patchCord3(MIXER, DAC);
// GUItool: end automatically generated code

// FastLED ============================================
#include <FastLED.h>
#include <SPI.h>

#define NUM_LEDS 288
#define LED_ENABLE 7
CRGB leds[NUM_LEDS];

void setup()
{
  SPI.begin();
  Serial.begin(9600);
// SD CARD =========================================================
  pinMode(SS, OUTPUT);
  digitalWrite(SS, HIGH); // deselect SD
  if(!SD.begin())//initialize SD card
  {
    while(1)
    {
      Serial.println ("Cannot access SPI Flash chip");
      delay (3000);
    }
  }
  
// AUDIO ===========================================================
  DAC.analogReference(INTERNAL); //INTERNAL OR EXTERNAL -> VOLUME
  pinMode(AMP,OUTPUT); 
  digitalWrite(AMP, HIGH); //enable Amplifier
  AudioMemory(8); // Audio connections require memory to work.
  MIXER.gain(0, SOUNDS_VOLUME); //other sounds
  MIXER.gain(1, HUM_VOLUME); //hum

// this also does not work when strip.begin below is uncommented
   digitalWrite(SS, LOW);
   SOUNDS.play("beep.wav"); 
   while(SOUNDS.isPlaying());
   digitalWrite(SS, HIGH);

// FastLED =====================================================
//  FastLED.addLeds<APA102, BGR>(leds, NUM_LEDS); // Audio stops when uncommented
  pinMode(LED_ENABLE, OUTPUT);
}

void loop()
{
// FastLED ===================================================
  for(int n = 0; n < NUM_LEDS; n++) 
  {
    leds[n].red = 5;
    leds[n].green = 0;
    leds[n].blue = 0;
    SPI.beginTransaction(SPISettings(24000000, MSBFIRST, SPI_MODE0));
    digitalWrite(LED_ENABLE, HIGH);
//    FastLED.show(); // Audio stops when uncommented
    digitalWrite(LED_ENABLE, LOW);
    SPI.endTransaction();
    delay(8);
    leds[n] = CRGB::Black;
  }
// AUDIO =====================================================
   digitalWrite(LED_ENABLE, LOW);
   digitalWrite(SS, LOW);
   SOUNDS.play("beep.wav"); 
   while(SOUNDS.isPlaying());
   digitalWrite(SS, HIGH);
   digitalWrite(LED_ENABLE, HIGH);
   delay(1000);
}

DOTSTAR test:

Code:
#include <SPI.h>

// SD CARD =========================
#include <SD.h>
#define CS_pin          10

// SOUND =========================
#include <Audio.h>
#include <SerialFlash.h>

#define AMP             5
#define SOUNDS_VOLUME        0.04f  
#define HUM_VOLUME           0.4f

// GUItool: begin automatically generated code
AudioPlaySdWav           HUM;     //xy=605,422
AudioPlaySdWav           SOUNDS;     //xy=628,310
AudioMixer4              MIXER;         //xy=789,380
AudioOutputAnalog        DAC;           //xy=939,296
AudioConnection          patchCord1(HUM, 0, MIXER, 1);
AudioConnection          patchCord2(SOUNDS, 0, MIXER, 0);
AudioConnection          patchCord3(MIXER, DAC);
// GUItool: end automatically generated code

// DOTSTAR =========================
#include <Adafruit_DotStar.h>

#define NUMPIXELS 288
#define DATAPIN 11
#define CLOCKPIN 13
#define LED_ENABLE 7

Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BRG);

int      head  = 0, tail = -10;
uint32_t color = 0x050000;

void setup()
{
  SPI.begin();
  Serial.begin(9600);
// SD CARD =========================================================
  pinMode(SS, OUTPUT);
  digitalWrite(SS, HIGH); // deselect SD
  if(!SD.begin())//initialize SD card
  {
    while(1)
    {
      Serial.println ("Cannot access SPI Flash chip");
      delay (3000);
    }
  }

// AUDIO ===========================================================
  DAC.analogReference(INTERNAL); //INTERNAL OR EXTERNAL -> VOLUME
  pinMode(AMP,OUTPUT); 
  digitalWrite(AMP, HIGH); //enable Amplifier
  AudioMemory(8); // Audio connections require memory to work.
  MIXER.gain(0, SOUNDS_VOLUME); //other sounds
  MIXER.gain(1, HUM_VOLUME); //hum

// this also does not work when strip.begin below is uncommented
   digitalWrite(SS, LOW);
   SOUNDS.play("beep.wav"); 
   while(SOUNDS.isPlaying());
   digitalWrite(SS, HIGH);

//DOTSTAR ==========================================================
  pinMode(LED_ENABLE, OUTPUT);
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE3));
  digitalWrite(LED_ENABLE, HIGH);
//  strip.begin(); // SOUNDS STOPS WORKING IF UNCOMMENTED
  strip.show();
  digitalWrite(LED_ENABLE, LOW);
  SPI.endTransaction();
}

void loop()
{
// DOTSTAR ============================================
  strip.setPixelColor(head, color); // 'On' pixel at head
  strip.setPixelColor(tail, 0);     // 'Off' pixel at tail
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE3));
  digitalWrite(LED_ENABLE, HIGH);
  strip.show();                     // Refresh strip
  delay(20);                        // Pause 20 milliseconds (~50 FPS)
  digitalWrite(LED_ENABLE, LOW);
  SPI.endTransaction();
  if(++head >= NUMPIXELS) {         // Increment head index.  Off end of strip?
    head = 0;                       //  Yes, reset head index to start
    if((color >>= 8) == 0)          //  Next color (R->G->B) ... past blue now?
      color = 0x050000;             //   Yes, reset to red
  }
  if(++tail >= NUMPIXELS) tail = 0; // Increment, reset tail index

// AUDIO =====================================================
   digitalWrite(LED_ENABLE, LOW);
   digitalWrite(SS, LOW);
   SOUNDS.play("beep.wav"); 
   while(SOUNDS.isPlaying());
   digitalWrite(SS, HIGH);
   digitalWrite(LED_ENABLE, HIGH);
   delay(1000);
}
}

Best regards
 
I moved strip.begin() and sd.begin() to loop and it works(DOTSTAR test).
That was only test program, tomorrow I will check if this solution has some impact on performance.
 
You have both LEDs and SD card on the first SPI port (pins 11/12/13)? That works with chip selects as long as you don't have audio code trying to interrupt the LEDs while they are writing, which may be what moving your begins around is doing.

If performance is still not there you can check that fastled is using transactions to properly release the SPI bus between uses
 
You have both LEDs and SD card on the first SPI port (pins 11/12/13)? That works with chip selects as long as you don't have audio code trying to interrupt the LEDs while they are writing, which may be what moving your begins around is doing.

If performance is still not there you can check that fastled is using transactions to properly release the SPI bus between uses

SD card is connected to 11/12/13 and LEDS are connected to CLK and DATA on prop shield with according to schematic are pins 11 and 13 with logic gate (AND) on the way so that You can cut communication off when using other spi devices.

If I understand You correctly, You mean that I don't need to change CS_PIN LOW/HIGH because FastLED does transaction either way ?
 
Very little testing has been done with master mode when Wire.begin(addr) is used to configure for slave mode.

It might work. Or it might not. If it does work at all, there might be possible issues with bus arbitration, which could be really frustrating random or intermittent failures. In theory this stuff is all supposed to work with I2C. But in practice, the Wire library has been tested in 2 use cases, exclusively master mode and exclusively slave mode. Mixing the 2 of going far off the well-worn path.

Using 2 separate ports is probably a much safer choice.
 
Very little testing has been done with master mode when Wire.begin(addr) is used to configure for slave mode.

It might work. Or it might not. If it does work at all, there might be possible issues with bus arbitration, which could be really frustrating random or intermittent failures. In theory this stuff is all supposed to work with I2C. But in practice, the Wire library has been tested in 2 use cases, exclusively master mode and exclusively slave mode. Mixing the 2 of going far off the well-worn path.

Using 2 separate ports is probably a much safer choice.


What do You mean by different ports, I thought that Teensy 3.2 has only one set of hardware SPI pins?
 
Along with releaseing CS the library also needs to release the internal hardware, and also not assume unchanged speed etc settings when it starts again. Have not been into fastled recently but did have some drama's some time back with it and a LCD library not setting speed correctly as they passed back and forth. That manifested as corrupted data though, not out right failure of code, which I gather was your result.
 
Status
Not open for further replies.
Back
Top