I am building a animatronic Elf on the shelf using a UNO board. I have 2 servos . Servo A to nod head up and down (yes) and Servo B to shake head side to side (No).
I am using a 4 button RF remote to control the project.
Button A cycles through several mp3 audio files that I am writing a script/story for.
Button B shakes head side to side (No)
Button C nods head up and down (yes)
Button D is not assigned yet
I would like to add some audio files to buttons B and C - So when I press button B the elf will shake head side to side and say No. I'd like to record several mp3 files for the negative responses and several for the affirmative as well.. So the code would cycle through several files before returning to the first file.
I have the system working except for the audio functions of buttons B & C.. The servos are working fine and the Audio on button A works fine.
Can someone help with the code for buttons B & C ?
Here is the code so far
#include <Servo.h>
#include <SoftwareSerial.h>
Servo servoA;
Servo servoB;
const int buttonAPin = 9; // Button A
const int buttonBPin = 10; // Button B
const int buttonCPin = 11; // Button C
const int buttonDPin = 12; // Button D
const int ledPin = 13; // Used as 5V output for QIACHIP module
int buttonAState = LOW;
int lastButtonAState = LOW;
unsigned long lastDebounceTimeA = 0;
unsigned long debounceDelay = 50;
int buttonBState = LOW;
int lastButtonBState = LOW;
unsigned long lastDebounceTimeB = 0;
int buttonCState = LOW;
int lastButtonCState = LOW;
unsigned long lastDebounceTimeC = 0;
SoftwareSerial mySerial(3, 2); // RX, TX for DF Player Mini
void setup() {
servoA.attach(6);
servoB.attach(7);
pinMode(buttonAPin, INPUT);
pinMode(buttonBPin, INPUT);
pinMode(buttonCPin, INPUT);
pinMode(buttonDPin, INPUT);
pinMode(ledPin, OUTPUT);
mySerial.begin(9600);
pinMode(13, OUTPUT); // Set pin 13 as 5V output for QIACHIP module
digitalWrite(13, HIGH); // Set pin 13 high to provide 5V
}
void loop() {
// Button A handling
int readingA = digitalRead(buttonAPin);
if (readingA != lastButtonAState) {
lastDebounceTimeA = millis();
}
if ((millis() - lastDebounceTimeA) > debounceDelay) {
if (readingA != buttonAState) {
buttonAState = readingA;
if (buttonAState == HIGH) {
// Button A pressed
playNextMP3();
}
}
}
lastButtonAState = readingA;
// Button B handling
int readingB = digitalRead(buttonBPin);
if (readingB != lastButtonBState) {
lastDebounceTimeB = millis();
}
if ((millis() - lastDebounceTimeB) > debounceDelay) {
if (readingB != buttonBState) {
buttonBState = readingB;
if (buttonBState == HIGH) {
// Button B pressed
continuousRotateServoA();
}
}
}
lastButtonBState = readingB;
// Button C handling
int readingC = digitalRead(buttonCPin);
if (readingC != lastButtonCState) {
lastDebounceTimeC = millis();
}
if ((millis() - lastDebounceTimeC) > debounceDelay) {
if (readingC != buttonCState) {
buttonCState = readingC;
if (buttonCState == HIGH) {
// Button C pressed
continuousRotateServoB();
}
}
}
lastButtonCState = readingC;
// Your existing code for button D handling
// (e.g., playNextMP3())
// Your existing code for continuous servo rotation
// (e.g., continuousRotateServoB())
}
void playNextMP3() {
static int mp3FileNumber = 1; // Assuming your files are numbered starting from 1
static const int lastFileNumber = 4; // Change this to the last file number
mySerial.write(0x7E); // Start code
mySerial.write(0xFF); // Version
mySerial.write(0x06); // Command length
mySerial.write(0x03); // Command: Play specific file
mySerial.write((byte)0x00); // Reserved
mySerial.write((byte)(mp3FileNumber >> 8)); // High byte of file number
mySerial.write((byte)mp3FileNumber); // Low byte of file number
mySerial.write(0xEF); // End code
delay(500); // Adjust delay if needed
mp3FileNumber++; // Move to the next file for the next press
// Reset to the first file if the last file is reached
if (mp3FileNumber > lastFileNumber) {
mp3FileNumber = 1;
}
}
void smoothMoveServo(Servo &servo, int targetPosition, int step, int delayTime) {
int currentPosition = servo.read();
if (currentPosition < targetPosition) {
for (int pos = currentPosition; pos <= targetPosition; pos += step) {
servo.write(pos);
delay(delayTime);
}
} else {
for (int pos = currentPosition; pos >= targetPosition; pos -= step) {
servo.write(pos);
delay(delayTime);
}
}
}
void continuousRotateServoA() {
while (digitalRead(buttonBPin) == HIGH) {
smoothMoveServo(servoA, 120, 1, 8); // Adjust target position, step, and delay time
smoothMoveServo(servoA, 60, 1, 10); // Adjust target position, step, and delay time
}
// Stop the servo when the button is released
servoA.write(90);
}
void continuousRotateServoB() {
while (digitalRead(buttonCPin) == HIGH) {
smoothMoveServo(servoB, 110, 1, 10); // Adjust target position, step, and delay time
smoothMoveServo(servoB, 60, 1, 10); // Adjust target position, step, and delay time
}
// Stop the servo when the button is released
servoB.write(90);
}