Itsy Bitsy M0 Express + Soundboard Help

Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
BH32794
 
Posts: 63
Joined: Mon Nov 13, 2017 8:15 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by BH32794 »

What I have done is powered both the itsy bitsy and sound board with separate usb from my computer.

That powers both, but still nothing in the serial monitor.

Will there be any issues if I power the itsy through usb while having the battery in the backpack inserted? I think I tried this once, but there was a weird noise coming from my speaker.

User avatar
BH32794
 
Posts: 63
Joined: Mon Nov 13, 2017 8:15 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by BH32794 »

I also just tried the following:

Itsy Bitsy plugged to computer via USB with battery in the backpack for the soundboard.

Still receiving "not found" on the soundboard.

User avatar
BH32794
 
Posts: 63
Joined: Mon Nov 13, 2017 8:15 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by BH32794 »

Ok, I got the soundboard library example sketch working through serial monitor. I didn't have an RST pin connected. Didn't think I needed it as I wasn't going to reset anything. But there you have it :)

Ok, now that I have this going, how do I trigger the sound via a button rather than my keyboard?

Serial1.print(filename); ?

And do I still need all of the soundboard example code in my sketch?

User avatar
adafruit_support_carter
 
Posts: 29150
Joined: Tue Nov 29, 2016 2:45 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by adafruit_support_carter »

And do I still need all of the soundboard example code in my sketch?
No, just the parts that are driving the sound board in the way you want. Like which menu option are you using? Can just use the code snippet for that menu entry.

How to read buttons:
https://learn.adafruit.com/adafruit-ard ... tal-inputs

User avatar
BH32794
 
Posts: 63
Joined: Mon Nov 13, 2017 8:15 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by BH32794 »

I’m familiar with how buttons/triggers work, but my issue that I’m still having is having the button trigger the sound through serial.

All I want the soundboard to do is play sounds and stop sounds when triggered/Untriggered. That’s it.

Are you able to tell me directly the code, not show me the example, of what I need to do this?

User avatar
adafruit_support_carter
 
Posts: 29150
Joined: Tue Nov 29, 2016 2:45 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by adafruit_support_carter »

Which menu option do you want to occur when a button is pressed?

User avatar
BH32794
 
Posts: 63
Joined: Mon Nov 13, 2017 8:15 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by BH32794 »

I want the soundboard to play sounds when the button is pressed.

Looking at the example, it's either case "#" or case "P"

Code: Select all

case '#': {
      Serial.print("Enter track #");
      uint8_t n = readnumber();

      Serial.print("\nPlaying track #"); Serial.println(n);
      if (! sfx.playTrack((uint8_t)n) ) {
        Serial.println("Failed to play track?");
      }
      break;
    }
    
    case 'P': {
      Serial.print("Enter track name (full 12 character name!) >");
      char name[20];
      readline(name, 20);

      Serial.print("\nPlaying track \""); Serial.print(name); Serial.print("\"");
      if (! sfx.playTrack(name) ) {
        Serial.println("Failed to play track?");
      }
      break;
   }
Then, when the button is released, I want the sounds to stop.

Code: Select all

case 'q': {
      Serial.println("Stopping...");
      if (! sfx.stop() ) Serial.println("Failed to stop");
      break;
   }  

User avatar
adafruit_support_carter
 
Posts: 29150
Joined: Tue Nov 29, 2016 2:45 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by adafruit_support_carter »

For using #, you'd also need a way to specify a track number, then:

Code: Select all

if (button_pressed()) {
  sfx.playTrack(track_number);
  while (button_pressed());
  sfx.stop();
}
For the P option, you'd need a way to specify the name, then:

Code: Select all

if (button_pressed()) {
  sfx.playTrack(track_name);
  while (button_pressed());
  sfx.stop();
}
where button_pressed() is a function that reads the digital pin attached to the button and returns true if pressed, otherwise false.

User avatar
BH32794
 
Posts: 63
Joined: Mon Nov 13, 2017 8:15 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by BH32794 »

Minor success. I've got the sound to play, but the trigger doesn't work.

I defined the sound names in the initializing, and then can call on them with sfx.playTrack. However, my checking of the button doesn't work.

Code: Select all



#include "Adafruit_Soundboard.h"
#include <Adafruit_NeoPixel.h>

