Due to high demand, expect some shipping delays at this time - orders may not ship for up to 2-3 business days.
0

wave shield
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

wave shield

by geostain on Sun Jan 10, 2016 7:30 am

is it possible to combine the https://learn.adafruit.com/system/assets/assets/000/010/347/original/wavehc_play6interloop.pde.txt and the SampleRateHc sketces together?? i need both in 1 , so i can trigger a .wav with a button and at the same time change its pitch ??

geostain
 
Posts: 26
Joined: Tue Dec 22, 2015 1:53 pm

Re: wave shield

by adafruit_support_rick on Sun Jan 10, 2016 9:49 am

Please see this section of the tutorial:
https://learn.adafruit.com/wave-shield- ... ger-keypad

You can trigger sounds with a button and have the pitch change

adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: wave shield

by geostain on Sun Jan 10, 2016 6:27 pm

i dont want to use a keypad. i need 8 pushbuttons.
i tried to delete the keypad and microphone code and paste the 6 button code from the example but getting errors and cant make it work!

geostain
 
Posts: 26
Joined: Tue Dec 22, 2015 1:53 pm

Re: wave shield

by adafruit_support_rick on Mon Jan 11, 2016 10:46 am

OK - it's not entirely straighforward.
Try this:
Code: Select all | TOGGLE FULL SIZE
/*
ADAVOICE is an Arduino-based voice pitch changer plus WAV playback.
Fun for Halloween costumes, comic convention getups and other shenanigans!

Hardware requirements:
 - Arduino Uno, Duemilanove or Diecimila (not Mega or Leonardo compatible).
 - Adafruit Wave Shield
 - Speaker attached to Wave Shield output
 - Battery for portable use
If using the voice pitch changer, you will also need:
 - Adafruit Microphone Breakout
 - 10K potentiometer for setting pitch (or hardcode in sketch)
If using the WAV playback, you will also need:
 - SD card
 - Keypad, buttons or other sensor(s) for triggering sounds
Software requirements:
 - WaveHC library for Arduino
 - Demo WAV files on FAT-formatted SD card

This example sketch uses a 3x4 keypad for triggering sounds...but with
some changes could be adapted to use several discrete buttons, Hall effect
sensors, force-sensing resistors (FSRs), I2C keypads, etc. (or if you just
want the voice effect, no buttons at all).

Connections:
 - 3.3V to mic amp+, 1 leg of potentiometer and Arduino AREF pin
 - GND to mic amp-, opposite leg of potentiometer
 - Analog pin 0 to mic amp output
 - Analog pin 1 to center tap of potentiometer
 - Wave Shield output to speaker or amplifier
 - Matrix is wired to pins A2, A3, A4, A5 (rows) and 6, 7, 8 (columns)
 - Wave shield is assumed wired as in product tutorial

Potentiometer sets playback pitch.  Pitch adjustment does NOT work in
realtime -- audio sampling requires 100% of the ADC.  Pitch setting is
read at startup (or reset) and after a WAV finishes playing.

POINT SPEAKER AWAY FROM MIC to avoid feedback.

Written by Adafruit industries, with portions adapted from the
'PiSpeakHC' sketch included with WaveHC library.
*/

#include <WaveHC.h>
#include <WaveUtil.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 volumes root directory
FatReader file;  // This object represent the WAV file for a pi digit or period
WaveHC    wave;  // This is the only wave (audio) object, -- we only play one at a time
#define error(msg) error_P(PSTR(msg))  // Macro allows error messages in flash memory

#define ADC_CHANNEL 0 // Microphone on Analog pin 0

// Wave shield DAC: digital pins 2, 3, 4, 5
#define DAC_CS_PORT    PORTD
#define DAC_CS         PORTD2
#define DAC_CLK_PORT   PORTD
#define DAC_CLK        PORTD3
#define DAC_DI_PORT    PORTD
#define DAC_DI         PORTD4
#define DAC_LATCH_PORT PORTD
#define DAC_LATCH      PORTD5

uint16_t in = 0, out = 0, xf = 0, nSamples; // Audio sample counters
uint8_t  adc_save;                          // Default ADC mode

// WaveHC didn't declare it's working buffers private or static,
// so we can be sneaky and borrow the same RAM for audio sampling!
extern uint8_t
  buffer1[PLAYBUFFLEN],                   // Audio sample LSB
  buffer2[PLAYBUFFLEN];                   // Audio sample MSB
#define XFADE     16                      // Number of samples for cross-fade
#define MAX_SAMPLES (PLAYBUFFLEN - XFADE) // Remaining available audio samples

// button information:

uint8_t buttonList[] = {14, 15, 16, 17, 18, 19};
#define NUM_BUTTONS (sizeof(buttonList)/sizeof(uint8_t))

// Kbutton/WAV information.  Number of elements here should match the
// number of buttons
const char *sound[] = {
  "breath" , "destroy", "saber", // pins 14, 15, 16
  "zilla"  , "crunch" , "burp",  // pins 17, 18, 19
  "startup" };                   // Extra item = boot sound


//////////////////////////////////// SETUP

void setup() {
  uint8_t i;

  Serial.begin(9600);           

  // The WaveHC library normally initializes the DAC pins...but only after
  // an SD card is detected and a valid file is passed.  Need to init the
  // pins manually here so that voice FX works even without a card.
  pinMode(2, OUTPUT);    // Chip select
  pinMode(3, OUTPUT);    // Serial clock
  pinMode(4, OUTPUT);    // Serial data
  pinMode(5, OUTPUT);    // Latch
  digitalWrite(2, HIGH); // Set chip select high

  // enable pull-up resistors on button pins
  for (int b = 0; b < NUM_BUTTONS; b++)
    pinMode(buttonList[b], INPUT_PULLUP);


  // Init SD library, show root directory.  Note that errors are displayed
  // but NOT regarded as fatal -- the program will continue with voice FX!
  if(!card.init())             SerialPrint_P("Card init. failed!");
  else if(!vol.init(card))     SerialPrint_P("No partition!");
  else if(!root.openRoot(vol)) SerialPrint_P("Couldn't open dir");
  else {
    PgmPrintln("Files found:");
    root.ls();
    // Play startup sound (last file in array).
    playfile(sizeof(sound) / sizeof(sound[0]) - 1);
  }

  // Optional, but may make sampling and playback a little smoother:
  // Disable Timer0 interrupt.  This means delay(), millis() etc. won't
  // work.  Comment this out if you really, really need those functions.
  TIMSK0 = 0;

  // Set up Analog-to-Digital converter:
  analogReference(EXTERNAL); // 3.3V to AREF
  adc_save = ADCSRA;         // Save ADC setting for restore later

  while(wave.isplaying); // Wait for startup sound to finish...
  startPitchShift();     // and start the pitch-shift mode by default.
}


//////////////////////////////////// LOOP

// As written here, the loop function scans a keypad to triggers sounds
// (stopping and restarting the voice effect as needed).  If all you need
// is a couple of buttons, it may be easier to tear this out and start
// over with some simple digitalRead() calls.

void loop() {
   // examine  buttons for a match...
  for(int b=0; b<NUM_BUTTONS; b++) {
    if(debounceRead(buttonList[b]) == LOW) { // First match.
      if(wave.isplaying)
        wave.stop();      // Stop current WAV (if any)
      else               stopPitchShift(); // or stop voice effect
        playfile(b);                    // and play new sound.
      while (debounceRead(buttonList[b]) == LOW);  // Wait for button release.
    }
  }

  if(!wave.isplaying && !(TIMSK2 & _BV(TOIE2))) startPitchShift();
}


//////////////////////////////////// HELPERS

uint8_t debounceRead(int pin)
{
  uint8_t pinState = digitalRead(pin);
  uint32_t timeout = millis();
  while ((millis() - timeout) < 10)
  {
    if (digitalRead(pin) != pinState)
    {
      pinState = digitalRead(pin);
      timeout = millis();
    }
  }

  return pinState;
}

// Open and start playing a WAV file
void playfile(int idx) {
  char filename[13];

  (void)sprintf(filename,"%s.wav", sound[idx]);
  Serial.print("File: ");
  Serial.println(filename);

  if(!file.open(root, filename)) {
    PgmPrint("Couldn't open file ");
    Serial.print(filename);
    return;
  }
  if(!wave.create(file)) {
    PgmPrintln("Not a valid WAV");
    return;
  }
  wave.play();
}


//////////////////////////////////// PITCH-SHIFT CODE

void startPitchShift() {

  // Read analog pitch setting before starting audio sampling:
  int pitch = analogRead(1);
  Serial.print("Pitch: ");
  Serial.println(pitch);

  // Right now the sketch just uses a fixed sound buffer length of
  // 128 samples.  It may be the case that the buffer length should
  // vary with pitch for better results...further experimentation
  // is required here.
  nSamples = 128;
  //nSamples = F_CPU / 3200 / OCR2A; // ???
  //if(nSamples > MAX_SAMPLES)      nSamples = MAX_SAMPLES;
  //else if(nSamples < (XFADE * 2)) nSamples = XFADE * 2;

  memset(buffer1, 0, nSamples + XFADE); // Clear sample buffers
  memset(buffer2, 2, nSamples + XFADE); // (set all samples to 512)

  // WaveHC library already defines a Timer1 interrupt handler.  Since we
  // want to use the stock library and not require a special fork, Timer2
  // is used for a sample-playing interrupt here.  As it's only an 8-bit
  // timer, a sizeable prescaler is used (32:1) to generate intervals
  // spanning the desired range (~4.8 KHz to ~19 KHz, or +/- 1 octave
  // from the sampling frequency).  This does limit the available number
  // of speed 'steps' in between (about 79 total), but seems enough.
  TCCR2A = _BV(WGM21) | _BV(WGM20); // Mode 7 (fast PWM), OC2 disconnected
  TCCR2B = _BV(WGM22) | _BV(CS21) | _BV(CS20);  // 32:1 prescale
  OCR2A  = map(pitch, 0, 1023,
    F_CPU / 32 / (9615 / 2),  // Lowest pitch  = -1 octave
    F_CPU / 32 / (9615 * 2)); // Highest pitch = +1 octave

  // Start up ADC in free-run mode for audio sampling:
  DIDR0 |= _BV(ADC0D);  // Disable digital input buffer on ADC0
  ADMUX  = ADC_CHANNEL; // Channel sel, right-adj, AREF to 3.3V regulator
  ADCSRB = 0;           // Free-run mode
  ADCSRA = _BV(ADEN) |  // Enable ADC
    _BV(ADSC)  |        // Start conversions
    _BV(ADATE) |        // Auto-trigger enable
    _BV(ADIE)  |        // Interrupt enable
    _BV(ADPS2) |        // 128:1 prescale...
    _BV(ADPS1) |        //  ...yields 125 KHz ADC clock...
    _BV(ADPS0);         //  ...13 cycles/conversion = ~9615 Hz

  TIMSK2 |= _BV(TOIE2); // Enable Timer2 overflow interrupt
  sei();                // Enable interrupts
}

void stopPitchShift() {
  ADCSRA = adc_save; // Disable ADC interrupt and allow normal use
  TIMSK2 = 0;        // Disable Timer2 Interrupt
}

ISR(ADC_vect, ISR_BLOCK) { // ADC conversion complete

  // Save old sample from 'in' position to xfade buffer:
  buffer1[nSamples + xf] = buffer1[in];
  buffer2[nSamples + xf] = buffer2[in];
  if(++xf >= XFADE) xf = 0;

  // Store new value in sample buffers:
  buffer1[in] = ADCL; // MUST read ADCL first!
  buffer2[in] = ADCH;
  if(++in >= nSamples) in = 0;
}

