Playing Audio While Performing Other Tasks

I have a 4WD robot with basic ultrasonic collision avoidance. Basically it moves forward until it detects an object then stops, turns left then carries on moving forward etc. This part of the code works perfectly. I now want to incorporate playing an audio clip while the robot is moving forward but can’t get this to work. The SD reader and audio output work correctly when run with a separate audio playing code however I cannot find a way to make the sound file play during forward movement. As I understand it the TMRpcm function should allow continuous playback while other tasks are being performed therefore I must be getting something fundamentally wrong. Code as follows :

#include <SPI.h>
#include <pcmConfig.h>
#include <pcmRF.h>
#include <TMRpcm.h>
#include <SD.h>
#define SD_ChipSelectPin 53
TMRpcm tmrpcm;
#include <math.h>

// No servo, collision avoidance only straight ahead. Turn left when object detected.
/*BTS7960 Motor Driver Carrier*/
const int MotorRight_R_EN = 4;
const int MotorRight_L_EN = 8;
const int MotorLeft_R_EN = 2;
const int MotorLeft_L_EN = 7;
const int Rpwm1 = 5;
const int Lpwm1 = 11;
const int Rpwm2 = 3;
const int Lpwm2 = 6;
long pwmLvalue = 30;
long pwmRvalue = 30;
byte pwmChannel;
byte maxDist = 200;                               //Maximum sensing distance (Objects further than this distance are ignored)
const int stopDist =  50;                               //Minimum distance from an object to stop in cm
float timeOut = 2 * (maxDist + 10) / 100 / 340 * 1000000; //Maximum time to wait for a return signal

/*SRF05 Ultrasonic Sensor*/
#define TRIG 12 // the SRF05 Trig pin
#define ECHO 13 // the SRF05 Echo pin
#define SENSOR_STEP 10 // 5 degrees
int numberOfSteps = int(180 / SENSOR_STEP);
unsigned long pulseTime;
unsigned long srfDistanceArray[180 / SENSOR_STEP]; // 180/step (where step is equal to 5)
unsigned long minimumDistanceThreshold = 5;
unsigned long maximumDistanceThreshold = 70;

/*IR */
int IRsensorFront = A7;
int distanceIRsensorFront;

void setup() {
  tmrpcm.speakerPin = 11;
  if (!SD.begin(SD_ChipSelectPin)) {
    Serial.println("SD fails");
  pinMode(IRsensorFront, INPUT);  // declare Front IR Sensor as input

  //SRF05 Ultrasonic Sensor
  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);

  //Setup Channel A - Drive Motor
  pinMode(MotorRight_R_EN, OUTPUT); //Initiates Motor Channel A1 pin
  pinMode(MotorRight_L_EN, OUTPUT); //Initiates Motor Channel A2 pin

  //Setup Channel B - Steering Motor
  pinMode(MotorLeft_R_EN, OUTPUT); //Initiates Motor Channel B1 pin
  pinMode(MotorLeft_L_EN, OUTPUT); //Initiates Motor Channel B2 pin

  //Setup PWM pins as Outputs
  pinMode(Rpwm1, OUTPUT);
  pinMode(Lpwm1, OUTPUT);
  pinMode(Rpwm2, OUTPUT);
  pinMode(Lpwm2, OUTPUT);
}// void setup()

void loop()
  int distanceIRsensorFront = readIRsensor(); //getAverageDistance();
  if (distanceIRsensorFront >= stopDist)
    digitalWrite(MotorRight_R_EN, HIGH);//enable right and left motor forward and reverse
    digitalWrite(MotorRight_L_EN, HIGH);
    digitalWrite(MotorLeft_R_EN, HIGH);
    digitalWrite(MotorLeft_L_EN, HIGH);
    //I want to play the WAV file while the robot is moving forward per the following lines
    //Run left and right motors forward
    analogWrite(Rpwm1, 150);
    analogWrite(Lpwm1, 0);
    analogWrite(Rpwm2, 150);
    analogWrite(Lpwm2, 0);
  while (distanceIRsensorFront >= stopDist)
    distanceIRsensorFront = readIRsensor();
  //if object is detected stop then turn to the left then carry on forward as before
  digitalWrite(MotorRight_R_EN, HIGH);
  digitalWrite(MotorRight_L_EN, HIGH);
  digitalWrite(MotorLeft_R_EN, HIGH);
  digitalWrite(MotorLeft_L_EN, HIGH);
  analogWrite(Rpwm1, 0);
  analogWrite(Lpwm1, 0);
  analogWrite(Rpwm2, 0);
  analogWrite(Lpwm2, 0);

  analogWrite(Rpwm1, 200);
  analogWrite(Lpwm1, 0);
  analogWrite(Rpwm2, 0);
  analogWrite(Lpwm2, 200);
  analogWrite(Rpwm1, 0);
  analogWrite(Lpwm1, 0);
  analogWrite(Rpwm2, 0);
  analogWrite(Lpwm2, 0);

}// void loop()

int readIRsensor()
  unsigned long pulseTime;                          //Create a variable to store the pulse travel time
  int distance;                                     //Create a variable to store the calculated distance
  digitalWrite(TRIG, HIGH);                         //Generate a 10 microsecond pulse
  digitalWrite(TRIG, LOW);
  pulseTime = pulseIn(ECHO, HIGH, timeOut);         //Measure the time for the pulse to return
  distance = (float)pulseTime * 340 / 2 / 10000;    //Calculate the object distance based on the pulse time
  return distance;
}// void readIRsensors()

void play() {"sound9.wav");

float measurement() {
  digitalWrite(TRIG, HIGH);
  digitalWrite(TRIG, LOW);
  // wait for the pulse to return. The pulse
  // goes from low to HIGH to low, so we specify
  // that we want a HIGH-going pulse below:
  pulseTime = pulseIn(ECHO, HIGH);
  return pulseTime / 58.00;
}// float measurement()

I believe it is the Delay(10000) that is causing your problem. While the delay functioning is happening nothing else can, it is called a blocking function. Not sure this is your problem but it should be a starting point.

Your problem is that your code never attempts to play any sound.
What happens if you try and play sound where you have that comment.

Gil is right for once, if that play function is ever called then it will start the sound and then the processor will effectively shut down for ten seconds while your sound plays.

Sorry, ignore the play() function with the delay I'm not using it. I have been inserting play.tmrpcm("sound9.wav") at different positions within the void() loop with no delay but it doesn't play when the motors are running. It will play the sound for a few seconds after the motors stop then the programme seems to freeze and do nothing, the motors don't start again. I don't think it should be inside the void loop but have tried it in the setup code and it does nnothing at all. According to the description of tmrpcm it allows sound to be played in the background but I don't see how.

PWM is generated by hardware timers. Maybe some of those analogWrite() are trying to use the same timer as the sound library?

Thanks. That's not something I was aware of. How do I find out if this is the problem ?.

Thought I'd found the issue, I had double dipped on pin 11 using it for a motor function and speaker output but this hasn't resolved the issue. I tried putting the command everywhere but it doesn't work. Audio works perfectly when I run a standalone code for playing wav files. Stumped.

Now resolved. I put the function into the setup code and added tmrpcm.loop(1). It now plays continuously while the robot patrols the garden warding off the rabbits.

Working on the same assignment for the project. Can you please help me with the circuit diagram and what all would be needed. Would be really helpful and prove to be kickstart for my academics.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.