#define PIXEL_PIN     5   // Pin connected to neo pixels
#define FIREPIN       7   // Fire button 
#define PIXEL_COUNT   30  // Count of neo pixels
#define SWITCHPIN1    15  // Analog
#define SWITCHPIN2    16  // Analog
#define SWITCHPIN3    17  // Analog
#define SWITCHPIN4    18  // Analog

// Choose any two pins that can be used with SoftwareSerial to RX & TX
#define SFX_TX  1
#define SFX_RX  0
#define SFX_RST 2

Adafruit_Soundboard sfx = Adafruit_Soundboard(&Serial1, NULL, SFX_RST);

#define NUM_SOUNDS 5
// The names of the found files.
// Note that they are 8 characters followed by a 3 character file
// type (.OGG or .WAV). Spaces are inserted to make up the
// 8 characters as needed.
char *soundName[NUM_SOUNDS] = {
  "EWOKHORNWAV",//0
  "LOCKLOADWAV",//1
  "PRIMARY1WAV",//2
  "STUNGUN2WAV",//3
  "BLASTER3WAV" //4
};


int buttonState = 0;


Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);



void setup() {
  
Serial1.begin(9600);
Serial.println("Adafruit Sound Board!");
  
  if (!sfx.reset()) {
    Serial.println("Not found");
    while (1);
  }
  Serial.println("SFX board found");


pinMode(FIREPIN, INPUT_PULLUP);
pinMode(SWITCHPIN1, INPUT_PULLUP);
pinMode(SWITCHPIN2, INPUT_PULLUP);
pinMode(SWITCHPIN3, INPUT_PULLUP);
pinMode(SWITCHPIN4, INPUT_PULLUP);

strip.begin();
  strip.show();

sfx.playTrack(soundName[0]);

delay(4000);
}



void loop() {

uint8_t  i;
  
buttonState = digitalRead(FIREPIN);

if (buttonState = LOW) { 

sfx.playTrack(soundName[3]);
  while (buttonState=HIGH);
  sfx.stop();

  animate_gradient_fill(strip,         
                      100,0,0,
                      255, 0, 0,
                      50);
  animate_gradient_fill(strip,         
                    230,0,0,
                      128, 0, 0,
                      100);
  animate_gradient_fill(strip,         
                      128, 0, 0,
                      255, 0, 0,
                      200);
  animate_gradient_fill(strip,         
                      255, 0, 0,
                      20, 0, 0,
                      150);
  animate_gradient_fill(strip,         
                      20, 0, 0,
                      0, 0, 0,
                      150);

}
  
else {   
      strip.setPixelColor(i, 0,0,0); //Button not pressed, turn off pixels
      strip.show(); //Show no pixels
      sfx.stop();
      }
              
  





  
  
  
//////////////////Soundboard Stuff/////////////////////  
  
  flushInput();
  
  Serial.println(F("What would you like to do?"));
  Serial.println(F("[r] - reset"));
  Serial.println(F("[+] - Vol +"));
  Serial.println(F("[-] - Vol -"));
  Serial.println(F("[L] - List files"));
  Serial.println(F("[P] - play by file name"));
  Serial.println(F("[#] - play by file number"));
  Serial.println(F("[=] - pause playing"));
  Serial.println(F("[>] - unpause playing"));
  Serial.println(F("[q] - stop playing"));
  Serial.println(F("[t] - playtime status"));
  Serial.println(F("> "));
  
  while (!Serial.available());
  char cmd = Serial.read();
  
  flushInput();
  
  switch (cmd) {
    case 'r': {
      if (!sfx.reset()) {
        Serial.println("Reset failed");
      }
      break; 
    }
    
    case 'L': {
      uint8_t files = sfx.listFiles();
    
      Serial.println("File Listing");
      Serial.println("========================");
      Serial.println();
      Serial.print("Found "); Serial.print(files); Serial.println(" Files");
      for (uint8_t f=0; f<files; f++) {
        Serial.print(f); 
        Serial.print("\tname: "); Serial.print(sfx.fileName(f));
        Serial.print("\tsize: "); Serial.println(sfx.fileSize(f));
      }
      Serial.println("========================");
      break; 
    }
    
    case '#': {
      Serial.print("Enter track #");
      uint8_t n = readnumber();

      Serial.print("\nPlaying track #"); Serial.println(n);
      if (! sfx.playTrack((uint8_t)n) ) {
        Serial.println("Failed to play track?");
      }
      break;
    }
    
    case 'P': {
      Serial.print("Enter track name (full 12 character name!) >");
      char name[20];
      readline(name, 20);

      Serial.print("\nPlaying track \""); Serial.print(name); Serial.print("\"");
      if (! sfx.playTrack(name) ) {
        Serial.println("Failed to play track?");
      }
      break;
   }

   case '+': {
      Serial.println("Vol up...");
      uint16_t v;
      if (! (v = sfx.volUp()) ) {
        Serial.println("Failed to adjust");
      } else {
        Serial.print("Volume: "); Serial.println(v);
      }
      break;
   }

   case '-': {
      Serial.println("Vol down...");
      uint16_t v;
      if (! (v=sfx.volDown()) ) {
        Serial.println("Failed to adjust");
      } else { 
        Serial.print("Volume: "); 
        Serial.println(v);
      }
      break;
   }
   
   case '=': {
      Serial.println("Pausing...");
      if (! sfx.pause() ) Serial.println("Failed to pause");
      break;
   }
   
   case '>': {
      Serial.println("Unpausing...");
      if (! sfx.unpause() ) Serial.println("Failed to unpause");
      break;
   }
   
   case 'q': {
      Serial.println("Stopping...");
      if (! sfx.stop() ) Serial.println("Failed to stop");
      break;
   }  

   case 't': {
      Serial.print("Track time: ");
      uint32_t current, total;
      if (! sfx.trackTime(&current, &total) ) Serial.println("Failed to query");
      Serial.print(current); Serial.println(" seconds");
      break;
   }  

   case 's': {
      Serial.print("Track size (bytes remaining/total): ");
      uint32_t remain, total;
      if (! sfx.trackSize(&remain, &total) ) 
        Serial.println("Failed to query");
      Serial.print(remain); Serial.print("/"); Serial.println(total); 
      break;
   }  

  }





  
} /////END LOOP



/************************ MENU HELPERS ***************************/

void flushInput() {
  // Read all available serial input to flush pending data.
  uint16_t timeoutloop = 0;
  while (timeoutloop++ < 40) {
    while(Serial1.available()) {
      Serial1.read();
      timeoutloop = 0;  // If char was received reset the timer
    }
    delay(1);
  }
}

char readBlocking() {
  while (!Serial.available());
  return Serial.read();
}

uint16_t readnumber() {
  uint16_t x = 0;
  char c;
  while (! isdigit(c = readBlocking())) {
    //Serial.print(c);
  }
  Serial.print(c);
  x = c - '0';
  while (isdigit(c = readBlocking())) {
    Serial.print(c);
    x *= 10;
    x += c - '0';
  }
  return x;
}

uint8_t readline(char *buff, uint8_t maxbuff) {
  uint16_t buffidx = 0;
  
  while (true) {
    if (buffidx > maxbuff) {
      break;
    }

    if (Serial.available()) {
      char c =  Serial.read();
      //Serial.print(c, HEX); Serial.print("#"); Serial.println(c);

      if (c == '\r') continue;
      if (c == 0xA) {
        if (buffidx == 0) {  // the first 0x0A is ignored
          continue;
        }
        buff[buffidx] = 0;  // null term
        return buffidx;
      }
      buff[buffidx] = c;
      buffidx++;
    }
  }
  buff[buffidx] = 0;  // null term
  return buffidx;
}
/************************ MENU HELPERS ***************************/


/////////////////////////NEOPIXEL STUFF///////////////////////////

float lerp(float x, float x0, float x1, float y0, float y1)
{
  // Clamp x within x0 and x1 bounds.
  x = x > x1 ? x1 : x;
  x = x < x0 ? x0 : x;
  // Calculate linear interpolation of y value.
  return y0 + (y1-y0)*((x-x0)/(x1-x0));
}

// Get the color of a pixel within a smooth gradient of two colors.
uint32_t color_gradient(uint8_t start_r, // Starting R,G,B color
                        uint8_t start_g,
                        uint8_t start_b, 
                        uint8_t end_r,   // Ending R,G,B color
                        uint8_t end_g,
                        uint8_t end_b,
                        float pos)       // Position along gradient, should be a value 0 to 1.0
{
  // Interpolate R,G,B values and return them as a color.  
  uint8_t red   = (uint8_t) lerp(pos, 0.0, 1.0, start_r, end_r);
  uint8_t green = (uint8_t) lerp(pos, 0.0, 1.0, start_g, end_g);
  uint8_t blue  = (uint8_t) lerp(pos, 0.0, 1.0, start_b, end_b);
  return Adafruit_NeoPixel::Color(red, green, blue);
}

// Set all pixels to the specified color.
void fill_pixels(Adafruit_NeoPixel& pixels, uint32_t color)
{
  for (int i=0; i < pixels.numPixels(); ++i) {
    pixels.setPixelColor(i, color);
  }
  strip.show();
}

void animate_gradient_fill(Adafruit_NeoPixel& pixels, // NeoPixel strip/loop/etc.
                           uint8_t start_r,           // Starting R,G,B color
                           uint8_t start_g,
                           uint8_t start_b, 
                           uint8_t end_r,             // Ending R,G,B color
                           uint8_t end_g,
                           uint8_t end_b,
                           int duration_ms)           // Total duration of animation, in milliseconds
{
  unsigned long start = millis();
  // Display start color.
  fill_pixels(pixels, Adafruit_NeoPixel::Color(start_r, start_g, start_b));
  // Main animation loop.
  unsigned long delta = millis() - start;
  while (delta < duration_ms) {
    // Calculate how far along we are in the duration as a position 0...1.0
    float pos = (float)delta / (float)duration_ms;
    // Get the gradient color and fill all the pixels with it.
    uint32_t color = color_gradient(start_r, start_g, start_b, end_r, end_g, end_b, pos);
    fill_pixels(pixels, color);
    // Update delta and repeat.
    delta = millis() - start;
  }
  // Display end color.
  fill_pixels(pixels, Adafruit_NeoPixel::Color(end_r, end_g, end_b));
}


User avatar
adafruit_support_carter
 
Posts: 29150
Joined: Tue Nov 29, 2016 2:45 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by adafruit_support_carter »

Probably never seeing HIGH here and going straight to stop:

