Waveshield 10sec & 20sec output pin low after wave.play

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
Hapmercian
 
Posts: 7
Joined: Tue Feb 10, 2015 6:23 pm

Waveshield 10sec & 20sec output pin low after wave.play

Post by Hapmercian »

Hi
I have the 6 button sketch running with the input/pullup resistors enabled on analog Pins A0-A5 wired to momentary buttons and all of the files are playing with the corresponding buttons. The override feature and the reset feature are also doing a good job and I need to keep them in the sketch in case a wrong button is pushed.
I've seemed to have tried different schemes but to no avail.
I am a beginner and really don't have a good grasp on the functions and how the all fit together with the proper syntax.
I have a total of four wav files but only need two tied to timers with values of 10 and 20 secs.
Output pin 11 needs LOW to energize a 5Vdc relay which switches 120Vac to an air solenoid.
I've tried delay, interrupts, tccr,etc. but my lack of experience just results in compiling errors.
Steve

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

#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[] = {A0, A1, A2, A3, A4, A5};
// 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(11, 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
  }
}


void loop() {
  byte i;
  
  if (justpressed[0]) {
    justpressed[0] = 0;
    wave.stop();
  }
  else if (justpressed[1]) {
      justpressed[1] = 0;
      playfile("rapid1mx.wav");
  }
  else if (justpressed[2]) {
      justpressed[2] = 0;
      playfile("rapid1w.wav");
  }
  else if (justpressed[3]) {
      justpressed[3] = 0;
      playfile("timed1mx.wav");
  } 
  else if (justpressed[4]) {
      justpressed[4] = 0;
      playfile("timed1w.wav");
  } 
  else if (justpressed[5]) {
      justpressed[5] = 0;
      playfile("LA.WAV");
  }
}



// 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
  }
  // 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
  }
  // 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();
Last edited by adafruit_support_mike on Wed Feb 11, 2015 12:00 am, edited 1 time in total.
Reason: added CODE tags to preserve formatting

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Waveshield 10sec & 20sec output pin low after wave.play

Post by adafruit_support_mike »

That kind of thing is easiest to do with state variables.. convenient places to hold information about what the system should be doing at any given time.

In this case, it sounds like you want a value that says whether the pin is currently down and one that says what it should be doing:

Code: Select all

boolean isDown  = false;
uint32_t goUpAt = 0;
You tell the system the pin should go down by setting the goUpAt value to some point in the future:


Code: Select all

    . . . 
  else if (justpressed[1]) {
      justpressed[1] = 0;
      playfile("rapid1mx.wav");
      
      goUpAt = millis() + 20000;
  }
    . . . 
Then decide what to do with pin 11 after deciding what song to play:

Code: Select all

    if ( millis() < goUpAt ) {
      //  pin 11 should be down
        if ( ! isDown ) {
            digitalWrite( 11, LOW );
            isDown = true;
        }
    } else {
      //  pin 11 should be up
        if ( isDown ) {
            digitalWrite( 11, HIGH );
            isDown = false;
            goUpAt = 0;  // clear the timer just to be sure
        }
    }

User avatar
Hapmercian
 
Posts: 7
Joined: Tue Feb 10, 2015 6:23 pm

Re: Waveshield 10sec & 20sec output pin low after wave.play

Post by Hapmercian »

Mike,
Hey, thanks for the swift reply.
I've screwed something up.
Pin 11 never turns off and the millis()+20000 where I've stuck it has no effect.
There were many iterations of the sketch not compiling before the one below would at least compile and upload.
It played fine, wave.stop fine and reset but no luck on the 10 and 20 second timing code.
More guidance is needed as to where to insert the lines of code and correct syntax if needed..
Steve

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

#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[] = {A0, A1, A2, A3, A4, A5};
// 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(11, 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
  }
}


void loop() {
  boolean isDown  = false;
  uint32_t goUpAt = 0;
  byte i;
  
  if (justpressed[0]) {
    justpressed[0] = 0;
    wave.stop();
  }
  else if (justpressed[1]) {
      justpressed[1] = 0;
      playfile("rapid1mx.wav");
 /////////////////////////// 20sec ////////////////   
      goUpAt = millis() + 20000;
 ////////////////////////////////////     
  }
    else if (justpressed[2]) {
      justpressed[2] = 0;
      playfile("rapid1w.wav");
    }
    if ( millis() < goUpAt ) {
      //  pin 11 should be down
        if ( ! isDown ) {
            digitalWrite( 11, LOW );
            isDown = true;   
    } 
      else 
      //  pin 11 should be up
       if ( isDown ) {
            digitalWrite( 11, HIGH );
            isDown = false;
            goUpAt = 0;  // clear the timer just to be sure
  }
  
 } else if (justpressed[3]) {
      justpressed[3] = 0;
      playfile("timed1mx.wav");
  } 
  else if (justpressed[4]) {
      justpressed[4] = 0;
      playfile("timed1w.wav");
  } 
  else if (justpressed[5]) {
      justpressed[5] = 0;
      playfile("LA.WAV");
  }
}