ISR(TIMER2_OVF_vect) { // Playback interrupt
  uint16_t s;
  uint8_t  w, inv, hi, lo, bit;
  int      o2, i2, pos;

  // Cross fade around circular buffer 'seam'.
  if((o2 = (int)out) == (i2 = (int)in)) {
    // Sample positions coincide.  Use cross-fade buffer data directly.
    pos = nSamples + xf;
    hi = (buffer2[pos] << 2) | (buffer1[pos] >> 6); // Expand 10-bit data
    lo = (buffer1[pos] << 2) |  buffer2[pos];       // to 12 bits
  } if((o2 < i2) && (o2 > (i2 - XFADE))) {
    // Output sample is close to end of input samples.  Cross-fade to
    // avoid click.  The shift operations here assume that XFADE is 16;
    // will need adjustment if that changes.
    w   = in - out;  // Weight of sample (1-n)
    inv = XFADE - w; // Weight of xfade
    pos = nSamples + ((inv + xf) % XFADE);
    s   = ((buffer2[out] << 8) | buffer1[out]) * w +
          ((buffer2[pos] << 8) | buffer1[pos]) * inv;
    hi = s >> 10; // Shift 14 bit result
    lo = s >> 2;  // down to 12 bits
  } else if (o2 > (i2 + nSamples - XFADE)) {
    // More cross-fade condition
    w   = in + nSamples - out;
    inv = XFADE - w;
    pos = nSamples + ((inv + xf) % XFADE);
    s   = ((buffer2[out] << 8) | buffer1[out]) * w +
          ((buffer2[pos] << 8) | buffer1[pos]) * inv;
    hi = s >> 10; // Shift 14 bit result
    lo = s >> 2;  // down to 12 bits
  } else {
    // Input and output counters don't coincide -- just use sample directly.
    hi = (buffer2[out] << 2) | (buffer1[out] >> 6); // Expand 10-bit data
    lo = (buffer1[out] << 2) |  buffer2[out];       // to 12 bits
  }

  // Might be possible to tweak 'hi' and 'lo' at this point to achieve
  // different voice modulations -- robot effect, etc.?

  DAC_CS_PORT &= ~_BV(DAC_CS); // Select DAC
  // Clock out 4 bits DAC config (not in loop because it's constant)
  DAC_DI_PORT  &= ~_BV(DAC_DI); // 0 = Select DAC A, unbuffered
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  DAC_DI_PORT  |=  _BV(DAC_DI); // 1X gain, enable = 1
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  for(bit=0x08; bit; bit>>=1) { // Clock out first 4 bits of data
    if(hi & bit) DAC_DI_PORT |=  _BV(DAC_DI);
    else         DAC_DI_PORT &= ~_BV(DAC_DI);
    DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  }
  for(bit=0x80; bit; bit>>=1) { // Clock out last 8 bits of data
    if(lo & bit) DAC_DI_PORT |=  _BV(DAC_DI);
    else         DAC_DI_PORT &= ~_BV(DAC_DI);
    DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  }
  DAC_CS_PORT    |=  _BV(DAC_CS);    // Unselect DAC

  if(++out >= nSamples) out = 0;
}

adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: wave shield

by geostain on Tue Jan 12, 2016 7:19 am

adafruit_support_rick wrote:OK - it's not entirely straighforward.
Try this:
Code: Select all | TOGGLE FULL SIZE
/*
ADAVOICE is an Arduino-based voice pitch changer plus WAV playback.
Fun for Halloween costumes, comic convention getups and other shenanigans!

Hardware requirements:
 - Arduino Uno, Duemilanove or Diecimila (not Mega or Leonardo compatible).
 - Adafruit Wave Shield
 - Speaker attached to Wave Shield output
 - Battery for portable use
If using the voice pitch changer, you will also need:
 - Adafruit Microphone Breakout
 - 10K potentiometer for setting pitch (or hardcode in sketch)
If using the WAV playback, you will also need:
 - SD card
 - Keypad, buttons or other sensor(s) for triggering sounds
Software requirements:
 - WaveHC library for Arduino
 - Demo WAV files on FAT-formatted SD card

This example sketch uses a 3x4 keypad for triggering sounds...but with
some changes could be adapted to use several discrete buttons, Hall effect
sensors, force-sensing resistors (FSRs), I2C keypads, etc. (or if you just
want the voice effect, no buttons at all).

Connections:
 - 3.3V to mic amp+, 1 leg of potentiometer and Arduino AREF pin
 - GND to mic amp-, opposite leg of potentiometer
 - Analog pin 0 to mic amp output
 - Analog pin 1 to center tap of potentiometer
 - Wave Shield output to speaker or amplifier
 - Matrix is wired to pins A2, A3, A4, A5 (rows) and 6, 7, 8 (columns)
 - Wave shield is assumed wired as in product tutorial

Potentiometer sets playback pitch.  Pitch adjustment does NOT work in
realtime -- audio sampling requires 100% of the ADC.  Pitch setting is
read at startup (or reset) and after a WAV finishes playing.

POINT SPEAKER AWAY FROM MIC to avoid feedback.

Written by Adafruit industries, with portions adapted from the
'PiSpeakHC' sketch included with WaveHC library.
*/

#include <WaveHC.h>
#include <WaveUtil.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 volumes root directory
FatReader file;  // This object represent the WAV file for a pi digit or period
WaveHC    wave;  // This is the only wave (audio) object, -- we only play one at a time
#define error(msg) error_P(PSTR(msg))  // Macro allows error messages in flash memory

#define ADC_CHANNEL 0 // Microphone on Analog pin 0

// Wave shield DAC: digital pins 2, 3, 4, 5
#define DAC_CS_PORT    PORTD
#define DAC_CS         PORTD2
#define DAC_CLK_PORT   PORTD
#define DAC_CLK        PORTD3
#define DAC_DI_PORT    PORTD
#define DAC_DI         PORTD4
#define DAC_LATCH_PORT PORTD
#define DAC_LATCH      PORTD5

uint16_t in = 0, out = 0, xf = 0, nSamples; // Audio sample counters
uint8_t  adc_save;                          // Default ADC mode

// WaveHC didn't declare it's working buffers private or static,
// so we can be sneaky and borrow the same RAM for audio sampling!
extern uint8_t
  buffer1[PLAYBUFFLEN],                   // Audio sample LSB
  buffer2[PLAYBUFFLEN];                   // Audio sample MSB
#define XFADE     16                      // Number of samples for cross-fade
#define MAX_SAMPLES (PLAYBUFFLEN - XFADE) // Remaining available audio samples

// button information:

uint8_t buttonList[] = {14, 15, 16, 17, 18, 19};
#define NUM_BUTTONS (sizeof(buttonList)/sizeof(uint8_t))

// Kbutton/WAV information.  Number of elements here should match the
// number of buttons
const char *sound[] = {
  "breath" , "destroy", "saber", // pins 14, 15, 16
  "zilla"  , "crunch" , "burp",  // pins 17, 18, 19
  "startup" };                   // Extra item = boot sound