Code: Select all

    if (buttonState = LOW) {

    sfx.playTrack(soundName[3]);
      while (buttonState=HIGH);
      sfx.stop();

User avatar
BH32794
 
Posts: 63
Joined: Mon Nov 13, 2017 8:15 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by BH32794 »

I've tried commenting out:

Code: Select all

 while (buttonState=HIGH);
  sfx.stop();
And it doesn't change anything.

User avatar
adafruit_support_carter
 
Posts: 29150
Joined: Tue Nov 29, 2016 2:45 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by adafruit_support_carter »

This works as expected in non button reading code?

Code: Select all

    sfx.playTrack(soundName[3]);
Can try adding some serial prints to sanity check the logic.

Code: Select all

    if (buttonState = LOW) {
    Serial.println("Playing track.");
    sfx.playTrack(soundName[3]);
    Serial.println("Reading button.");
      while (buttonState=HIGH);
    Serial.println("Stopping track.");
      sfx.stop();

User avatar
BH32794
 
Posts: 63
Joined: Mon Nov 13, 2017 8:15 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by BH32794 »

Hmmm....by commenting out the if statement for button, soundname 3 still does not play. The lights will flash once.

Code: Select all



#include "Adafruit_Soundboard.h"
#include <Adafruit_NeoPixel.h>

#define PIXEL_PIN     5   // Pin connected to neo pixels
#define FIREPIN       7   // Fire button 
#define PIXEL_COUNT   30  // Count of neo pixels
#define SWITCHPIN1    15  // Analog
#define SWITCHPIN2    16  // Analog
#define SWITCHPIN3    17  // Analog
#define SWITCHPIN4    18  // Analog

// Choose any two pins that can be used with SoftwareSerial to RX & TX
#define SFX_TX  1
#define SFX_RX  0
#define SFX_RST 2

Adafruit_Soundboard sfx = Adafruit_Soundboard(&Serial1, NULL, SFX_RST);

#define NUM_SOUNDS 5
// The names of the found files.
// Note that they are 8 characters followed by a 3 character file
// type (.OGG or .WAV). Spaces are inserted to make up the
// 8 characters as needed.
char *soundName[NUM_SOUNDS] = {
  "EWOKHORNWAV",//0
  "LOCKLOADWAV",//1
  "PRIMARY1WAV",//2
  "STUNGUN2WAV",//3
  "BLASTER3WAV" //4
};


int buttonState = 0;


Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);



void setup() {
  
Serial1.begin(9600);
Serial.println("Adafruit Sound Board!");
  
  if (!sfx.reset()) {
    Serial.println("Not found");
    while (1);
  }
  Serial.println("SFX board found");


pinMode(FIREPIN, INPUT_PULLUP);
pinMode(SWITCHPIN1, INPUT_PULLUP);
pinMode(SWITCHPIN2, INPUT_PULLUP);
pinMode(SWITCHPIN3, INPUT_PULLUP);
pinMode(SWITCHPIN4, INPUT_PULLUP);

strip.begin();
  strip.show();

sfx.playTrack(soundName[0]);

delay(4000);
}



void loop() {

uint8_t  i;
  
//buttonState = digitalRead(FIREPIN);
//
//if (buttonState = LOW) { 

sfx.playTrack(soundName[3]);
//  while (buttonState=HIGH);
//  sfx.stop();

  animate_gradient_fill(strip,         
                      100,0,0,
                      255, 0, 0,
                      50);
  animate_gradient_fill(strip,         
                    230,0,0,
                      128, 0, 0,
                      100);
  animate_gradient_fill(strip,         
                      128, 0, 0,
                      255, 0, 0,
                      200);
  animate_gradient_fill(strip,         
                      255, 0, 0,
                      20, 0, 0,
                      150);
  animate_gradient_fill(strip,         
                      20, 0, 0,
                      0, 0, 0,
                      150);

//}
  
//else {   
//      strip.setPixelColor(i, 0,0,0); //Button not pressed, turn off pixels
//      strip.show(); //Show no pixels
//      sfx.stop();
//      }
              
  





  
  
  
//////////////////Soundboard Stuff/////////////////////  
  
  flushInput();
  
  Serial.println(F("What would you like to do?"));
  Serial.println(F("[r] - reset"));
  Serial.println(F("[+] - Vol +"));
  Serial.println(F("[-] - Vol -"));
  Serial.println(F("[L] - List files"));
  Serial.println(F("[P] - play by file name"));
  Serial.println(F("[#] - play by file number"));
  Serial.println(F("[=] - pause playing"));
  Serial.println(F("[>] - unpause playing"));
  Serial.println(F("[q] - stop playing"));
  Serial.println(F("[t] - playtime status"));
  Serial.println(F("> "));
  
  while (!Serial.available());
  char cmd = Serial.read();
  
  flushInput();
  
  switch (cmd) {
    case 'r': {
      if (!sfx.reset()) {
        Serial.println("Reset failed");
      }
      break; 
    }
    
    case 'L': {
      uint8_t files = sfx.listFiles();
    
      Serial.println("File Listing");
      Serial.println("========================");
      Serial.println();
      Serial.print("Found "); Serial.print(files); Serial.println(" Files");
      for (uint8_t f=0; f<files; f++) {
        Serial.print(f); 
        Serial.print("\tname: "); Serial.print(sfx.fileName(f));
        Serial.print("\tsize: "); Serial.println(sfx.fileSize(f));
      }
      Serial.println("========================");
      break; 
    }
    
    case '#': {
      Serial.print("Enter track #");
      uint8_t n = readnumber();

      Serial.print("\nPlaying track #"); Serial.println(n);
      if (! sfx.playTrack((uint8_t)n) ) {
        Serial.println("Failed to play track?");
      }
      break;
    }
    
    case 'P': {
      Serial.print("Enter track name (full 12 character name!) >");
      char name[20];
      readline(name, 20);

      Serial.print("\nPlaying track \""); Serial.print(name); Serial.print("\"");
      if (! sfx.playTrack(name) ) {
        Serial.println("Failed to play track?");
      }
      break;
   }

   case '+': {
      Serial.println("Vol up...");
      uint16_t v;
      if (! (v = sfx.volUp()) ) {
        Serial.println("Failed to adjust");
      } else {
        Serial.print("Volume: "); Serial.println(v);
      }
      break;
   }

   case '-': {
      Serial.println("Vol down...");
      uint16_t v;
      if (! (v=sfx.volDown()) ) {
        Serial.println("Failed to adjust");
      } else { 
        Serial.print("Volume: "); 
        Serial.println(v);
      }
      break;
   }
   
   case '=': {
      Serial.println("Pausing...");
      if (! sfx.pause() ) Serial.println("Failed to pause");
      break;
   }
   
   case '>': {
      Serial.println("Unpausing...");
      if (! sfx.unpause() ) Serial.println("Failed to unpause");
      break;
   }
   
   case 'q': {
      Serial.println("Stopping...");
      if (! sfx.stop() ) Serial.println("Failed to stop");
      break;
   }  

   case 't': {
      Serial.print("Track time: ");
      uint32_t current, total;
      if (! sfx.trackTime(&current, &total) ) Serial.println("Failed to query");
      Serial.print(current); Serial.println(" seconds");
      break;
   }  

   case 's': {
      Serial.print("Track size (bytes remaining/total): ");
      uint32_t remain, total;
      if (! sfx.trackSize(&remain, &total) ) 
        Serial.println("Failed to query");
      Serial.print(remain); Serial.print("/"); Serial.println(total); 
      break;
   }  

  }





  
} /////END LOOP



/************************ MENU HELPERS ***************************/

void flushInput() {
  // Read all available serial input to flush pending data.
  uint16_t timeoutloop = 0;
  while (timeoutloop++ < 40) {
    while(Serial1.available()) {
      Serial1.read();
      timeoutloop = 0;  // If char was received reset the timer
    }
    delay(1);
  }
}

char readBlocking() {
  while (!Serial.available());
  return Serial.read();
}

uint16_t readnumber() {
  uint16_t x = 0;
  char c;
  while (! isdigit(c = readBlocking())) {
    //Serial.print(c);
  }
  Serial.print(c);
  x = c - '0';
  while (isdigit(c = readBlocking())) {
    Serial.print(c);
    x *= 10;
    x += c - '0';
  }
  return x;
}

uint8_t readline(char *buff, uint8_t maxbuff) {
  uint16_t buffidx = 0;
  
  while (true) {
    if (buffidx > maxbuff) {
      break;
    }

    if (Serial.available()) {
      char c =  Serial.read();
      //Serial.print(c, HEX); Serial.print("#"); Serial.println(c);

      if (c == '\r') continue;
      if (c == 0xA) {
        if (buffidx == 0) {  // the first 0x0A is ignored
          continue;
        }
        buff[buffidx] = 0;  // null term
        return buffidx;
      }
      buff[buffidx] = c;
      buffidx++;
    }
  }
  buff[buffidx] = 0;  // null term
  return buffidx;
}
/************************ MENU HELPERS ***************************/


/////////////////////////NEOPIXEL STUFF///////////////////////////

float lerp(float x, float x0, float x1, float y0, float y1)
{
  // Clamp x within x0 and x1 bounds.
  x = x > x1 ? x1 : x;
  x = x < x0 ? x0 : x;
  // Calculate linear interpolation of y value.
  return y0 + (y1-y0)*((x-x0)/(x1-x0));
}

// Get the color of a pixel within a smooth gradient of two colors.
uint32_t color_gradient(uint8_t start_r, // Starting R,G,B color
                        uint8_t start_g,
                        uint8_t start_b, 
                        uint8_t end_r,   // Ending R,G,B color
                        uint8_t end_g,
                        uint8_t end_b,
                        float pos)       // Position along gradient, should be a value 0 to 1.0
{
  // Interpolate R,G,B values and return them as a color.  
  uint8_t red   = (uint8_t) lerp(pos, 0.0, 1.0, start_r, end_r);
  uint8_t green = (uint8_t) lerp(pos, 0.0, 1.0, start_g, end_g);
  uint8_t blue  = (uint8_t) lerp(pos, 0.0, 1.0, start_b, end_b);
  return Adafruit_NeoPixel::Color(red, green, blue);
}

// Set all pixels to the specified color.
void fill_pixels(Adafruit_NeoPixel& pixels, uint32_t color)
{
  for (int i=0; i < pixels.numPixels(); ++i) {
    pixels.setPixelColor(i, color);
  }
  strip.show();
}

void animate_gradient_fill(Adafruit_NeoPixel& pixels, // NeoPixel strip/loop/etc.
                           uint8_t start_r,           // Starting R,G,B color
                           uint8_t start_g,
                           uint8_t start_b, 
                           uint8_t end_r,             // Ending R,G,B color
                           uint8_t end_g,
                           uint8_t end_b,
                           int duration_ms)           // Total duration of animation, in milliseconds
{
  unsigned long start = millis();
  // Display start color.
  fill_pixels(pixels, Adafruit_NeoPixel::Color(start_r, start_g, start_b));
  // Main animation loop.
  unsigned long delta = millis() - start;
  while (delta < duration_ms) {
    // Calculate how far along we are in the duration as a position 0...1.0
    float pos = (float)delta / (float)duration_ms;
    // Get the gradient color and fill all the pixels with it.
    uint32_t color = color_gradient(start_r, start_g, start_b, end_r, end_g, end_b, pos);
    fill_pixels(pixels, color);
    // Update delta and repeat.
    delta = millis() - start;
  }
  // Display end color.
  fill_pixels(pixels, Adafruit_NeoPixel::Color(end_r, end_g, end_b));
}


User avatar
BH32794
 
Posts: 63
Joined: Mon Nov 13, 2017 8:15 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by BH32794 »

Hi Carter,

Bit of an update.

I got the sound and lights to work. Now I just need to perfect the timing.

A few things are happening:

1) When the button is pressed, lights and sounds work, but the sound gets cut off near the end. Probably needs a longer delay to play the whole sound.
2) If I HOLD the button, it messes everything up. Lights and sound are out of sync and it doesn't return to normal.