// 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
  }
  // 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
  }
  // 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();
}
Last edited by adafruit_support_mike on Wed Feb 11, 2015 7:40 pm, edited 1 time in total.
Reason: added CODE tags to preserve formatting

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Waveshield 10sec & 20sec output pin low after wave.play

Post by adafruit_support_mike »

You need to move this part:

Code: Select all

    if ( millis() < goUpAt ) {
      //  pin 11 should be down
        if ( ! isDown ) {
            digitalWrite( 11, LOW );
            isDown = true;   
    } 
      else 
      //  pin 11 should be up
       if ( isDown ) {
            digitalWrite( 11, HIGH );
            isDown = false;
            goUpAt = 0;  // clear the timer just to be sure
  }  
past the end of the if() else if() section where you choose which file to play.

The overall structure of the code should look like:

Code: Select all

loop () {
    check the switches
    if ( we should play a track ) {
        play the selected track
        set the timer for pin 11 if necessary
    }
    deal with pin 11
}

User avatar
Hapmercian
 
Posts: 7
Joined: Tue Feb 10, 2015 6:23 pm

Re: Waveshield 10sec & 20sec output pin low after wave.play

Post by Hapmercian »

Hey Mike,
I couldn't get Pin11 to go to sleep. I even swapped a new R3 board, measuring Pin11 first which was off until the WaveShield was plugged in.
I reread the Waveshield Manual and here's what I found (direct from the literature):
(Pins 13, 12, 11 are always used by the SD card(they are the only pins that have a high speed SPI interface). Then there are 5 other pins used to talk to the DAC and SD card, but they can be set to connect to any arduino pin. However, by default, the library is configured to use pins 10 (for SD card) and pins 2, 3, 4 and 5 for the DACey
That means pins 6, 7, 8, 9 and the 6 analog in pins (also known as digital i/o pins 14-20) are available)
I take from the above explaination why 5Vdc stays on Pin11. It can't be used as an OUTPUT.
Plus Pin12 has a half of a Vdc on it.
I did read those facts but clearly forgot.
Back to the drawing board.
Thanks again,
Steve

User avatar
Hapmercian
 
Posts: 7
Joined: Tue Feb 10, 2015 6:23 pm

Re: Waveshield 10sec & 20sec output pin low after wave.play

Post by Hapmercian »

Code: Select all

void loop() {
  byte i;
  //////////HERE'S WHERE I STUCK SOME NEW CODE/////////////////////
  boolean isDown  = false;
 uint32_t goUpAt = 0;

  /////////////////////END OF NEW CODE////////////////////////////////
  if (justpressed[0]) {
    justpressed[0] = 0;
    wave.stop();
  }
  else if (justpressed[1]) {
      justpressed[1] = 0;
      playfile("rapid1mx.wav");
  }
  else if (justpressed[2]) {
      justpressed[2] = 0;
      playfile("rapid1w.wav");
 //////////////HERE'S WHERE I STUCK SOME NEW CODE///////////////////     
      goUpAt = millis() + 10000;
          if ( millis() < goUpAt ) {
      //  pin 11 should be down
        if ( ! isDown ) {
            digitalWrite( 11, LOW );
            isDown = true;
        }
    } else {
      //  pin 11 should be up
        if ( isDown ) {
            digitalWrite( 11, HIGH );
            isDown = false;
            goUpAt = 0;  // clear the timer just to be sure
        }
    }
////////////////////////////END OF NEW CODE///////////////////////
  }
  else if (justpressed[3]) {
      justpressed[3] = 0;
      playfile("timed1mx.wav");
  } 
  else if (justpressed[4]) {
      justpressed[4] = 0;
      playfile("timed1w.wav");
  //////////HERE'S WHERE I STUCK SOME NEW CODE//////////////////    
     goUpAt = millis() + 20000;
       if ( millis() < goUpAt ) {
      //  pin 7 should be down
        if ( ! isDown ) {
            digitalWrite( 7, LOW );
            isDown = true;
        }
    } else {
      //  pin 7 should be up
        if ( isDown ) {
            digitalWrite( 7, HIGH );
            isDown = false;
            goUpAt = 0;  // clear the timer just to be sure
        }
    }
  
  } 
  //////////////////////END OF NEW CODE////////////////////////
  else if (justpressed[5]) {
      justpressed[5] = 0;
      playfile("LA.WAV");
  }
}
ok,
Changed the OUTPUT to 7, I think I put the new code in the proper places as indicated in your last post. It plays fine and buttons respond correctly but the 10 and 20sec timers code still does not take 7 low.
Steve
Last edited by adafruit_support_mike on Sun Feb 15, 2015 2:36 am, edited 1 time in total.
Reason: added CODE tags to preserve formatting

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Waveshield 10sec & 20sec output pin low after wave.play

Post by adafruit_support_mike »

It looks like you're doing something I call 'shotgunning'.. moving code around without knowing exactly what it will do in the new location.

It's an easy pattern to fall into, but it's a bad habit. The most common result is that you end up with bits and pieces of half ideas scattered all over the place, the code doesn't run, and you can't begin to figure out how to get back to the last working state.

Take a few minutes to think about what the snippets of code I posted do, and where it makes sense to put them in the code.

Take this chunk for instance:

Code: Select all

  else if (justpressed[2]) {
      justpressed[2] = 0;
      playfile("rapid1w.wav");
 //////////////HERE'S WHERE I STUCK SOME NEW CODE///////////////////     
      goUpAt = millis() + 10000;
          if ( millis() < goUpAt ) {
      //  pin 11 should be down
        if ( ! isDown ) {
            digitalWrite( 11, LOW );
            isDown = true;
        }
    } else {
      //  pin 11 should be up
        if ( isDown ) {
            digitalWrite( 11, HIGH );
            isDown = false;
            goUpAt = 0;  // clear the timer just to be sure
        }
    }
////////////////////////////END OF NEW CODE///////////////////////
The 'else if' condition at the top means everything inside the braces will only execute when a button has just been pressed. What effect does that have on this line:

Code: Select all

          if ( millis() < goUpAt ) {
and how does that relate to what you want the code to do?

User avatar
Hapmercian
 
Posts: 7
Joined: Tue Feb 10, 2015 6:23 pm

Re: Waveshield 10sec & 20sec output pin low after wave.play

Post by Hapmercian »

Greetings and salutations ,
I have pondered and pondered but it still is darker than a mystery,
The ...if ( millis() < goUpAt) says to me that this test will always be not true because goUpAt is set to 0 and the millis starts at 0 at power up and continues counting positive till it reaches its maximum value than resets to 0.
It also resets if the the board power is cycled off/on.
The millis will never be less than 0.
I don't know why the next goUpAt = millis() + 10000; does nothing.
Isn't millis going up positive? Isn't goUpAt = 0?
The timer function below the else if of the wav file selected by the button in the loop section of the code does not work for me.
I've tried multiple times. It compiles, uploads and runs but no timer function.,
The buttons and wav files perform flawlessly.
Thanks,
Steve

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Waveshield 10sec & 20sec output pin low after wave.play

Post by adafruit_support_mike »

The outer condition is the problem.

The code as you've written it only compares millis() to the variable goUpAt inside a block controlled by the condition "if (justpressed[2])". If you haven't just pressed button 2, nothing inside that block will execute on that pass through loop().

That's not what you want. You want pin 11 to go high a certain amount of time after the button has been released.

Where should you put the code that compares millis() to goUpAt if you don't want that to be controlled by the buttons?

User avatar
Hapmercian
 
Posts: 7
Joined: Tue Feb 10, 2015 6:23 pm

Re: Waveshield 10sec & 20sec output pin low after wave.play

Post by Hapmercian »

Hardy felicitations,
I have played and experimented with the bloody code trying to link millis and goUpAt to the playfile block instead of the justpressed loop. No timerfunction even if compile and upload are successful.
I cannot assemble any instructions to make this happen. I'm really frustrated.
I don't want to add 2 external hardwire timers for the cost factor.
I'm willing to pay a consultant for the lines needed to make my control box meet all the below requirements.
Anyone know someone willing to take this job?
I've been playing with the code for a month!! It ain't gonna happen.
Here's what's needed.
The buttons below can be pressed in any order.
Allow a new button push to override the old button push.
Allow for a stop play and reset.
Push button (1Whatever)...play .wav linked to that...no timer functions needed just push and play and then get ready for the next option.
.Push button( 2Whatever)..play .wav linked to that button no timer functions needed just push and play and then get ready for next option .
The code as written meets all those requirements.
Here's the functions I cannot make work no matter how much time spent or will be spent.
Push button (3Whatever) play .wav file linked to that button and upon completion of wave play start timer and turn pin7 on. Wait for 10000 and turn off pin7. Get ready for next option
Push button (4Whatever)play .wav file linked to that button and upon completion of wave play start timer and turn pin 7 on. Wait for 20000 and turn off pin7. Get ready for next option.
It just won't go and I've given up trying..
I've purchased 2 Waveshield boards with the intent of making 2 control boxes .
All of my hardware works as should.
Thanks
Steve
#include <elapsedMillis.h>
#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

#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[] = {
A0, A1, A2, A3, A4, A5};
// 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(7, OUTPUT);

// Make input & enable pull-up resistors on switch pins
for (i=0; i< NUMBUTTONS; i++) {
pinMode(buttons, INPUT);
digitalWrite(buttons, 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
}
}


void loop() {

byte i;
if (justpressed[0]) {
justpressed[0] = 0;
wave.stop();
}
else if (justpressed[1]) {
justpressed[1] = 0;//S2
playfile("rapid1mx.wav");
}
else if (justpressed[2]) {
justpressed[2] = 0;
playfile("rapid1w.wav");//S3buzzer
}
else if (justpressed[3]) {
justpressed[3] = 0;
playfile("timed1mx.wav");//S4
}
else if (justpressed[4]) {
justpressed[4] = 0;//S5 buzzer
playfile("timed1w.wav");

}
else if (justpressed[5]) {
justpressed[5] = 0;
playfile("LA.WAV");
}
}





// 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
}
// 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
}
// 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();

}

