Waveshield, almost there

Hi there,

I am almost there where I wanna be. I have a wave shield on an Arduino Uno. I do get the .wav files to play randomly (unfortunately it plays them all randomly and not just one, but is not the most important question).
I am still struggling with the servo. During my investigation I discovered that you can't include the wave.hc library and the servo library (they use both the build in timer?!). I also discovered that you can work with a servo, without really mention it in the code. I connected a wire form R7 of the wave shield (the voltage change with the volume of the sound) and connect it on an analog port (A5). Then put ( 8 ) as pwm output. This seems to work... so now and then.
Can somebody check my code and see if this is 'a' way to do it? Should I still convert the incomming voltage to a digital output? Any advice is welcome.
The lines which I used for the servo are marked with //servo test. (two lines in the beginning, one line under void setup() and a few almost at the end.

Thanks in advance

[code]
 #include <FatReader.h>
   #include <SdReader.h>
   #include <avr/pgmspace.h>
   #include "WaveUtil.h"
   #include "WaveHC.h"   

   int songCount = 9;   // total of .WAV files

   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 eyeLedsPin = 12;   //Toegevoegd
   
   //servo test
   const int pwm = 8;     //naming pin 8 as 'pwm' variable
   const int adc = 5;     //naming pin 5 of analog input side as 'adc'
     
   
   // 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() {
     Serial.begin(9600);             // set up serial library at 9600 bps for debugging
     putstring_nl("WaveHC with 1 button");
   
      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);
     //servo test
     pinMode(pwm,OUTPUT);           //setting pin 8 as output (denk wvt. aan { } toepassen)

     // pin12 LED
     pinMode(12, OUTPUT);   //Led eyes (Misschien A4, aangestuurd door volt uitlezing

     randomSeed(analogRead(0)); //Pin A0 niet benutten, geeft randomfunctie door interferentie?

       //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 ("Files found (* = fragmented):"); //("Ready!");
     root.ls(LS_R | LS_FLAG_FRAGMENTED);
   }
       
   void loop() {
    int songNumber = random(songCount+1);
    Serial.println(songNumber);
    switch(songNumber)

    {
      case 0:
        playcomplete("GHSTBRTH.WAV");
        break;
      case 1:
        playcomplete("BLFMTJPT.WAV");
        break;
      case 2:
        playcomplete("MTJNMDR.WAV");
        break;
      case 3:
        playcomplete("YCNNTLV.WAV");
        break;
      case 4:
        playcomplete("DRCLLGH.WAV");
        break;
      case 5:
        playcomplete("HWMTJHR.WAV");
        break;
      case 6:
        playcomplete("SCRCRW.WAV");
        break;
      case 7:
        playcomplete("WEREWOLF.WAV");
        break;
      case 8:
        playcomplete("KNCKKNCK");
        break;
        
    }
    
  

    
  }

   // 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) {
     // Servo test (old remark:do nothing while its playing)
     {
      int adc = analogRead(50) ;       //analog voltage and storing it in an integer
      adc = map(adc, 0, 1023, 0, 255); //keep it between 0, 255
/* ----------map funtion------------the above funtion scales the output of adc, which is 10 bit and gives values btw 0 to 1023, in values btw 0 to 255 form analogWrite funtion which only receives values btw this range 
*/ 
analogWrite(pwm,adc) ; 
  }
     }
     // 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();
   }

[/code]

Your code does not match your description. inside playcomplete(), you declare a new, local variable called adc which has nothing to do with your global variable called adc. You then do an analog read on pin 50 which a Uno does not have so you are getting random garbage.

Don't confuse your pin assignments with the value you get from reading those pins