I'd like it to be so if I rapidly push the trigger, the sound will play with the trigger pull. I tried messing around with button states, but I'm not getting the right results.

Code: Select all


#include "Adafruit_Soundboard.h"
#include <Adafruit_NeoPixel.h>

#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

#define PIXEL_PIN     5   // Pin connected to neo pixels
#define FIREPIN       7   // Fire button 
#define SWITCHPIN1    15  // Analog
#define SWITCHPIN2    16  // Analog
#define SWITCHPIN3    17  // Analog
#define SWITCHPIN4    18  // Analog
#define LED_COUNT     30
#define NUM_LEDS      30

// Choose any two pins that can be used with SoftwareSerial to RX & TX
#define SFX_TX  1
#define SFX_RX  0
#define SFX_RST 2

Adafruit_Soundboard sfx = Adafruit_Soundboard(&Serial1, NULL, SFX_RST);

#define NUM_SOUNDS 5
// The names of the found files.
// Note that they are 8 characters followed by a 3 character file
// type (.OGG or .WAV). Spaces are inserted to make up the
// 8 characters as needed.
char *soundName[NUM_SOUNDS] = {
  "EWOKHORNWAV",//0
  "LOCKLOADWAV",//1
  "PRIMARY1WAV",//2
  "STUNGUN2WAV",//3
  "BLASTER3WAV" //4
};

