Over the last couple of weeks I've put together a sketch using an Arduino Uno, which i’ll swap out later for the smaller Nano. The sketch controls Leds and their sequence using states, a small servo motor & sound effects controlled by 2 momentary buttons
It basically has three stages.
- No buttons pressed, servo doesn't move and leds blink slowly
- Button A pressed, servo moves 35 degrees and leds blink slightly faster
- Button B pressed, servo moves 83 degrees and leds blink really fast
The sketch works but i'm having an issue with the sound effects
[code]
/*
===================================================================================================
==================================== BB-8 PADAWAN DOME ============================================
====================================== Version 0.07 =============================================
===================================================================================================
Version History
0.01 - Original Sketch by DavidScott
0.02 - r0n_dL added annotations & variable for PIN_sound_BUSY as suggested by DavidScott
0.03 - r0n_dL reassigned pins to align with Padawan control system
- Changed SoftwareSerial pins (RX/TX) 10/9 to 8/4
0.04 - Change pinMode for PIN_trigger to INPUT_PULLUP to resolve issue using with Pro Micro
0.05 - Added support for the BY8301-16P and BY8001-16P sound modules
0.06 - Using an updated version of MP3FLASH16P (MP3Flash16Pv2) which now removes static serial
mappings out of the .cpp file
- Add support to select between using 3 different sound modules by changing 1 variable
0.07 - Changed hard coded serial port in library
r0n_dL IMPORTANT NOTE & RECOGNITON: This sketch was written by DavidScott. Thanks for a great base!
// DavidScott's original comment below
// This example plays a random file (001 to 010) forever
// It uses the playFileAndWait() command so no extra code is needed, it will play another file as soon as
// the previous one finishes. If it doesn't work, try reversing the RX/TX wires as that's probably going to be
// the most common mistake. Also check that the player's BUSY line is connected to Arduino pin 3
// Finally check that the player has a speaker connected as well as ground and VCC
r0n_dL NOTES: Basic sketch provided by DavidScott to give sounds and synchronized voice lights for
scale BB-8 Domes
REQUIRED Libaries to make this sketch work:
MP3Flash16Pv2 Library
https://github.com/r0ndL/MP3Flash16Pv2
BY8x0116P Library
https://github.com/r0ndL/BY8x0116Pv2
*/
// SET AUDIO OPTIONS...
// NOTE: This sketch currently supports 3 different sound modules (MP3-FLASH-16P, BY8001-16P, BY8301-16P)
#define AUDIO1 2 // 1=MP3-FLASH-16P
// 2=BY8001-16P or BY8301-16P
// INCLUDE LIBS AND DECLARE VARIABLES...
#include "AltSoftSerial.h"
AltSoftSerial MP3Serial; // SoftwareSerial port assignments (RX, TX) to communicate with sound module
#if (AUDIO1==2)
//settings for BY8001-16P or BY8301-16P module...
#include "BY8x0116Pv2.h"
BY8x0116Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port
#else
//settings for MP3-FLASH-16P...
#include "MP3Flash16Pv2.h"
MP3Flash16Pv2 myPlayer(MP3Serial); // Use SoftwareSerial as the serial port
#endif
// ARDUINO PIN ASSIGNMENTS...
// Default Pin Assignments - BASIC WIRING in NOTES
#define PIN_sound_BUSY A3 //Connect to BUSY pin on sound module
// ADDITIONAL SOUND OPTIONS...
#define number_of_sounds 3
//
//
//
#include<ServoTimer2.h>
// RED LEDS wired to buttonA & B press
int ledPinRA = A0; // the number of the LED pin
int ledPinRB = A1; // the number of the LED pin
ServoTimer2 myservo; // create servo object to control servo CONNECT UNO TX PIN 9, RX PIN 8
int buttonApin = 2;
int buttonBpin = 4;
int pos = 0; // set initial servo position to 0
int buttonAstate = 0; // variable for reading pushbutton status
int buttonBstate = 0;
/*
by noiasca
https://forum.arduino.cc/index.php?topic=666044
*/
const uint16_t intervalSLOW[] {1000, 1000, 1000, 1000, 1000, 1000, 1000, 100}; // time to wait in each intervall
const uint16_t intervalMEDIUM[] {400, 400, 400, 400, 400, 400, 400, 100};
const uint16_t intervalFAST[] {100, 100, 100, 100, 100, 100, 100, 100};
const byte ledPinA = 5;
const byte ledPinB = 6;
const byte ledPinC = 7;
const byte ledPinD = A4;
const byte ledPinE = A5;
const byte ledPinF = 10;
const byte ledPinG = 11;
void handleLedsSLOW()
{
static uint32_t previousMillis = 0;
static byte state = 7;
if (millis() - previousMillis >= intervalSLOW[state])
{
// it's time for next state
state++;
state = state % 8;
Serial.print(F("state=")); Serial.println(state);
// act according state
switch (state)
{
case 0:
digitalWrite(ledPinA, HIGH);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 1:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, HIGH);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 2:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, HIGH);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 3:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, HIGH);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 4:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, HIGH);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 5:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, HIGH);
digitalWrite(ledPinG, LOW);
break;
case 6:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, HIGH);
break;
case 7:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
}
previousMillis = millis();
}
}
void handleLedsMEDIUM()
{
static uint32_t previousMillis = 0;
static byte state = 7;
if (millis() - previousMillis >= intervalMEDIUM[state])
{
// it's time for next state
state++;
state = state % 8;
Serial.print(F("state=")); Serial.println(state);
// act according state
switch (state)
{
case 0:
digitalWrite(ledPinA, HIGH);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 1:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, HIGH);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 2:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, HIGH);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 3:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, HIGH);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 4:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, HIGH);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 5:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, HIGH);
digitalWrite(ledPinG, LOW);
break;
case 6:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, HIGH);
break;
case 7:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
}
previousMillis = millis();
}
}
void handleLedsFAST()
{
static uint32_t previousMillis = 0;
static byte state = 7;
if (millis() - previousMillis >= intervalFAST[state])
{
// it's time for next state
state++;
state = state % 8;
Serial.print(F("state=")); Serial.println(state);
// act according state
switch (state)
{
case 0:
digitalWrite(ledPinA, HIGH);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 1:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, HIGH);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 2:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, HIGH);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 3:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, HIGH);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 4:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, HIGH);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
case 5:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, HIGH);
digitalWrite(ledPinG, LOW);
break;
case 6:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, HIGH);
break;
case 7:
digitalWrite(ledPinA, LOW);
digitalWrite(ledPinB, LOW);
digitalWrite(ledPinC, LOW);
digitalWrite(ledPinD, LOW);
digitalWrite(ledPinE, LOW);
digitalWrite(ledPinF, LOW);
digitalWrite(ledPinG, LOW);
break;
}
previousMillis = millis();
}
}
void setup() {
myservo.attach(3);
Serial.begin(9600);
pinMode(3, OUTPUT); // initialize the servo pin as an output
pinMode(buttonApin, INPUT_PULLUP); // initialize the button A pin as an input
pinMode(buttonBpin, INPUT_PULLUP); // initialize the button B pin as an input
pinMode(ledPinA, OUTPUT); // initialize the LED1 pin as an output
pinMode(ledPinB, OUTPUT); // initialize the LED2 pin as an output
pinMode(ledPinC, OUTPUT); // initialize the LED3 pin as an output
pinMode(ledPinD, OUTPUT); // initialize the LED4 pin as an output
pinMode(ledPinE, OUTPUT); // initialize the LED5 pin as an output
pinMode(ledPinF, OUTPUT); // initialize the LED6 pin as an output
pinMode(ledPinG, OUTPUT); // initialize the LED7 pin as an output
pinMode(12, OUTPUT); // sets the digital pin 12 as output for 2 SLIDE switch LEDS
pinMode(ledPinRA, OUTPUT); // initialize the LED pin as an output
pinMode(ledPinRB, OUTPUT); // initialize the LED pin as an output
MP3Serial.begin(9600);
myPlayer.init(PIN_sound_BUSY); // Init the player with the MP3 BUSY pin connected to Arduino pin defined
}
void loop() {
digitalWrite(12, HIGH); // sets the digital pin 12 on
buttonAstate = digitalRead(buttonApin); // read the state of button A value
buttonBstate = digitalRead(buttonBpin); // read the state of button B value
// servo position
if ((buttonAstate == HIGH) && (buttonBstate == HIGH)) {
myservo.write(750);
if (!myPlayer.isBusy()) {
myPlayer.playFile(1, 10);
//delay(100);
}
// LED controls
handleLedsSLOW(); // checks if something is todo with the LEDs
//do other important stuff here
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (digitalRead(buttonAstate) == HIGH) {
// turn LED on:
digitalWrite(ledPinRA, LOW);
} else {
// turn LED off:
digitalWrite(ledPinRA, LOW);
}
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (digitalRead(buttonBstate) == HIGH) {
// turn LED on:
digitalWrite(ledPinRB, LOW);
} else {
// turn LED off:
digitalWrite(ledPinRB, LOW);
}
}
else if (buttonAstate == LOW) { // check if button A is pressed
myservo.write(1042); // if it is rotate servo to 35 degrees
if (!myPlayer.isBusy()) {
myPlayer.playFile(2, 10);
//delay(100);
}
handleLedsMEDIUM(); // checks if something is todo with the LEDs
//do other important stuff here
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (digitalRead(buttonAstate) == HIGH) {
// turn LED on:
digitalWrite(ledPinRA, HIGH);
} else {
// turn LED off:
digitalWrite(ledPinRA, LOW);
}
}
else {
(buttonBstate == LOW) // check if button B is pressed
; myservo.write(1442); // if it is rotate servo to 83 degrees
if (!myPlayer.isBusy()) {
myPlayer.playFile(3, 10);
//delay(100);
}
handleLedsFAST(); // checks if something is todo with the LEDs
//do other important stuff here
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (digitalRead(buttonBstate) == HIGH) {
// turn LED on:
digitalWrite(ledPinRB, HIGH);
} else {
// turn LED off:
digitalWrite(ledPinRB, LOW);
}
}
delay(100); // waits for a second
}
[/code]
I have a BY8301-16p module that I have loaded the 3 sound files onto, 01.mp3, 02.mp3 & 03.mp3. I want 1 sound file to play & loop for each of the 3 stages listed above.
Sound 1 plays when the Nano is switched on and the LEDS sequence, that part works as it should.
For stages 2 & 3, the leds sequence & the servo moves just as they should while the corresponding button is pressed and held down.
The probelm is the sound file doesnt instantly change, it waits until its finished playing then changes to the correct track and loops while the button is pressed & held.
I tried removing the ! from
if (!myPlayer.isBusy()) {
myPlayer.playFile(3, 10);
& that does change the track instantly, but just causes the sound to play for a split second before looping, only when i release the button does it play that sound.
What do i need to change to make the track start as soon as the button is pressed, and play on loop for as long as the button is held down
Any help would be greatly appreciated by this Arduino newbie.
