Need help programming servo movement to audio file from sd card

Hey everyone,
First of all, thanks for the help. I am somewhat new at using the Arduino, but have programming background in javascript and visual basic.

I am working on a project for my daughter where I am attempting to animate an alligator head with a servo and sync the movement to audio. I have constructed the head, installed the servo and have it working. I used a pot to test and control the physical head through the arduino and it works great. I also am using a sd shield to store wav files and am using TRMPCM to control the audio.

While I can use the audio volume level to drive the servo position, I really wanted to program the movement myself. I have 4 different short audio clips which I want to be able to select from 4 momentary buttons. I have been successful at initializing the arduino and getting the servo to move using a delay. I have researched and found that delay is probably not what I want to be using to command the servo to move as it appears to stop all other processes and I want to play music during the movements. After looking all around, the only servo examples I have found use either a pot or a digital read to drive position. I want to effectually set the positions manually, but control angle over time.

Any suggestions would be greatly appreciated. I have attached my current code below. I started implementing buttons, but did not finish as I am trying to figure out the servo issue first to see if this is even viable.

Thanks.

#include <SD.h>                      // need to include the SD library
//#define SD_ChipSelectPin 53  //example uses hardware SS pin 53 on Mega2560
#define SD_ChipSelectPin 10  //using digital pin 4 on arduino nano 328, can use other pins
#include <TMRpcm.h>           //  also need to include this library...
#include <SPI.h>
#include <Servo.h>
#define BUTTON_PIN 2
#define BUTTON_PIN 3

Servo myservo; // create servo object to control a servo
int pos = 82; // variable to store servo position
int incomingByte; // variable to store byte sent from serial port
TMRpcm tmrpcm;   // create an object for use in this sketch


void setup(){

  pinMode(BUTTON_PIN, INPUT);
  digitalWrite(BUTTON_PIN, HIGH); // connect internal pull-up
  tmrpcm.speakerPin = 9; //5,6,11 or 46 on Mega, 9 on Uno, Nano, etc
  myservo.attach(7); // attaches the servo on pin 7 to the servo object
  myservo.write(82); // set servo to 40 degrees
  delay(4000);
  myservo.write(20);
  delay(500);
  myservo.write(20);
  delay(500);  
  myservo.write(20);
  delay(2000);
  myservo.write(80);
  delay(3000);  
  myservo.write(20);
  delay(500);  
  myservo.write(20);
  delay(100);  
  myservo.write(82);  
  
  Serial.begin(9600);
  if (!SD.begin(SD_ChipSelectPin)) {  // see if the card is present and can be initialized:
    Serial.println("SD fail");  
    return;   // don't do anything more if not
  }
  tmrpcm.play("g_hungry.wav"); //the sound file "music" will play each time the arduino powers up, or is reset
}



void loop(){  

  if(Serial.available()){    
    switch(Serial.read()){ //send the letter p over the serial monitor to start playback
    case 'j': myservo.write(20);
      tmrpcm.play("g_jaws.wav");
      Serial.println("Playing Jaws");
      myservo.write(20);
      delay(500);
      myservo.write(82);
      delay(500); break;

    case 'b': myservo.write(20);
      tmrpcm.play("g_baby.wav");
      Serial.println("Playing Baby sounds");
      myservo.write(20);
      delay(500);
      myservo.write(82);
      delay(500); break;      
     
     default: break; 

    }
  }

}

After looking all around, the only servo examples I have found use either a pot or a digital read to drive position.

No, they use a potentiometer or Serial.read() to get the position. The position data is then used to drive the servo.

I want to effectually set the positions manually, but control angle over time.

You are free to do that.

You need to define what position you want to start at, and how the position changes over time.

How do I control position over time. I set the angle by using a "myservo.write(#)", but how do I code in delays in time between movement without using a delay command which would stop everything?

but how do I code in delays in time between movement without using a delay command

All together now: Read, understand, and embrace the blink without delay philosophy (see the example with that name).

I believe that the main problem with your code is that the servo library and the audio library both are trying to use TIMER1 at the same time, so you end up with a few options:

  1. Do a myservo.detach(); before playing audio and do a myservo.attach(servo1_pin); before trying to use the servo
  2. Use the timer2 servo library (google it) or a custom servo solution
  3. Attempt to use the timer2 option of the TMRpcm library (untested with servo lib) - see the wiki on github to enable
  4. Use an audio shield to offload the audio processing from Arduino

See Conflict with Servo Library · Issue #3 · TMRh20/TMRpcm · GitHub