int buttonState = 0;
int lastButtonState = 0;

Adafruit_NeoPixel strip(LED_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);



void setup() {
  
// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.
  
strip.begin();
strip.show();  
strip.setBrightness(255); // Set BRIGHTNESS to about 1/5 (max = 255)

pinMode(FIREPIN, INPUT_PULLUP);

pinMode(SWITCHPIN1, INPUT_PULLUP);
pinMode(SWITCHPIN2, INPUT_PULLUP);
pinMode(SWITCHPIN3, INPUT_PULLUP);
pinMode(SWITCHPIN4, INPUT_PULLUP);


Serial1.begin(9600);
Serial.println("Adafruit Sound Board!");

if (!sfx.reset()) {
    Serial.println("Not found");
    while (1);
  }
  Serial.println("SFX board found");

sfx.playTrack(soundName[1]);
delay(4000);

}



void loop() {

buttonState = digitalRead(FIREPIN);

if (buttonState != lastButtonState){
  if (buttonState == HIGH) {
    sfx.playTrack(soundName[2]);
    delay (100);
    colorWipe(0xff,0x00,0x00, 5);
    colorWipe(0x00,0x00,0x00, 5);
    }
  else{
    setAll(0,0,0); 
    sfx.stop();
    
    }
    
} 
lastButtonState = buttonState;              
  





  
  
  
//////////////////Soundboard Stuff/////////////////////  
  
// flushInput();
  
//  Serial.println(F("What would you like to do?"));
//  Serial.println(F("[r] - reset"));
//  Serial.println(F("[+] - Vol +"));
//  Serial.println(F("[-] - Vol -"));
//  Serial.println(F("[L] - List files"));
//  Serial.println(F("[P] - play by file name"));
//  Serial.println(F("[#] - play by file number"));
//  Serial.println(F("[=] - pause playing"));
//  Serial.println(F("[>] - unpause playing"));
//  Serial.println(F("[q] - stop playing"));
//  Serial.println(F("[t] - playtime status"));
//  Serial.println(F("> "));
  
//  while (!Serial.available());
//  char cmd = Serial.read();
  
//   flushInput();
//  
//  switch (cmd) {
//    case 'r': {
//      if (!sfx.reset()) {
//        Serial.println("Reset failed");
//      }
//      break; 
//    } 
//    
//    case '#': {
//      Serial.print("Enter track #");
//      uint8_t n = readnumber();
//
//      Serial.print("\nPlaying track #"); Serial.println(n);
//      if (! sfx.playTrack((uint8_t)n) ) {
//        Serial.println("Failed to play track?");
//      }
//      break;
//    }
//    
//    case 'P': {
//      Serial.print("Enter track name (full 12 character name!) >");
//      char name[20];
//      readline(name, 20);
//
//      Serial.print("\nPlaying track \""); Serial.print(name); Serial.print("\"");
//      if (! sfx.playTrack(name) ) {
//        Serial.println("Failed to play track?");
//      }
//      break;
//   }
//
//   case '+': {
//      Serial.println("Vol up...");
//      uint16_t v;
//      if (! (v = sfx.volUp()) ) {
//        Serial.println("Failed to adjust");
//      } else {
//        Serial.print("Volume: "); Serial.println(v);
//      }
//      break;
//   }
//
//   
//   case 'q': {
//      Serial.println("Stopping...");
//      if (! sfx.stop() ) Serial.println("Failed to stop");
//      break;
//   }  
//
//   case 't': {
//      Serial.print("Track time: ");
//      uint32_t current, total;
//      if (! sfx.trackTime(&current, &total) ) Serial.println("Failed to query");
//      Serial.print(current); Serial.println(" seconds");
//      break;
//   }  
//
//   case 's': {
//      Serial.print("Track size (bytes remaining/total): ");
//      uint32_t remain, total;
//      if (! sfx.trackSize(&remain, &total) ) 
//        Serial.println("Failed to query");
//      Serial.print(remain); Serial.print("/"); Serial.println(total); 
//      break;
//   }  
//
//  }





  
} /////END LOOP