//////////////////////////////////// SETUP

void setup() {
  uint8_t i;

  Serial.begin(9600);           

  // The WaveHC library normally initializes the DAC pins...but only after
  // an SD card is detected and a valid file is passed.  Need to init the
  // pins manually here so that voice FX works even without a card.
  pinMode(2, OUTPUT);    // Chip select
  pinMode(3, OUTPUT);    // Serial clock
  pinMode(4, OUTPUT);    // Serial data
  pinMode(5, OUTPUT);    // Latch
  digitalWrite(2, HIGH); // Set chip select high

  // enable pull-up resistors on button pins
  for (int b = 0; b < NUM_BUTTONS; b++)
    pinMode(buttonList[b], INPUT_PULLUP);


  // Init SD library, show root directory.  Note that errors are displayed
  // but NOT regarded as fatal -- the program will continue with voice FX!
  if(!card.init())             SerialPrint_P("Card init. failed!");
  else if(!vol.init(card))     SerialPrint_P("No partition!");
  else if(!root.openRoot(vol)) SerialPrint_P("Couldn't open dir");
  else {
    PgmPrintln("Files found:");
    root.ls();
    // Play startup sound (last file in array).
    playfile(sizeof(sound) / sizeof(sound[0]) - 1);
  }

  // Optional, but may make sampling and playback a little smoother:
  // Disable Timer0 interrupt.  This means delay(), millis() etc. won't
  // work.  Comment this out if you really, really need those functions.
  TIMSK0 = 0;

  // Set up Analog-to-Digital converter:
  analogReference(EXTERNAL); // 3.3V to AREF
  adc_save = ADCSRA;         // Save ADC setting for restore later

  while(wave.isplaying); // Wait for startup sound to finish...
  startPitchShift();     // and start the pitch-shift mode by default.
}


//////////////////////////////////// LOOP

// As written here, the loop function scans a keypad to triggers sounds
// (stopping and restarting the voice effect as needed).  If all you need
// is a couple of buttons, it may be easier to tear this out and start
// over with some simple digitalRead() calls.

void loop() {
   // examine  buttons for a match...
  for(int b=0; b<NUM_BUTTONS; b++) {
    if(debounceRead(buttonList[b]) == LOW) { // First match.
      if(wave.isplaying)
        wave.stop();      // Stop current WAV (if any)
      else               stopPitchShift(); // or stop voice effect
        playfile(b);                    // and play new sound.
      while (debounceRead(buttonList[b]) == LOW);  // Wait for button release.
    }
  }

  if(!wave.isplaying && !(TIMSK2 & _BV(TOIE2))) startPitchShift();
}


//////////////////////////////////// HELPERS

uint8_t debounceRead(int pin)
{
  uint8_t pinState = digitalRead(pin);
  uint32_t timeout = millis();
  while ((millis() - timeout) < 10)
  {
    if (digitalRead(pin) != pinState)
    {
      pinState = digitalRead(pin);
      timeout = millis();
    }
  }

  return pinState;
}

// Open and start playing a WAV file
void playfile(int idx) {
  char filename[13];

  (void)sprintf(filename,"%s.wav", sound[idx]);
  Serial.print("File: ");
  Serial.println(filename);

  if(!file.open(root, filename)) {
    PgmPrint("Couldn't open file ");
    Serial.print(filename);
    return;
  }
  if(!wave.create(file)) {
    PgmPrintln("Not a valid WAV");
    return;
  }
  wave.play();
}


//////////////////////////////////// PITCH-SHIFT CODE

void startPitchShift() {

  // Read analog pitch setting before starting audio sampling:
  int pitch = analogRead(1);
  Serial.print("Pitch: ");
  Serial.println(pitch);

  // Right now the sketch just uses a fixed sound buffer length of
  // 128 samples.  It may be the case that the buffer length should
  // vary with pitch for better results...further experimentation
  // is required here.
  nSamples = 128;
  //nSamples = F_CPU / 3200 / OCR2A; // ???
  //if(nSamples > MAX_SAMPLES)      nSamples = MAX_SAMPLES;
  //else if(nSamples < (XFADE * 2)) nSamples = XFADE * 2;

  memset(buffer1, 0, nSamples + XFADE); // Clear sample buffers
  memset(buffer2, 2, nSamples + XFADE); // (set all samples to 512)

  // WaveHC library already defines a Timer1 interrupt handler.  Since we
  // want to use the stock library and not require a special fork, Timer2
  // is used for a sample-playing interrupt here.  As it's only an 8-bit
  // timer, a sizeable prescaler is used (32:1) to generate intervals
  // spanning the desired range (~4.8 KHz to ~19 KHz, or +/- 1 octave
  // from the sampling frequency).  This does limit the available number
  // of speed 'steps' in between (about 79 total), but seems enough.
  TCCR2A = _BV(WGM21) | _BV(WGM20); // Mode 7 (fast PWM), OC2 disconnected
  TCCR2B = _BV(WGM22) | _BV(CS21) | _BV(CS20);  // 32:1 prescale
  OCR2A  = map(pitch, 0, 1023,
    F_CPU / 32 / (9615 / 2),  // Lowest pitch  = -1 octave
    F_CPU / 32 / (9615 * 2)); // Highest pitch = +1 octave

  // Start up ADC in free-run mode for audio sampling:
  DIDR0 |= _BV(ADC0D);  // Disable digital input buffer on ADC0
  ADMUX  = ADC_CHANNEL; // Channel sel, right-adj, AREF to 3.3V regulator
  ADCSRB = 0;           // Free-run mode
  ADCSRA = _BV(ADEN) |  // Enable ADC
    _BV(ADSC)  |        // Start conversions
    _BV(ADATE) |        // Auto-trigger enable
    _BV(ADIE)  |        // Interrupt enable
    _BV(ADPS2) |        // 128:1 prescale...
    _BV(ADPS1) |        //  ...yields 125 KHz ADC clock...
    _BV(ADPS0);         //  ...13 cycles/conversion = ~9615 Hz

  TIMSK2 |= _BV(TOIE2); // Enable Timer2 overflow interrupt
  sei();                // Enable interrupts
}