User avatar
Hapmercian
 
Posts: 7
Joined: Tue Feb 10, 2015 6:23 pm

Re: Waveshield 10sec & 20sec output pin low after wave.play

Post by Hapmercian »

Howdy All,
I contacted a retired friend (electrical engineer) with other programming language skills and through his generosity of time and patience we were able to put together the following code.
It works and is stable...
I hope this helps others because as we soon learned it was not just simply putting a line here in this block or a bit of logic there with a for or else statement etc..
HAVE FUN!!!
#include <elapsedMillis.h>
#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

#define DEBOUNCE 5 // button debouncer
int Targetturntimer = 0;
int Turntimevalue = 0;

// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {
A0, A1, A2, A3, A4, A5};
// 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 Not real important but I would change this to pin7 Solenoid
pinMode(7, OUTPUT);

// Make input & enable pull-up resistors on switch pins
for (i=0; i< NUMBUTTONS; i++) {
pinMode(buttons, INPUT);
digitalWrite(buttons, 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
}
}


void loop() {

byte i;


if (justpressed[0]) {
justpressed[0] = 0;
wave.stop();
Targetturntimer = 0;
}
else if (justpressed[1]) {
justpressed[1] = 0;//S2
Targetturntimer = 1;
Turntimevalue = 10000;
playfile("rapid1mx.wav");
}
else if (justpressed[2]) {
justpressed[2] = 0;
Targetturntimer = 0;
playfile("rapid1w.wav");//S3buzzer
}
else if (justpressed[3]) {
justpressed[3] = 0;
Targetturntimer = 1;
//Serial.print (Targetturntimer );
Turntimevalue = 20000;
//putstring_nl("Test!");
playfile("timed1mx.wav");//S4
}
else if (justpressed[4]) {
justpressed[4] = 0;//S5 buzzer
Targetturntimer = 0;
playfile("timed1w.wav");
}
else if (justpressed[5]) {
justpressed[5] = 0;
Targetturntimer = 0;
playfile("LA.WAV");
}

if (wave.isplaying) {
// putstring_nl("Test!");
//Serial.print (Targetturntimer == 1);
}
else {
//Serial.print (Targetturntimer );
if (Targetturntimer == 1) {
//Serial.print (TS("TestStopII!");
delay (3000) ; //Wait 3 seconds before turning targets
digitalWrite(7,1) ; //Turn on solenoid output
delay (Turntimevalue); //have targets turned for Rapid or Timed delay
digitalWrite(7,0) ; //Turn off solenoid output
Targetturntimer = 0;
}
}

}


// 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
}
// 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
}
// 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();

}

.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”