const int adcPin = A5;
const int pwmPin = 8;
....
playcomplete() {
  int adcValue = anlaogRead(adcPin);
  adcValue = map(adcValue, 0, 1023, 0, 255); //keep it between 0, 255
  // another method is adcValue /= 4;
  analogWrite(pwmPin, adcValue );
...

Thanks blh6y4,

Your code does not match your description. inside playcomplete(), you declare a new, local variable called adc which has nothing to do with your global variable called adc. You then do an analog read on pin 50 which a Uno does not have so you are getting random garbage.

Thanks for your reply. I think that was a typo, in this line
int adc = analogRead(50) ;      //analog voltage and storing it in an integer
the (50) should be (5) refering to the analog pin A5 in this line

const int adc = 5;     //naming pin 5 of analog input side as 'adc'

If I understand well, I should replace

{
      int adc = analogRead(50) ;       //analog voltage and storing it in an integer
      adc = map(adc, 0, 1023, 0, 255); //keep it between 0, 255
/* ----------map funtion------------the above funtion scales the output of adc, which is 10 bit and gives values btw 0 to 1023, in values btw 0 to 255 form analogWrite funtion which only receives values btw this range
*/
analogWrite(pwm,adc) ;

for this line

int adcValue = anlaogRead(adcPin);
  adcValue = map(adcValue, 0, 1023, 0, 255); //keep it between 0, 255
 // another method is adcValue /= 4;
  analogWrite(pwmPin, adcValue );

What I don't understand is, what do you exactly mean by

// another method is adcValue /= 4;

I don't know how to interpret this, what does '=4' mean?

At the moment I am at nightshift, so can't work with the code. I will try it hopefully tomorrow.

Thanks again.

KERI:
What I don't understand is, what do you exactly mean by

// another method is adcValue /= 4;

I don't know how to interpret this, what does '=4' mean?

At the moment I am at nightshift, so can't work with the code. I will try it hopefully tomorrow.

Thanks again.

it is shorthand notation for

adcValue = adcValue / 4;
[code]
Whenever you are doing some mathematical operation on a variable and want to assign the result back to the same variable you can use this
[code]
a += 1; // same as a=a+1
a -= 1; // a=a-1
a *= 1; // a = a *1

and since you are mapping 0-1023 to 0-255 it is divide by 4.

Thanks for your help so far, blh64.

Hello everyone,

What do i accomplished so far: the pieces between (....) is what I have troubles with.
(when powerd up, Case 7 should play in a loop) A coffins opens -activated externally-, a skeleton jumps out, a switch will be activated and start playing a spooky spoken sentence -(ONE of the other Cases- randomly chosen). (when the file is finished, the shield should go back to Case 7, playing in a loop until the switch is activated again).

What I want is that the waveshield plays -when powered up- one file (Case 7 @ the bottom of this sketch) in a loop.

When a switch is activated, this file (Case 7) stops playing and ONE of the other files (just one), randomly choosen, play's, and then stops, the skelleton falles back in the coffin -not inplemented yet in this sketch) and Case 7 starts again playing in a loop until the button is pressed again.

At this moment the waveshield waits for the switch to be activated and then plays all the available files randomly and doesn't stop.

I opt-out some of the Cases, because the are just sound, no spoken words and therefore not interested for this.

If it is to harsh, I forget the random choosen file and play just one file after the switch is activated.

I tried different things, all the availble example from adafruit, but I am stuck and lost in all the trials.

Thanks for any help and happy Halloween.

//combine waveshield and servo.h replaced by servoTimer2-master test with button

#include <ServoTimer2.h>
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"

int songCount = 7;    // total af .WAV files

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

uint8_t dirLevel; // indent level for file/dir names    (for prettyprinting)
dir_t dirBuf;     // buffer for directory reads

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

//constant
          //Test servo
ServoTimer2 servo1;
const int soundPin = 4;     // analog pin used to connect the + form jack bus
const int ledPin = 11;      // output for the eyes

// for pushbutton
const int pushbuttonPin = 7;      // choose the input pin for pushbutton
//int pirState = LOW;             // we start, assuming no motion detected
//int val = 0;                    // variable for reading the pin statu
const int servoPin = 9;

//variables
int minPulse =   750; // minimum servo position
int maxPulse     = 2250; // maximum servo position
int pulse = 0;
int turnRate     =  1800;  // servo turn rate increment (larger value, faster rate)
int refreshTime  =  500;   // time (ms) between pulses (50Hz)
int mouthchange = 6;  //checks to see if mouth position needs to be changed

long lastPulse   = 0;   // recorded time (ms) of the last pulse
int analogValue = 0;
int analogPin = 1;

#define DEBOUNCE 100  // button debouncer

// 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() {
  // set up serial port
  Serial.begin(9600);
  putstring_nl("WaveHC with 1 button");
  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);

   // set up servo pin
  servo1.attach(9);                       // attaches the servo on pin 9 to jaw servo
  pinMode (pushbuttonPin, INPUT_PULLUP);  // switch
  pinMode (ledPin, OUTPUT);               // eyeleds

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

void loop() {
  if (digitalRead(pushbuttonPin) == HIGH)
  {
  int songNumber = random(songCount + 1);
  Serial.println(songNumber);
  switch (songNumber)

  {
    case 0:
      playcomplete("BLFMTJPX.WAV");
      break;
    case 1:
      playcomplete("BLFMTJPT.WAV");
      break;
    case 2:
      playcomplete("MTJNMDR.WAV");
      break;
    case 3:
      playcomplete("YCNNTLV.WAV");
      break;
   /* case 4:
      playcomplete("DRCLLGH.WAV");
      break;*/
    case 5:
      playcomplete("HWMTJHR.WAV");
      break;
   /* case 6:
      playcomplete("SCRCRW.WAV");
      break;
      case 7:
      playcomplete("KNCKKNCK.WAV");
      break;*/
  }

  }
}

// 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) {

    {
      int sound = (analogRead(soundPin) * 8);   //Original value is 8
      Serial. println(sound);
      int LEDValue = map (sound, 0, 1023, 0, 255);
      analogWrite (ledPin, LEDValue);

      if (LEDValue <= 1)
      {
        analogWrite (ledPin, LOW);
      }
      int pos = map (sound, 0, 512, 30, 200);   //scale it to use it with the jaw movement
      servo1.write(pos);                        //set the jaw position according to the scaled value
      delay(200);          //Wait for the servo to get there (delete it if troubles)

    }

    if (millis() - lastPulse >= refreshTime)

    digitalWrite(servoPin, HIGH);   // start the pulse
    delayMicroseconds(pulse);       // pulse width
    digitalWrite(servoPin, LOW);    // stop the pulse
    lastPulse = millis();
    // 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();
}