void stopPitchShift() {
  ADCSRA = adc_save; // Disable ADC interrupt and allow normal use
  TIMSK2 = 0;        // Disable Timer2 Interrupt
}

ISR(ADC_vect, ISR_BLOCK) { // ADC conversion complete

  // Save old sample from 'in' position to xfade buffer:
  buffer1[nSamples + xf] = buffer1[in];
  buffer2[nSamples + xf] = buffer2[in];
  if(++xf >= XFADE) xf = 0;

  // Store new value in sample buffers:
  buffer1[in] = ADCL; // MUST read ADCL first!
  buffer2[in] = ADCH;
  if(++in >= nSamples) in = 0;
}

ISR(TIMER2_OVF_vect) { // Playback interrupt
  uint16_t s;
  uint8_t  w, inv, hi, lo, bit;
  int      o2, i2, pos;

  // Cross fade around circular buffer 'seam'.
  if((o2 = (int)out) == (i2 = (int)in)) {
    // Sample positions coincide.  Use cross-fade buffer data directly.
    pos = nSamples + xf;
    hi = (buffer2[pos] << 2) | (buffer1[pos] >> 6); // Expand 10-bit data
    lo = (buffer1[pos] << 2) |  buffer2[pos];       // to 12 bits
  } if((o2 < i2) && (o2 > (i2 - XFADE))) {
    // Output sample is close to end of input samples.  Cross-fade to
    // avoid click.  The shift operations here assume that XFADE is 16;
    // will need adjustment if that changes.
    w   = in - out;  // Weight of sample (1-n)
    inv = XFADE - w; // Weight of xfade
    pos = nSamples + ((inv + xf) % XFADE);
    s   = ((buffer2[out] << 8) | buffer1[out]) * w +
          ((buffer2[pos] << 8) | buffer1[pos]) * inv;
    hi = s >> 10; // Shift 14 bit result
    lo = s >> 2;  // down to 12 bits
  } else if (o2 > (i2 + nSamples - XFADE)) {
    // More cross-fade condition
    w   = in + nSamples - out;
    inv = XFADE - w;
    pos = nSamples + ((inv + xf) % XFADE);
    s   = ((buffer2[out] << 8) | buffer1[out]) * w +
          ((buffer2[pos] << 8) | buffer1[pos]) * inv;
    hi = s >> 10; // Shift 14 bit result
    lo = s >> 2;  // down to 12 bits
  } else {
    // Input and output counters don't coincide -- just use sample directly.
    hi = (buffer2[out] << 2) | (buffer1[out] >> 6); // Expand 10-bit data
    lo = (buffer1[out] << 2) |  buffer2[out];       // to 12 bits
  }

  // Might be possible to tweak 'hi' and 'lo' at this point to achieve
  // different voice modulations -- robot effect, etc.?

  DAC_CS_PORT &= ~_BV(DAC_CS); // Select DAC
  // Clock out 4 bits DAC config (not in loop because it's constant)
  DAC_DI_PORT  &= ~_BV(DAC_DI); // 0 = Select DAC A, unbuffered
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  DAC_DI_PORT  |=  _BV(DAC_DI); // 1X gain, enable = 1
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  for(bit=0x08; bit; bit>>=1) { // Clock out first 4 bits of data
    if(hi & bit) DAC_DI_PORT |=  _BV(DAC_DI);
    else         DAC_DI_PORT &= ~_BV(DAC_DI);
    DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  }
  for(bit=0x80; bit; bit>>=1) { // Clock out last 8 bits of data
    if(lo & bit) DAC_DI_PORT |=  _BV(DAC_DI);
    else         DAC_DI_PORT &= ~_BV(DAC_DI);
    DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  }
  DAC_CS_PORT    |=  _BV(DAC_CS);    // Unselect DAC

  if(++out >= nSamples) out = 0;
}



thanks a lot or your time ..

is it possible to make it work for digital i/o and not for pull up resistors? i have button from digital (0,1,6,,7,8,9,10,11,12,13)

i see in serial monitor that at eacth reset arduino stores the pich but the startup wav keep playing at the same pich . im not sure for the trigger wav because i cant trigger anything with my pushbutton at digital 0 , at this point .

geostain
 
Posts: 26
Joined: Tue Dec 22, 2015 1:53 pm

Re: wave shield

by adafruit_support_rick on Tue Jan 12, 2016 7:42 am

It does work for digital I/O. You have to connect your buttons between the digital pin and ground.
Pins 14, 15, 16, 17, 18, and 19 are labeled as A0, A1, A2, A3, A4, and A5, but they are actually digital pins as well. They do double-duty as analog and digital pins.

But if you want to use 0,1,6,,7,8,9,10,11,12,13, all you have to do is substitute those numbers in the array:
Code: Select all | TOGGLE FULL SIZE
uint8_t buttonList[] = {0,1,6,7,8,9,10,11,12,13};


You probably don't want to use digital 0 and 1, because the serial monitor data goes through those pins. You will have problems with that. Use a different pair of pins for those two buttons.

adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: wave shield

by geostain on Tue Jan 12, 2016 8:04 am

ok , in that part of the code
Code: Select all | TOGGLE FULL SIZE
uint8_t buttonList[] = {0,1,6,7,8,9,10,11,12,13};
#define NUM_BUTTONS (sizeof(buttonList)/sizeof(uint8_t))

// Kbutton/WAV information.  Number of elements here should match the
// number of buttons
const char *sound[] = {
  "ni"  , "pa", "bou", // pins 0, 1, 6
  "ga"  , "di" , "ke",  // pins 7, 8, 9
  };                   // Extra item = boot sound



i choose my wav from sd card as i want to played by the buttons . ex: i want when i push the first button to play ni the 2 to play pa ... etc

but i dont get any response only the startup sound is playing . is the mistake there or somewhere in the setup() ?

i must delete this part? if i only use digital?
Code: Select all | TOGGLE FULL SIZE
 // enable pull-up resistors on button pins
  for (int b = 0; b < NUM_BUTTONS; b++)
    pinMode(buttonList[b], INPUT_PULLUP);

geostain
 
Posts: 26
Joined: Tue Dec 22, 2015 1:53 pm

Re: wave shield

