Go Down

Topic: Help with Code for Volume Knob (Rotary Encoder) + FX Mini Sound Board (Read 780 times) previous topic - next topic

m0rningstar

Hi, thanks for checking out this question!

I am trying to control the adafruit fx mini sound board volume with a rotary encoder - both are connected to a metro 328. I have tried calling sfx.volUp() & sfx.VolDown() depending on direction rotate thinking that would automatically turn up/down the volume - this didn't work.

I am not sure how I can accomplish what I want. Can you please help me out?

Code: [Select]
#include "FastLED.h"
 #include <SoftwareSerial.h>
#include "Adafruit_Soundboard.h"
#include <SimpleRotary.h>


int inPin = 8;         // the number of the input pin
int inPinTwo = 9;
int inPinThree = 10;
int outPin = 13;       // the number of the output pin

int state = HIGH;      // the current state of the output pin

int reading;           // the current reading from the input pin
int readingTwo;
int readingThree;
int previous = LOW;    // the previous reading from the input pin
int previousTwo = LOW;
int previousThree = LOW;
volatile int change;
int btnPress;

int pixelNumber;



// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

//NEOPIXEL
#define LED_PIN     7
#define LEDPIN 7
#define LED_TYPE     NEOPIXEL
#define NUM_LEDS    2
#define BRIGHTNESS 255
#define FRAMES_PER_SECOND 60
CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB
#define CHIPSET     WS2812B

//AUDIO
#define SFX_RST 11
#define SFX_TX 5
#define SFX_RX 6
SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX);
Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, SFX_RST);

//ROTARY
// Pin A, Pin B, Button Pin
SimpleRotary rotary(2,4,3);

void setup()
{
//BUTTON
  pinMode(inPin, INPUT);
  pinMode(inPinTwo,INPUT);
  pinMode(inPinThree,INPUT);
  pinMode(outPin, OUTPUT);

//  Serial.begin(9600);
Serial.begin(115200);
  ss.begin(9600);

  // set up LED strip info
FastLED.addLeds<LED_TYPE,LEDPIN>(leds,NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
btnPress = 1;

//AUDIO
if (!sfx.reset()) {
    Serial.println("Not found");
    while (1);
  }
  Serial.println("SFX board found");
//sfx.volDown((uint8_t)50);
 
}

void loop()
{
//Serial.println(sfx.volUp());
//sfx.vol
 
//  ROTARY
  byte i;
  byte p;
  // 0 = not turning, 1 = CW, 2 = CCW
  i = rotary.rotate();
  //    louder
  if ( i == 1 ) {
    Serial.println("CW");
sfx.volUp();
  }
//    quiter
  if ( i == 2 ) {
    Serial.println("CCW");
sfx.volDown();
  }
  //pushed
  p = rotary.push();
  if(p == 1){
    Serial.println("Pushed");
    }

 
//    BUTTON 1 - SOLID LIGHT
  reading = digitalRead(inPin);
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH){
      state = LOW;
      btnPress = 1;
//      sfx.volDown();
//      sfx.stop();     
    }
    else{
      state = HIGH;
      btnPress = 2;
      }

    time = millis();   

  }
    digitalWrite(outPin, state);
    previous = reading;

//  BUTTON 2 - GLITTER LIGHT
   readingTwo = digitalRead(inPinTwo);
  if (readingTwo == HIGH && previousTwo == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
      btnPress = 3;
//      sfx.volDown();
//      sfx.stop();
      }
    else{
      state = HIGH;
      btnPress = 4;
    }
    time = millis();
    }
    digitalWrite(outPin,state);
    previousTwo = readingTwo;


//  BUTTON 3  - MOVEMENT SENSOR LIGHT
       readingThree = digitalRead(inPinThree);
  if (readingThree == HIGH && previousThree == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
       btnPress = 5;
      }
    else{
      state = HIGH;
      btnPress = 6;
    }

    time = millis();
    }
    digitalWrite(outPin,state);
    previousThree = readingThree;



    //BUTTON 1 - SOLID LIGHT
     if (btnPress == 1){
          fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();
//           sfx.stop();
//          Serial.println("pressed1");
      }

    if (btnPress == 2){
          fill_solid(leds,NUM_LEDS,0xFfffff);
          FastLED.show();
//          Serial.println("pressed2");

      }

    //  BUTTON 2 - GLITTER LIGHT
    if (btnPress == 3){
            fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();
//           sfx.stop();
//          Serial.println("pressed3");

      }
    if (btnPress == 4){
         fadeToBlackBy( leds, NUM_LEDS, 10);
          addGlitter(30);
          FastLED.show();
//          Serial.println("pressed4");
      }

    //  BUTTON 3  - MOVEMENT SENSOR LIGHT
    if (btnPress == 5){
            fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();
//           sfx.stop();
//          Serial.println("pressed5");
      }
    if (btnPress == 6){
        Serial.println("pressed6");
//        sfx.playTrack((uint8_t)1);

      }
  }


//glitter effect
void addGlitter( fract8 chanceOfGlitter) {
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;}
}


 


Rotary Code Only
Code: [Select]
//  ROTARY
  byte i;
  byte p;
  // 0 = not turning, 1 = CW, 2 = CCW
  i = rotary.rotate();
//    louder
  if ( i == 1 ) {
    Serial.println("CW");
sfx.volUp();
  }
//    quiter
  if ( i == 2 ) {
    Serial.println("CCW");
sfx.volDown();
  }
  //pushed
  p = rotary.push();
  if(p == 1){
    Serial.println("Pushed");

    }


Connections/Fritz

MarkT

With any problem like this you need to divide and conquer.

Test the rotary encoder code on its own, using Serial.print to confirm you are reading it correctly.

Test the FX volume code on its own, with explicit calls of know value at know times, so you know that
works.

Only then are you ready to combine the functionalities - and backup your code before any (major) change, so
you can go back to a working version if the worst happens!
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

m0rningstar

Thanks for the response MarkT!  I have definitely tested out every component separately before combining and they work great on their own.

I did some code shuffling and I found that adjusting the volume either before/after playing the track works, but not during the playback of the track.  As you can imagine, this is undesirable but maybe the limitation?

Rotary Code Only
Code: [Select]
void loop()

//  ROTARY
  byte i;
  byte p;
  // 0 = not turning, 1 = CW, 2 = CCW
  i = rotary.rotate();
//    louder
  if ( i == 1 ) {
    Serial.println("CW");
 uint16_t v;
     if (! (v = sfx.volUp()) ) {
            Serial.println("Failed to adjust");
           
          } else {
            Serial.print("Volume: "); Serial.println(v);
           
          }
  }
//    quiter
  if ( i == 2 ) {
    Serial.println("CCW");
     uint16_t v;
     if (! (v = sfx.volDown()) ) {
            Serial.println("Failed to adjust");
           
          } else {
            Serial.print("Volume: "); Serial.println(v);
           
          }
  }
reading = digitalRead(inPin);
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH){
      state = LOW;
      btnPress = 1;
    }
    else{
      state = HIGH;
      btnPress = 2;
      }

    time = millis();   

  }
    digitalWrite(outPin, state);
    previous = reading;

if (btnPress == 2){
          fill_solid(leds,NUM_LEDS,0xFfffff);
          FastLED.show();
sfx.playTrack((uint8_t)1);

      }
}

Go Up