/************************ MENU HELPERS ***************************/

void flushInput() {
  // Read all available serial input to flush pending data.
  uint16_t timeoutloop = 0;
  while (timeoutloop++ < 40) {
    while(Serial.available()) {
      Serial.read();
      timeoutloop = 0;  // If char was received reset the timer
    }
    delay(1);
  }
}

char readBlocking() {
  while (!Serial.available());
  return Serial.read();
}

uint16_t readnumber() {
  uint16_t x = 0;
  char c;
  while (! isdigit(c = readBlocking())) {
    //Serial.print(c);
  }
  Serial.print(c);
  x = c - '0';
  while (isdigit(c = readBlocking())) {
    Serial.print(c);
    x *= 10;
    x += c - '0';
  }
  return x;
}

uint8_t readline(char *buff, uint8_t maxbuff) {
  uint16_t buffidx = 0;
  
  while (true) {
    if (buffidx > maxbuff) {
      break;
    }

    if (Serial.available()) {
      char c =  Serial.read();
      //Serial.print(c, HEX); Serial.print("#"); Serial.println(c);

      if (c == '\r') continue;
      if (c == 0xA) {
        if (buffidx == 0) {  // the first 0x0A is ignored
          continue;
        }
        buff[buffidx] = 0;  // null term
        return buffidx;
      }
      buff[buffidx] = c;
      buffidx++;
    }
  }
  buff[buffidx] = 0;  // null term
  return buffidx;
}


/////////////////////////NEOPIXEL STUFF///////////////////////////

void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H 
   // NeoPixel
   strip.show();
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   FastLED.show();
 #endif
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H 
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H 
   // FastLED
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
 #endif
}

void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue); 
  }
  showStrip();
}

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
  for(uint16_t i=0; i<NUM_LEDS; i++) {
      setPixel(i, red, green, blue);
      showStrip();
      delay(SpeedDelay);
  }
}

User avatar
BH32794
 
Posts: 63
Joined: Mon Nov 13, 2017 8:15 pm

Re: Itsy Bitsy M0 Express + Soundboard Help

Post by BH32794 »

Just bumping this thread. Still looking for some assistance.

Locked
Please be positive and constructive with your questions and comments.

Return to “Itsy Bitsy Boards”