by adafruit_support_rick on Tue Jan 12, 2016 11:54 am

geostain wrote:i must delete this part? if i only use digital?
 // enable pull-up resistors on button pins
  for (int b = 0; b < NUM_BUTTONS; b++)
    pinMode(buttonList[b], INPUT_PULLUP);


No. It's all digital.

Two things. One: I missed this bit. You have to comment out this line so that debounceRead can work:
Code: Select all | TOGGLE FULL SIZE
//  TIMSK0 = 0;


Two: You can't use pins 13, 12, 11, 10, 1, and 0. for your buttons. Those are already used by other things. Also, you can't use A0.

You *can* use 6, 7, 8, 9, A1 (15), A2 (16), A3(17), A4(18), and A5(19).

adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: wave shield

by geostain on Tue Jan 12, 2016 12:30 pm

adafruit_support_rick wrote:
geostain wrote:i must delete this part? if i only use digital?
 // enable pull-up resistors on button pins
  for (int b = 0; b < NUM_BUTTONS; b++)
    pinMode(buttonList[b], INPUT_PULLUP);


No. It's all digital.

Two things. One: I missed this bit. You have to comment out this line so that debounceRead can work:
Code: Select all | TOGGLE FULL SIZE
//  TIMSK0 = 0;


Two: You can't use pins 13, 12, 11, 10, 1, and 0. for your buttons. Those are already used by other things. Also, you can't use A0.

You *can* use 6, 7, 8, 9, A1 (15), A2 (16), A3(17), A4(18), and A5(19).


now the buttons works like a charm.. thx but the pitch doesnt change.. in serial monitor i can see the new values if a button is pressed or if i push reset but at the playback can here any difference .

thanks again , i dont knkow if you believe in God but i hope He gives you back 10x more the good things you done for me . :)

ps the potentiometer is connected to A0 3v grd also a bridge from 3v to aref( i also change it from the code from analog1 to 0)

geostain
 
Posts: 26
Joined: Tue Dec 22, 2015 1:53 pm

Re: wave shield

by adafruit_support_rick on Tue Jan 12, 2016 3:57 pm

geostain wrote:ps the potentiometer is connected to A0 3v grd also a bridge from 3v to aref( i also change it from the code from analog1 to 0)


If you're using AREF, then you need to call analogReference(EXTERNAL); in setup(). Did you remember to do that?

adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: wave shield

by geostain on Tue Jan 12, 2016 5:12 pm

adafruit_support_rick wrote:
geostain wrote:ps the potentiometer is connected to A0 3v grd also a bridge from 3v to aref( i also change it from the code from analog1 to 0)


If you're using AREF, then you need to call analogReference(EXTERNAL); in setup(). Did you remember to do that?


i will see that and i will answer shortly
but im using aref cause the example diagram says so .. if it not necessary i cut the bridge out..

here is the fulll code until now:
Code: Select all | TOGGLE FULL SIZE
/*
ADAVOICE is an Arduino-based voice pitch changer plus WAV playback.
Fun for Halloween costumes, comic convention getups and other shenanigans!

Hardware requirements:
 - Arduino Uno, Duemilanove or Diecimila (not Mega or Leonardo compatible).
 - Adafruit Wave Shield
 - Speaker attached to Wave Shield output
 - Battery for portable use
If using the voice pitch changer, you will also need:
 - Adafruit Microphone Breakout
 - 10K potentiometer for setting pitch (or hardcode in sketch)
If using the WAV playback, you will also need:
 - SD card
 - Keypad, buttons or other sensor(s) for triggering sounds
Software requirements:
 - WaveHC library for Arduino
 - Demo WAV files on FAT-formatted SD card

This example sketch uses a 3x4 keypad for triggering sounds...but with
some changes could be adapted to use several discrete buttons, Hall effect
sensors, force-sensing resistors (FSRs), I2C keypads, etc. (or if you just
want the voice effect, no buttons at all).

Connections:
 - 3.3V to mic amp+, 1 leg of potentiometer and Arduino AREF pin
 - GND to mic amp-, opposite leg of potentiometer
 - Analog pin 0 to mic amp output
 - Analog pin 1 to center tap of potentiometer
 - Wave Shield output to speaker or amplifier
 - Matrix is wired to pins A2, A3, A4, A5 (rows) and 6, 7, 8 (columns)
 - Wave shield is assumed wired as in product tutorial

Potentiometer sets playback pitch.  Pitch adjustment does NOT work in
realtime -- audio sampling requires 100% of the ADC.  Pitch setting is
read at startup (or reset) and after a WAV finishes playing.

POINT SPEAKER AWAY FROM MIC to avoid feedback.

Written by Adafruit industries, with portions adapted from the
'PiSpeakHC' sketch included with WaveHC library.
*/

#include <WaveHC.h>
#include <WaveUtil.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 volumes root directory
FatReader file;  // This object represent the WAV file for a pi digit or period
WaveHC    wave;  // This is the only wave (audio) object, -- we only play one at a time
#define error(msg) error_P(PSTR(msg))  // Macro allows error messages in flash memory

#define ADC_CHANNEL 1 // Microphone on Analog pin 0

// Wave shield DAC: digital pins 2, 3, 4, 5
#define DAC_CS_PORT    PORTD
#define DAC_CS         PORTD2
#define DAC_CLK_PORT   PORTD
#define DAC_CLK        PORTD3
#define DAC_DI_PORT    PORTD
#define DAC_DI         PORTD4
#define DAC_LATCH_PORT PORTD
#define DAC_LATCH      PORTD5

uint16_t in = 0, out = 0, xf = 0, nSamples; // Audio sample counters
uint8_t  adc_save;                          // Default ADC mode

// WaveHC didn't declare it's working buffers private or static,
// so we can be sneaky and borrow the same RAM for audio sampling!
extern uint8_t
  buffer1[PLAYBUFFLEN],                   // Audio sample LSB
  buffer2[PLAYBUFFLEN];                   // Audio sample MSB
#define XFADE     16                      // Number of samples for cross-fade
#define MAX_SAMPLES (PLAYBUFFLEN - XFADE) // Remaining available audio samples

// button information:

