ok well as described i am after a simple music player
but i want it to cycle, currently there are 3 buttons but the idea is to have 4 buttons.
a play/pause, stop, next and previous. Im not using seek as i just want to change tracks not rewind them.
I have cracked most of the problems but the play pause eludes me, if you can point me in the right direction, would be much appreciated.
Cheers
Wave Shield + Buttons
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- xl97
- Posts: 201
- Joined: Mon Jul 27, 2009 12:51 pm
Re: Wave Shield + Buttons
Well I posted about the pause stuff... still didnt work? (I havent tried myself)..
and I guess my use of FF/RWD was wrong.. I meant NEXT/PREV buttons to be more accurate
Is that now working for you? (the PREVIOUS button?)
and I guess my use of FF/RWD was wrong.. I meant NEXT/PREV buttons to be more accurate
Is that now working for you? (the PREVIOUS button?)
-
- Posts: 54
- Joined: Tue Nov 20, 2012 11:16 am
Re: Wave Shield + Buttons
OK, well getting further on thanks for the assistance.
As you can see from the screenshots included I am able to view wav 1-4 but then when I reverse the order thats when it doesn't work and starts putting minus numbers in there, Also on the final shot you'll see that there is a 0 in there which is like a pause it stops play back for one button press.
Any Ideas on this.
cheers
As you can see from the screenshots included I am able to view wav 1-4 but then when I reverse the order thats when it doesn't work and starts putting minus numbers in there, Also on the final shot you'll see that there is a 0 in there which is like a pause it stops play back for one button press.
Any Ideas on this.
cheers
- Attachments
-
- Screen 3.jpg (96.71 KiB) Viewed 1092 times
-
- Screen 2.jpg (91.95 KiB) Viewed 1092 times
-
- Screen 1.jpg (95.16 KiB) Viewed 1092 times
- xl97
- Posts: 201
- Joined: Mon Jul 27, 2009 12:51 pm
Re: Wave Shield + Buttons
sorry, been busy with the holidays...
are you still having trouble with this?
I can probably take a peek today if you like?
are you still having trouble with this?
I can probably take a peek today if you like?
- xl97
- Posts: 201
- Joined: Mon Jul 27, 2009 12:51 pm
Re: Wave Shield + Buttons
ok..well form the code you last posted.. I dont even see any PAUSE/RESUME..etc code in there? (nor any buttons enabled for it?)
these seems like a similar thread posted only a few days ago.. (except he wanted to have another button play the same sample over and over added into the mix..but otherwise a audio track player)
some suggestions,
1.) use a case/switch statement to check the condition of 1 var/value with many possible outcomes/paths. (not a bunch of if/else if statements..
2.) you can increment/decrease a var/value like so:
someValue++;
or
someValue--;
maybe your way is throwing an error?
anyways.. here is a different (but similar) approach if you wanna give it a shot.. (at work, not hardware to load/test it on)
but you need 4 momentary buttons:
const int prevButton = 16;
const int nextButton = 17;
const int prButton = 18;
const int stopButton = 12;
connected to those pins.
sample code:
these seems like a similar thread posted only a few days ago.. (except he wanted to have another button play the same sample over and over added into the mix..but otherwise a audio track player)
some suggestions,
1.) use a case/switch statement to check the condition of 1 var/value with many possible outcomes/paths. (not a bunch of if/else if statements..
2.) you can increment/decrease a var/value like so:
someValue++;
or
someValue--;
maybe your way is throwing an error?
anyways.. here is a different (but similar) approach if you wanna give it a shot.. (at work, not hardware to load/test it on)
but you need 4 momentary buttons:
const int prevButton = 16;
const int nextButton = 17;
const int prButton = 18;
const int stopButton = 12;
connected to those pins.
sample code:
Code: Select all
// Solution sketch for this adafruit post:
// http://forums.adafruit.com/viewtopic.php?f=31&t=34510
// created by: xl97
//import default/needed libraries
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"
//custom defined variables
const int prevButton = 16;
const int nextButton = 17;
const int prButton = 18;
const int stopButton = 12;
char filename[10]; // leave enough room here.
int trackCounter = 0;
int totalTracks = 5;
boolean trackPaused = 0;
//project variables
SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the filesystem on the card
FatReader f; // This holds the information for the file we're play
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
#define DEBOUNCE 5 // button debouncer
//make button array for easy looping/checking
int buttons[] = {prevButton, nextButton, prButton, stopButton};
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'pressed' (the current state)
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
// this handy function will return the number of bytes currently free in RAM, great for debugging!
int freeRam(void)
{
extern int __bss_end;
extern int *__brkval;
int free_memory;
if((int)__brkval == 0) {
free_memory = ((int)&free_memory) - ((int)&__bss_end);
}
else {
free_memory = ((int)&free_memory) - ((int)__brkval);
}
return free_memory;
}
void sdErrorCheck(void)
{
if (!card.errorCode())
{
return;
}
putstring("\n\rSD I/O error: ");
Serial.print(card.errorCode(), HEX);
putstring(", ");
Serial.println(card.errorData(), HEX);
while(1);
}
//------------------[end init code]---------------------//
void setup() {
byte i;
// Set up serial port
Serial.begin(9600);
putstring_nl("WaveHC with ");
Serial.print(NUMBUTTONS, DEC);
putstring_nl("buttons");
putstring("Free RAM: "); // This can help with debugging, running out of RAM is bad
Serial.println(freeRam());
// Set-up pins not in button array
// pin13 LED
pinMode(13, OUTPUT);
// Make input & enable pull-up resistors on switch pins
for (i=0; i< NUMBUTTONS; i++) {
pinMode(buttons[i], INPUT);
digitalWrite(buttons[i], HIGH);
}
// if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
if (!card.init()) { //play with 8 MHz spi (default faster!)
putstring_nl("Card init. failed!"); // Something went wrong, lets print out why
sdErrorCheck();
while(1); // then 'halt' - do nothing!
}
// enable optimize read - some cards may timeout. Disable if you're having problems
card.partialBlockRead(true);
// Now we will look for a FAT partition!
uint8_t part;
for (part = 0; part < 5; part++) { // we have up to 5 slots to look in
if (vol.init(card, part))
break; // we found one, lets bail
}
if (part == 5) { // if we ended up not finding one :(
putstring_nl("No valid FAT partition!");
sdErrorCheck(); // Something went wrong, lets print out why
while(1); // then 'halt' - do nothing!
}
// Lets tell the user about what we found
putstring("Using partition ");
Serial.print(part, DEC);
putstring(", type is FAT");
Serial.println(vol.fatType(),DEC); // FAT16 or FAT32?
// Try to open the root directory
if (!root.openRoot(vol)) {
putstring_nl("Can't open root dir!"); // Something went wrong,
while(1); // then 'halt' - do nothing!
}
// Whew! We got past the tough parts.
putstring_nl("Ready!");
TCCR2A = 0;
TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
//Timer2 Overflow Interrupt Enable
TIMSK2 |= 1<<TOIE2;
}
//--------------------[end set-up code]-----------------------//
//Add function for timer to execute.
SIGNAL(TIMER2_OVF_vect) {
check_switches();
}
//check switches function (watched by timer repeatedly)
void check_switches()
{
//create vars to hold the states of the current button being checked
static byte previousstate[NUMBUTTONS];
static byte currentstate[NUMBUTTONS];
byte index;
//run through each button in the array to check if it is being pressed
for (index = 0; index < NUMBUTTONS; index++) {
currentstate[index] = digitalRead(buttons[index]); // read each button/store its status
if (currentstate[index] == previousstate[index]) {
if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
// just pressed
//putstring("Button Pressed: ");
//Serial.println(index,DEC);
justpressed[index] = 1;
}
else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
// just released
justreleased[index] = 1;
}
pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed //commenting out stops file while pressed
}
//Serial.println(pressed[index], DEC);
//update previous status to the current status
previousstate[index] = currentstate[index]; // keep a running tally of the buttons
}
}
void loop(){
//NEXT button (plays next track)
if(justpressed[0]){
justpressed[0] = 0;
sprintf(filename,"%d.wav", trackCounter);
Serial.println(filename);
playfile(filename);
//check it at last file and reset if needed
if(trackCounter == totalTracks){
trackCounter = 0;
}
else{
trackCounter++;
}
}
//PREV button (plays next track)
if(justpressed[1]){
justpressed[1] = 0;
sprintf(filename,"%d.wav", trackCounter);
Serial.println(filename);
playfile(filename);
//check it at last file and reset if needed
if(trackCounter == 0){
trackCounter = totalTracks;
}
else{
trackCounter--;
}
}
//PAUSE/RESUME button
if (justpressed[2]){
justpressed[2] = 0;
if (wave.isplaying) {
wave.pause();
Serial.println("paused.....");
}else{
wave.resume();
Serial.println("resumed.....");
}
}
//STOP button
if (justpressed[3]){
justpressed[3] = 0;
if (wave.isplaying) {
wave.stop();
}
}
}
void playfile(char *name) {
// look in the root directory and open the file
if (!f.open(root, name)) {
putstring("Couldn't open file ");
Serial.print(name);
return;
}
// OK read the file and turn it into a wave object
if (!wave.create(f)) {
putstring_nl("Not a valid WAV");
return;
}
wave.play();
}
-
- Posts: 54
- Joined: Tue Nov 20, 2012 11:16 am
Re: Wave Shield + Buttons
Cheers mate, I too are at work, so will give it a try when I get in
Sorry we don't have holidays like you over in uk!
Whilst putting a case switch in it kept just playing one song not cycling through them, I will try your solution and also post my switch case code if I can't get it to work!
Sorry we don't have holidays like you over in uk!
Whilst putting a case switch in it kept just playing one song not cycling through them, I will try your solution and also post my switch case code if I can't get it to work!
- xl97
- Posts: 201
- Joined: Mon Jul 27, 2009 12:51 pm
Re: Wave Shield + Buttons
? I'm not located in the UK?
Im located in the US
(but they dont have Thanksgiving where you are?)
Im located in the US
(but they dont have Thanksgiving where you are?)
-
- Posts: 54
- Joined: Tue Nov 20, 2012 11:16 am
Re: Wave Shield + Buttons
Yeah sorry that's what I meant!
No we don't we only have Christmas and new year!
How long does thanks giving last then?
No we don't we only have Christmas and new year!
How long does thanks giving last then?
- xl97
- Posts: 201
- Joined: Mon Jul 27, 2009 12:51 pm
Re: Wave Shield + Buttons
bob500000 wrote:Yeah sorry that's what I meant!
No we don't we only have Christmas and new year!
How long does thanks giving last then?
as long as we can stretch it out for!
usually 1-2 day off of work.. (depending on your job and the day it falls on)
-
- Posts: 54
- Joined: Tue Nov 20, 2012 11:16 am
Re: Wave Shield + Buttons
Ok, so I tried your code and for some reason it failed to run, no compile errors, just didnt work on the board.
I set it up as you suggested but still no joy, used your example of using four buttons with my code and seems to be working however, im still confused as to where the 0 is coming from, do you have any ideas on that one.
cheers
I set it up as you suggested but still no joy, used your example of using four buttons with my code and seems to be working however, im still confused as to where the 0 is coming from, do you have any ideas on that one.
cheers
- xl97
- Posts: 201
- Joined: Mon Jul 27, 2009 12:51 pm
Re: Wave Shield + Buttons
I dont understand what you mean by where '0' is coming from?
Do you have the switches on the correct pins?
//custom defined variables
const int prevButton = 16;
const int nextButton = 17;
const int prButton = 18;
const int stopButton = 12;
Do you have the switches on the correct pins?
//custom defined variables
const int prevButton = 16;
const int nextButton = 17;
const int prButton = 18;
const int stopButton = 12;
- xl97
- Posts: 201
- Joined: Mon Jul 27, 2009 12:51 pm
Re: Wave Shield + Buttons
ahh..ok, looking back I see what you mean about the zero...
well in my code example..
we take the total number of 'tracks' you want to 'loop/cycle' through.. (in this instance its 5.. totalTracks = 5)
now, in most/many programming languages, they are 'zero-index' based..
meaning when they start counting.. they start at/with 0 (zero)..
In an array the first index is index[0] (ie: someArray[0] = 7, someArray[1] = 3...etc..etc..)
and in most loops, I start with 0 (zero) as my init value
example:
so here.. the code is looking to play 0:
0.wav
1.wav
2.wav
3.wav
4.wav
and then repeat... or go back 'down' in the count..
if you count.. that is '5' wav files... and matches the totalTracks variable we set..
I an MOT sure how many buttons or what you have in your project.. but the code is set up for only the 4 'player' buttons you mentioned..
//custom defined variables
const int prevButton = 16;
const int nextButton = 17;
const int prButton = 18; // play/resume button
const int stopButton = 12;
edit it to match your set-up if not correct...
well in my code example..
we take the total number of 'tracks' you want to 'loop/cycle' through.. (in this instance its 5.. totalTracks = 5)
now, in most/many programming languages, they are 'zero-index' based..
meaning when they start counting.. they start at/with 0 (zero)..
In an array the first index is index[0] (ie: someArray[0] = 7, someArray[1] = 3...etc..etc..)
and in most loops, I start with 0 (zero) as my init value
example:
Code: Select all
for(i=0; i < totalTracks; i++){
// do something while i is less than totaltracks
}
0.wav
1.wav
2.wav
3.wav
4.wav
and then repeat... or go back 'down' in the count..
if you count.. that is '5' wav files... and matches the totalTracks variable we set..
I an MOT sure how many buttons or what you have in your project.. but the code is set up for only the 4 'player' buttons you mentioned..
//custom defined variables
const int prevButton = 16;
const int nextButton = 17;
const int prButton = 18; // play/resume button
const int stopButton = 12;
edit it to match your set-up if not correct...
-
- Posts: 54
- Joined: Tue Nov 20, 2012 11:16 am
Re: Wave Shield + Buttons
Ok, an update I got it working below is the code that I have used to get all the buttons to play ball.
Thanks xl97 for your assistance.
Thanks xl97 for your assistance.
Code: Select all
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"
SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the filesystem on the card
FatReader f; // This holds the information for the file we're play
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
int currentSongcount = 0; // Keeps track of which song to play each time the button is pressed
int maxSongcount = 4; // Total number of songs on the SD card
int minSongcount = 1;
int paused = 0;
#define DEBOUNCE 5 // button debouncer
// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {16, 17, 18, 15};
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'pressed' (the current state
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
// this handy function will return the number of bytes currently free in RAM, great for debugging!
int freeRam(void)
{
extern int __bss_end;
extern int *__brkval;
int free_memory;
if((int)__brkval == 0) {
free_memory = ((int)&free_memory) - ((int)&__bss_end);
}
else {
free_memory = ((int)&free_memory) - ((int)__brkval);
}
return free_memory;
}
void sdErrorCheck(void)
{
if (!card.errorCode()) return;
putstring("\n\rSD I/O error: ");
Serial.print(card.errorCode(), HEX);
putstring(", ");
Serial.println(card.errorData(), HEX);
while(1);
}
void setup() {
byte i;
// set up serial port
Serial.begin(9600);
putstring_nl("WaveHC with ");
Serial.print(NUMBUTTONS, DEC);
putstring_nl("buttons");
putstring("Free RAM: "); // This can help with debugging, running out of RAM is bad
Serial.println(freeRam()); // if this is under 150 bytes it may spell trouble!
// Set the output pins for the DAC control. This pins are defined in the library
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
// pin13 LED
pinMode(13, OUTPUT);
// Make input & enable pull-up resistors on switch pins
for (i=0; i< NUMBUTTONS; i++) {
pinMode(buttons[i], INPUT);
digitalWrite(buttons[i], HIGH);
}
// if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
if (!card.init()) { //play with 8 MHz spi (default faster!)
putstring_nl("Card init. failed!"); // Something went wrong, lets print out why
sdErrorCheck();
while(1); // then 'halt' - do nothing!
}
// enable optimize read - some cards may timeout. Disable if you're having problems
card.partialBlockRead(true);
// Now we will look for a FAT partition!
uint8_t part;
for (part = 0; part < 5; part++) { // we have up to 5 slots to look in
if (vol.init(card, part))
break; // we found one, lets bail
}
if (part == 5) { // if we ended up not finding one :(
putstring_nl("No valid FAT partition!");
sdErrorCheck(); // Something went wrong, lets print out why
while(1); // then 'halt' - do nothing!
}
// Lets tell the user about what we found
putstring("Using partition ");
Serial.print(part, DEC);
putstring(", type is FAT");
Serial.println(vol.fatType(),DEC); // FAT16 or FAT32?
// Try to open the root directory
if (!root.openRoot(vol)) {
putstring_nl("Can't open root dir!"); // Something went wrong,
while(1); // then 'halt' - do nothing!
}
// Whew! We got past the tough parts.
putstring_nl("Ready!");
TCCR2A = 0;
TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
//Timer2 Overflow Interrupt Enable
TIMSK2 |= 1<<TOIE2;
}
SIGNAL(TIMER2_OVF_vect) {
check_switches();
}
void check_switches()
{
static byte previousstate[NUMBUTTONS];
static byte currentstate[NUMBUTTONS];
byte index;
for (index = 0; index < NUMBUTTONS; index++) {
currentstate[index] = digitalRead(buttons[index]); // read the button
/*
Serial.print(index, DEC);
Serial.print(": cstate=");
Serial.print(currentstate[index], DEC);
Serial.print(", pstate=");
Serial.print(previousstate[index], DEC);
Serial.print(", press=");
*/
if (currentstate[index] == previousstate[index]) {
if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
// just pressed
justpressed[index] = 1;
}
else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
// just released
justreleased[index] = 1;
}
pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed
}
//Serial.println(pressed[index], DEC);
previousstate[index] = currentstate[index]; // keep a running tally of the buttons
}
}
/////////////////////////////////////////////////////
//This is Button 1 Press
/////////////////////////////////////////////////////
void loop() {
byte i;
static byte playing = 0;
if (justpressed[0]) {
if (currentSongcount != maxSongcount)
{
currentSongcount == currentSongcount ++;
} else
if (currentSongcount == maxSongcount){
currentSongcount = 1;
}
Serial.println(currentSongcount);
if (currentSongcount == 1) {
playfile("1.wav");
}
else if (currentSongcount == 2) {
playfile("2.wav");
}
else if (currentSongcount == 3) {
playfile("3.wav");
}
else if (currentSongcount == 4) {
playfile("4.wav");
}
if (! wave.isplaying) {
playing = 1;
}
if (currentSongcount == maxSongcount)
currentSongcount = 4;
justpressed[0] = 0;
}
/////////////////////////////////////////////////////
//This is Button 2 Press
/////////////////////////////////////////////////////
if (justpressed[1]) {
if (currentSongcount != minSongcount)
{
currentSongcount == currentSongcount --;
} else
if (currentSongcount == minSongcount){
currentSongcount = 1;
}
Serial.println(currentSongcount);
if (currentSongcount == 1) {
playfile("1.wav");
}
else if (currentSongcount == 2) {
playfile("2.wav");
}
else if (currentSongcount == 3) {
playfile("3.wav");
}
else if (currentSongcount == 4) {
playfile("4.wav");
}
if (! wave.isplaying) {
playing = 1;
}
if (currentSongcount == minSongcount)
currentSongcount = 5;
justpressed[1] = 0;
}
/////////////////////////////////////////////////////
//This is Button 3 Press
/////////////////////////////////////////////////////
if (justpressed[2] && wave.isplaying){
justpressed[2] = 0;
wave.pause();
paused = 1;
Serial.println("Paused");
}
/////////////////////////////////////////////////////
//This is Button 4 Press
/////////////////////////////////////////////////////
if (justpressed[3] && paused ==1){
justpressed[3] = 0;
wave.resume();
paused = 0;
Serial.println("Resume");
}
}
// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
// call our helper to find and play this name
playfile(name);
while (wave.isplaying)
{
// do nothing while its playing
Serial.println("Wave is Playing");
}
// now its done playing
}
void playfile(char *name) {
// see if the wave object is currently doing something
if (wave.isplaying) {// already playing something, so stop it!
wave.stop(); // stop it
Serial.println("Wave Stopped");
}
// look in the root directory and open the file
if (!f.open(root, name)) {
putstring("Couldn't open file "); Serial.print(name); return;
}
// OK read the file and turn it into a wave object
if (!wave.create(f)) {
putstring_nl("Not a valid WAV"); return;
}
// ok time to play! start playback
wave.play();
Serial.println("Next Wave is playing");
}
Please be positive and constructive with your questions and comments.