Go Down

Topic: Combine DFPlayer sketch output with sound sketch created using interupts (Read 186 times) previous topic - next topic

WL888

Code: [Select]
Hi All
I have 2 sketches, each works individually as expected.
I am attempting to combine them into a single sketch, The first is a cut down version of the MojoEngineSim, the second is a DFPlayer .
The attached sketch has them combined, but with the call for the DFPlayer commented out.
In this state the MojoEngine part works correctly, giving a sound variation when the 10k pot is turned,  but when the call for the DFPlayer is un-commented there is no sound variation from the Mojo part of the sketch.

I will be the first to admit that from the area below "PCM Setup" i am way out of my depth.

Could people have a look at this and see if you can find a solution.
Thanks


//********************************DFPlayer
#include <DFPlayer_Mini_Mp3.h>
const int buttonPin = 4;            // the number of the pushbutton pin
int buttonState = 0;                // variable for reading the pushbutton status
int buusyPin = 10;// buusyPin = 10; // sound player busy
int bsy = 0;
int LEDstripLight = 12;             // IRL520 to LED strip light

int sensorPin = A0;                 // Audio level samples
int sensorValue = 0;                // variable to store the value coming from the sensor
int buttn = 0;

#include "settings.h"
#include "idle.h"
//*****************************MOJO Engine
// Mode settings - These could easily be 4 jumpers connected to spare pins, checked at startup to determine mode
//boolean managedThrottle = false;     // Managed mode looks after the digipot if fitted for volume, and adds some mass to the engine
boolean potThrottle = true;         // A pot connected to A1, 0-1023 sets speed

// Stuff not to play with!
#define SPEAKER 3                              // This is kept as 3, original code had 11 as option, but this conflicts with SPI
volatile uint16_t currentSmpleRate = BASE_RATE; // Current playback rate, this is adjusted depending on engine RPM
boolean audioRunning = false;                   // Audio state, used so we can toggle the sound system
uint16_t curVolume = 0;                         // Current digi pot volume, used for fade in/out
volatile uint16_t curEngineSample;              // Index of current loaded sample
uint8_t  lastSample;                            // Last loaded sample
int16_t  currentThrottle = 0;                   // 0 - 1000, a top value of 1023 is acceptable
uint8_t  throttleByte = 0;                      // Raw throttle position in SPI mode, gets mapped to currentThrottle
uint8_t  spiReturnByte = 0;                     // The current RPM mapped to a byte for SPI return
volatile int16_t pulseWidth = 0;                // Current pulse width when in PWM mode

void setup()
{
  //*************************DFPlayer
  pinMode(buttonPin, INPUT);
  pinMode(LEDstripLight, OUTPUT);
  pinMode(buusyPin, INPUT);
  pinMode(buttonPin, INPUT);
  Serial.begin (9600);
  mp3_set_serial (Serial);          //set Serial for DFPlayer-mini mp3 module
  mp3_set_volume (30);              // must remove mp3_reset(); to get this to work
  mp3_set_EQ (5);                   //EQ 0/1/2/3/4/5   Normal/Pop/Rock/Jazz/Classic/Bass
  //***********************************Mojo Engine
  int writePot(DEFAULT_VOLUME);

  // setup complete, so start making sounds
  startPlayback();
}

void loop()
{
  if(potThrottle) doPotThrottle();

  //DFPlayer();
}

//******************************DFPlayer
void DFPlayer() {
    //Serial.println("");
  //Serial.println("Waiting for Button Push");
  do {
    buttn = digitalRead(buttonPin); // pins closest to power pins
  } while (buttn == 0);

  //Serial.println("Button Hit");
  mp3_play(3);
  delay(100);
  do {
    sensorValue = analogRead(sensorPin);
    //Serial.print(sensorValue);
    //Serial.print(" ");
    if (sensorValue >= 370) {
      //Serial.println("large number! ");
      digitalWrite(LEDstripLight, HIGH);
    }
    if (sensorValue <= 320) {
      digitalWrite(LEDstripLight, LOW);
    }
    bsy = digitalRead(buusyPin);
  } while (bsy == 0);             // zero when sound active

//****************************End DFPlayer*
}
void doPotThrottle(){
    currentSmpleRate = F_CPU / (BASE_RATE + long(analogRead(POT_PIN) * TOP_SPEED_MULTIPLIER));
  }



/*PCM Setup  */

void startPlayback()
{
  pinMode(SPEAKER, OUTPUT);
  audioRunning = true;

  // Set up Timer 2 to do pulse width modulation on the speaker pin.
  ASSR &= ~(_BV(EXCLK) | _BV(AS2));                         // Use internal clock (datasheet p.160)

  TCCR2A |= _BV(WGM21) | _BV(WGM20);                        // Set fast PWM mode  (p.157)
  TCCR2B &= ~_BV(WGM22);

  TCCR2A = (TCCR2A | _BV(COM2B1)) & ~_BV(COM2B0);           // Do non-inverting PWM on pin OC2B (p.155)
  TCCR2A &= ~(_BV(COM2A1) | _BV(COM2A0));                   // On the Arduino this is pin 3.
  TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10); // No prescaler (p.158)

  OCR2B = pgm_read_byte(&idle_data[0]);                     // Set initial pulse width to the first sample.

  // Set up Timer 1 to send a sample every interrupt.
  cli();

  TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);             // Set CTC mode (Clear Timer on Compare Match) (p.133)
  TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));             // Have to set OCR1A *after*, otherwise it gets reset to 0!

  TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10); // No prescaler (p.134)

  OCR1A = F_CPU / BASE_RATE;                                // Set the compare register (OCR1A).
                                                            // OCR1A is a 16-bit register, so we have to do this with
                                                            // interrupts disabled to be safe.

  TIMSK1 |= _BV(OCIE1A);                                   // Enable interrupt when TCNT1 == OCR1A (p.136)

  lastSample = pgm_read_byte(&idle_data[idle_len-1]);
  curEngineSample = 0;
  sei();


  uint8_t target = map(currentThrottle, 0, 1023, VOL_MIN, VOL_MAX); // Fadein the volume pot
  for(uint8_t i = 0; i < target; i ++){
    curVolume = i;
    int writePot(curVolume);
    delay(1);
  }
}


void stopPlayback()
{
  // Fadeout the volume pot
  for(uint8_t i = curVolume; i > 0; i--){
    curVolume = i;
    int writePot(i);
    delay(1);
  }

  audioRunning = false;

  TIMSK1 &= ~_BV(OCIE1A); // Disable playback per-sample interrupt.
  TCCR1B &= ~_BV(CS10);   // Disable the per-sample timer completely.
  TCCR2B &= ~_BV(CS10);   // Disable the PWM timer.

  digitalWrite(SPEAKER, LOW);
}

/*        Interupts       */

// Uses a pin change interrupt and micros() to get the pulsewidth at pin 2
void getPulsewidth(){
  unsigned long currentMicros = micros();
  boolean currentState = digitalRead(2);

  static unsigned long prevMicros = 0;
  static boolean lastState = LOW;

  if(lastState == LOW && currentState == HIGH){      // Rising edge
    prevMicros = currentMicros;
    lastState = currentState;
  }
  else if(lastState == HIGH && currentState == LOW){ // Falling edge
    pulseWidth = currentMicros - prevMicros;
    lastState = currentState;
  }

}

// SPI slave interrupt, just stores the last byte and sends
// current throttle when in managed mode
// If we change to a multibyte system this will get expanded
ISR (SPI_STC_vect){
  if(digitalRead(10)){
    throttleByte = SPDR;  // Store new byte
    SPDR = spiReturnByte; // Queue up return byte for next transaction
  }
}


// This is the main playback interrupt, keep this nice and tight!!
ISR(TIMER1_COMPA_vect) {
  OCR1A = currentSmpleRate;

  if (curEngineSample >= idle_len) { // Loop the sample
    curEngineSample = 0;
  }

  OCR2B = pgm_read_byte(&idle_data[curEngineSample]);

  ++curEngineSample;

}

Go Up