uint8_t buttonList[] = {6,7,8,9,15,16,17,18,19};
#define NUM_BUTTONS (sizeof(buttonList)/sizeof(uint8_t))
volatile byte pressed[NUM_BUTTONS], justpressed[NUM_BUTTONS], justreleased[NUM_BUTTONS];
// Kbutton/WAV information.  Number of elements here should match the
// number of buttons
const char *sound[] = {
  "ni"  , "pa", "bou", // pins 0, 1, 6
  "ga"  , "di" , "ke",  // pins 7, 8, 9
  };                   // Extra item = boot sound


//////////////////////////////////// SETUP

void setup() {
  uint8_t i;

  Serial.begin(9600);           
analogReference(EXTERNAL);
  // The WaveHC library normally initializes the DAC pins...but only after
  // an SD card is detected and a valid file is passed.  Need to init the
  // pins manually here so that voice FX works even without a card.
  pinMode(2, OUTPUT);    // Chip select
  pinMode(3, OUTPUT);    // Serial clock
  pinMode(4, OUTPUT);    // Serial data
  pinMode(5, OUTPUT);    // Latch
  digitalWrite(2, HIGH); // Set chip select high

  // enable pull-up resistors on button pins
  for (int b = 0; b < NUM_BUTTONS; b++)
    pinMode(buttonList[b], INPUT_PULLUP);


  // Init SD library, show root directory.  Note that errors are displayed
  // but NOT regarded as fatal -- the program will continue with voice FX!
  if(!card.init())             SerialPrint_P("Card init. failed!");
  else if(!vol.init(card))     SerialPrint_P("No partition!");
  else if(!root.openRoot(vol)) SerialPrint_P("Couldn't open dir");
  else {
    PgmPrintln("Files found:");
    root.ls();
    // Play startup sound (last file in array).
    playfile(sizeof(sound) / sizeof(sound[0]) - 1);
  }

  // Optional, but may make sampling and playback a little smoother:
  // Disable Timer0 interrupt.  This means delay(), millis() etc. won't
  // work.  Comment this out if you really, really need those functions.
  //TIMSK0 = 0;

  // Set up Analog-to-Digital converter:
  analogReference(EXTERNAL); // 3.3V to AREF
  adc_save = ADCSRA;         // Save ADC setting for restore later

  while(wave.isplaying); // Wait for startup sound to finish...
  startPitchShift();     // and start the pitch-shift mode by default.
}


//////////////////////////////////// LOOP

// As written here, the loop function scans a keypad to triggers sounds
// (stopping and restarting the voice effect as needed).  If all you need
// is a couple of buttons, it may be easier to tear this out and start
// over with some simple digitalRead() calls.

void loop() {
   // examine  buttons for a match...
  for(int b=0; b<NUM_BUTTONS; b++) {
    if(debounceRead(buttonList[b]) == LOW ) { // First match.
      if(wave.isplaying)
        wave.stop();      // Stop current WAV (if any)
      else               stopPitchShift(); // or stop voice effect
        playfile(b);                    // and play new sound.
      while (debounceRead(buttonList[b]) == LOW);  // Wait for button release.
    }
  }

  if(!wave.isplaying && !(TIMSK2 & _BV(TOIE2))) startPitchShift();
}


//////////////////////////////////// HELPERS

uint8_t debounceRead(int pin)
{
  uint8_t pinState = digitalRead(pin);
  uint32_t timeout = millis();
  while ((millis() - timeout) < 10)
  {
    if (digitalRead(pin) != pinState)
    {
      pinState = digitalRead(pin);
      timeout = millis();
    }
  }

  return pinState;
}

// Open and start playing a WAV file
void playfile(int idx) {
  char filename[13];

  (void)sprintf(filename,"%s.wav", sound[idx]);
  Serial.print("File: ");
  Serial.println(filename);

  if(!file.open(root, filename)) {
    PgmPrint("Couldn't open file ");
    Serial.print(filename);
    return;
  }
  if(!wave.create(file)) {
    PgmPrintln("Not a valid WAV");
    return;
  }
  wave.play();
}


//////////////////////////////////// PITCH-SHIFT CODE

void startPitchShift() {

  // Read analog pitch setting before starting audio sampling:
  int pitch = analogRead(0);
  Serial.print("Pitch: ");
  Serial.println(pitch);

  // Right now the sketch just uses a fixed sound buffer length of
  // 128 samples.  It may be the case that the buffer length should
  // vary with pitch for better results...further experimentation
  // is required here.
  nSamples = 128;
  //nSamples = F_CPU / 3200 / OCR2A; // ???
  //if(nSamples > MAX_SAMPLES)      nSamples = MAX_SAMPLES;
  //else if(nSamples < (XFADE * 2)) nSamples = XFADE * 2;

  memset(buffer1, 0, nSamples + XFADE); // Clear sample buffers
  memset(buffer2, 2, nSamples + XFADE); // (set all samples to 512)

  // WaveHC library already defines a Timer1 interrupt handler.  Since we
  // want to use the stock library and not require a special fork, Timer2
  // is used for a sample-playing interrupt here.  As it's only an 8-bit
  // timer, a sizeable prescaler is used (32:1) to generate intervals
  // spanning the desired range (~4.8 KHz to ~19 KHz, or +/- 1 octave
  // from the sampling frequency).  This does limit the available number
  // of speed 'steps' in between (about 79 total), but seems enough.
  TCCR2A = _BV(WGM21) | _BV(WGM20); // Mode 7 (fast PWM), OC2 disconnected
  TCCR2B = _BV(WGM22) | _BV(CS21) | _BV(CS20);  // 32:1 prescale
  OCR2A  = map(pitch, 0, 1023,
    F_CPU / 32 / (9615 / 2),  // Lowest pitch  = -1 octave
    F_CPU / 32 / (9615 * 2)); // Highest pitch = +1 octave

  // Start up ADC in free-run mode for audio sampling:
  DIDR0 |= _BV(ADC0D);  // Disable digital input buffer on ADC0
  ADMUX  = ADC_CHANNEL; // Channel sel, right-adj, AREF to 3.3V regulator
  ADCSRB = 0;           // Free-run mode
  ADCSRA = _BV(ADEN) |  // Enable ADC
    _BV(ADSC)  |        // Start conversions
    _BV(ADATE) |        // Auto-trigger enable
    _BV(ADIE)  |        // Interrupt enable
    _BV(ADPS2) |        // 128:1 prescale...
    _BV(ADPS1) |        //  ...yields 125 KHz ADC clock...
    _BV(ADPS0);         //  ...13 cycles/conversion = ~9615 Hz

  TIMSK2 |= _BV(TOIE2); // Enable Timer2 overflow interrupt
  sei();                // Enable interrupts
}

