Wave Shield not going fast enough

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
drummer102
 
Posts: 9
Joined: Tue Sep 24, 2013 11:31 pm

Wave Shield not going fast enough

Post by drummer102 »

OK, so I've built a laser harp that has 12 beams that shine onto photo-resistors, and using the wave shield when the beam is broken it makes a noise. When the code is used on a breadboard with 12 buttons it worked fine. Our problem is when uploaded to the harp the delay between breaking the beam and a noise being played is slow, and when switching beams the transfer time is even slower. So in essence we can barely manage 1/8 notes. Do you have any ideas for why this is so slow. When I uploaded a basic code that turns on a LED when the beam is broken, the speed at which the Arduino could comprehend was definitely fast enough. My only idea is that the code reads "just released" when there is absolutely no light shown onto the sensor so it takes a little bit of time for the sensor to read completely dark. Any ideas.

photo-resistors- number 20, it's 5k http://www.futurlec.com/Photocells.shtml

Code: Select all

//12 string Laser Harp


/* Analog 0 and A1 have 2 sensors set up
while pins 6, 7, 8, 9, A3, A4, A5 are digital pins
with only one photocell attached  
*/
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"
#include <Wire.h>

int time = 500;

int isButtonBeingPushed1 = 0;   
int oneShotMode1 = 1; // 1 = oneshot mode on, 0 = oneshot mode off
byte buttonStateRaw1;

int isButtonBeingPushed2 = 0;   
int oneShotMode2 = 1; // 1 = oneshot mode on, 0 = oneshot mode off
byte buttonStateRaw2;

int buttonState1;
int buttonState2;

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[] = {6, 7, 8, 9, 16, 17, 18, 19};
// 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
  }
}


void loop() {


  // check the button state
  buttonStateRaw1 = Wire.read();                                        //---------------------------------------------Anaolog0----------------------------------------------------
  delayMicroseconds(3);
 
 if(buttonStateRaw1 == 1 && isButtonBeingPushed1 == 0)           
 {
     isButtonBeingPushed1 = 1;
   
   if(oneShotMode1 == 1)
   {
     oneShotMode1 = 0;
  }
   else if(oneShotMode1 == 0)
   {
     oneShotMode1 = 1;
   }
   delay(DEBOUNCE);
 }
 else if(buttonStateRaw1 == 0 )
  {
       isButtonBeingPushed1 = 0; 
  }
   unsigned long timeSinceButtonPush1;                          
  
   // 4 buttons on analog pin 0
  int analog0;
  analog0 = analogRead(0);
  delay(2);
  // Serial.print("analog 0: ");
   // Serial.println(analog0);
  timeSinceButtonPush1;
  if(analog0 > 100 && analog0 < 300) // button1
  {
    buttonState1 = 1;
    playfile("9.WAV");
    while (wave.isplaying && analog0 > 100 && analog0 < 300)
    analog0 = analogRead(0); 
    buttonState1 = 0;
  }
  wave.stop();
 
  if (analog0 > 300 && analog0 < 370) // button 2
  {

    buttonState1 = 1;
    playfile("10.WAV");
    while (wave.isplaying && analog0 > 300 && analog0 < 370)
    analog0 = analogRead(0);
    buttonState1 = 0;
    
  }
  wave.stop();
  

  //------------------------------------------------------------First analog switch-------------------------------------------------
  buttonStateRaw2 = Wire.read();                                        //---------------------------------------------Anaolog0----------------------------------------------------
  delayMicroseconds(3);
 
 if(buttonStateRaw2 == 1 && isButtonBeingPushed2 == 0)           
 {
     isButtonBeingPushed2 = 1;
   
   if(oneShotMode2 == 1)
   {
     oneShotMode2 = 0;
  }
   else if(oneShotMode2 == 0)
   {
     oneShotMode2 = 1;
   }
   delay(DEBOUNCE);
 }
 else if(buttonStateRaw2 == 0 )
  {
       isButtonBeingPushed2 = 0; 
  }
   unsigned long timeSinceButtonPush2;                          
  
   // 4 buttons on analog pin 0
  int analog1;
  analog1 = analogRead(1);
  delay(2);
  // Serial.print("analog 0: ");
   // Serial.println(analog0);
  timeSinceButtonPush2;
  if(analog1 > 150 && analog1 < 340) // button1
  {
    buttonState2 = 1;
    playfile("11.WAV");
    while (wave.isplaying && analog1 > 150 && analog1 < 340)
    analog1 = analogRead(1); 
    buttonState2 = 0;
  }
  wave.stop();
 
  if (analog1 > 340 && analog1 < 395) // button 2
  {

    buttonState2 = 1;
    playfile("12.WAV");
    while (wave.isplaying && analog1 > 340 && analog1 < 395)
    analog1 = analogRead(1);
    buttonState2 = 0;
    
  }
  wave.stop();
  //--------------------------------------------------------------------2nd analog switch------------------------
  byte i;

  if (justreleased[0]) {
    justpressed[0] = 0;
    playfile("1.WAV");
    while (wave.isplaying && pressed[0]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
  if (justreleased[1]) {
    justpressed[1] = 0;
    playfile("2.WAV");
    while (wave.isplaying && pressed[1]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
  if (justreleased[2]) {
    justpressed[2] = 0;
    playfile("5.WAV");
    while (wave.isplaying && pressed[2]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
  if (justreleased[3]) {
    justpressed[3] = 0;
    playfile("6.WAV");
    while (wave.isplaying && pressed[3]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
  if (justreleased[4]) {
    justpressed[4] = 0;
    playfile("3.WAV");
    while (wave.isplaying && pressed[4]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
  if (justreleased[5]) {
    justpressed[5] = 0;
    playfile("4.WAV");
    while (wave.isplaying && pressed[5]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
  if (justreleased[6]) {
    justpressed[6] = 0;
    playfile("7.WAV");
    while (wave.isplaying && pressed[6]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
  if (justreleased[7]) {
    justpressed[7] = 0;
    playfile("8.WAV");
    while (wave.isplaying && pressed[7]) {
      //Serial.print(".");
    }
    wave.stop();    
  }
}


// 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
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Wave Shield not going fast enough

Post by adafruit_support_mike »

There are too many free variables in play to decide where the problem lies.

I'd suggest dropping back to a simpler version of your break-beam code. Use the Serial monitor or an LED to benchmark the response times for a single beam, then multiple beams. If the audio worked for physical switches, I'd say you have a sensor issue.

drummer102
 
Posts: 9
Joined: Tue Sep 24, 2013 11:31 pm

Re: Wave Shield not going fast enough

Post by drummer102 »

So, I found the problem, and I have no idea how that fixed it. I followed what you said by bringing it down to the smallest scale possible. So I had the harp running with only two strings with the code from the wave shield examples. Well it turns out that the problem was in my code I chose the option of

Code: Select all

 if (justreleased[0]) {
When I changed it to

Code: Select all

 if (justpressed[0]) {
on all of the beams, it worked. Strange :roll:

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

Re: Wave Shield not going fast enough

Post by adafruit_support_mike »

Minor changes to a body of code can have a bit impact on performance.

As a rule, humans tend to be very bad at predicting code performance on a strictly heuristic basis. An hour's worth of simplified tests will give you more useful information than a week of speculation. ;-)

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

Return to “Arduino Shields from Adafruit”