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;
}