void stopPitchShift() {
  ADCSRA = adc_save; // Disable ADC interrupt and allow normal use
  TIMSK2 = 0;        // Disable Timer2 Interrupt
}

ISR(ADC_vect, ISR_BLOCK) { // ADC conversion complete

  // Save old sample from 'in' position to xfade buffer:
  buffer1[nSamples + xf] = buffer1[in];
  buffer2[nSamples + xf] = buffer2[in];
  if(++xf >= XFADE) xf = 0;

  // Store new value in sample buffers:
  buffer1[in] = ADCL; // MUST read ADCL first!
  buffer2[in] = ADCH;
  if(++in >= nSamples) in = 0;
}

ISR(TIMER2_OVF_vect) { // Playback interrupt
  uint16_t s;
  uint8_t  w, inv, hi, lo, bit;
  int      o2, i2, pos;

  // Cross fade around circular buffer 'seam'.
  if((o2 = (int)out) == (i2 = (int)in)) {
    // Sample positions coincide.  Use cross-fade buffer data directly.
    pos = nSamples + xf;
    hi = (buffer2[pos] << 2) | (buffer1[pos] >> 6); // Expand 10-bit data
    lo = (buffer1[pos] << 2) |  buffer2[pos];       // to 12 bits
  } if((o2 < i2) && (o2 > (i2 - XFADE))) {
    // Output sample is close to end of input samples.  Cross-fade to
    // avoid click.  The shift operations here assume that XFADE is 16;
    // will need adjustment if that changes.
    w   = in - out;  // Weight of sample (1-n)
    inv = XFADE - w; // Weight of xfade
    pos = nSamples + ((inv + xf) % XFADE);
    s   = ((buffer2[out] << 8) | buffer1[out]) * w +
          ((buffer2[pos] << 8) | buffer1[pos]) * inv;
    hi = s >> 10; // Shift 14 bit result
    lo = s >> 2;  // down to 12 bits
  } else if (o2 > (i2 + nSamples - XFADE)) {
    // More cross-fade condition
    w   = in + nSamples - out;
    inv = XFADE - w;
    pos = nSamples + ((inv + xf) % XFADE);
    s   = ((buffer2[out] << 8) | buffer1[out]) * w +
          ((buffer2[pos] << 8) | buffer1[pos]) * inv;
    hi = s >> 10; // Shift 14 bit result
    lo = s >> 2;  // down to 12 bits
  } else {
    // Input and output counters don't coincide -- just use sample directly.
    hi = (buffer2[out] << 2) | (buffer1[out] >> 6); // Expand 10-bit data
    lo = (buffer1[out] << 2) |  buffer2[out];       // to 12 bits
  }

  // Might be possible to tweak 'hi' and 'lo' at this point to achieve
  // different voice modulations -- robot effect, etc.?

  DAC_CS_PORT &= ~_BV(DAC_CS); // Select DAC
  // Clock out 4 bits DAC config (not in loop because it's constant)
  DAC_DI_PORT  &= ~_BV(DAC_DI); // 0 = Select DAC A, unbuffered
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  DAC_DI_PORT  |=  _BV(DAC_DI); // 1X gain, enable = 1
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  for(bit=0x08; bit; bit>>=1) { // Clock out first 4 bits of data
    if(hi & bit) DAC_DI_PORT |=  _BV(DAC_DI);
    else         DAC_DI_PORT &= ~_BV(DAC_DI);
    DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  }
  for(bit=0x80; bit; bit>>=1) { // Clock out last 8 bits of data
    if(lo & bit) DAC_DI_PORT |=  _BV(DAC_DI);
    else         DAC_DI_PORT &= ~_BV(DAC_DI);
    DAC_CLK_PORT |=  _BV(DAC_CLK); DAC_CLK_PORT &= ~_BV(DAC_CLK);
  }
  DAC_CS_PORT    |=  _BV(DAC_CS);    // Unselect DAC

  if(++out >= nSamples) out = 0;
}

geostain
 
Posts: 26
Joined: Tue Dec 22, 2015 1:53 pm

Re: wave shield

by adafruit_support_rick on Wed Jan 13, 2016 10:48 am

Keep using the 3.3V AREF

It all Looks good to me. But does it work?

adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: wave shield

by geostain on Wed Jan 13, 2016 1:16 pm

adafruit_support_rick wrote:Keep using the 3.3V AREF

It all Looks good to me. But does it work?


nope the pitch for the wav that is playing is the same at every position of the potentiometer.
only in serial monitor i see changes ,, at the actually output(speaker) the wav sounds the same .

geostain
 
Posts: 26
Joined: Tue Dec 22, 2015 1:53 pm

Re: wave shield

by adafruit_support_rick on Wed Jan 13, 2016 2:51 pm

Sorry - I'm a nitwit. The potentiometer is attached to Analog 1. So you can't also attach a button to Analog 1. You've got Digital 15 in your buttons array - that's the same pin as analog 1. You'll have to remove 15 from the button list:
Code: Select all | TOGGLE FULL SIZE
uint8_t buttonList[] = {6,7,8,9,16,17,18,19};

adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: wave shield

by geostain on Wed Jan 13, 2016 3:04 pm

adafruit_support_rick wrote:Sorry - I'm a nitwit. The potentiometer is attached to Analog 1. So you can't also attach a button to Analog 1. You've got Digital 15 in your buttons array - that's the same pin as analog 1. You'll have to remove 15 from the button list:
Code: Select all | TOGGLE FULL SIZE
uint8_t buttonList[] = {6,7,8,9,16,17,18,19};


i had it connected at A0(also from the code form a1 to a0) i change it again to A1 (and from the code )but still doesn't work.
but i know that the potentiometer i working cause the SampleRateHc works fine!!

geostain
 
Posts: 26
Joined: Tue Dec 22, 2015 1:53 pm

Please be positive and constructive with your questions and comments.