Go Down

Topic: Combine DFPlayer sketch output with sound sketch created using interupts (Read 131 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy