0

MusicMaker shield with touch sensor coding question
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

MusicMaker shield with touch sensor coding question

by moonmansays on Wed Sep 04, 2019 12:47 pm

Hello. I'm a performing musician and very new to Arduino IDE. I want to use a MusicMaker with a touch sensor so that when the sensor is touched, a sound file is played and when the sensor is released, the file stops playing. When the sensor is touched again, the same sound file starts again from the beginning. I have been successful in getting the touch sensor to play the file when I touch it, but when I release it, the track continues to play. I recently made an adjustment to the code (replacing 'playFullFile' with 'startPlayingFile') and now the when I touch the sensor, the track starts to play 3 or 4 times all within a fraction of a second and then I hear nothing. However, in the serial monitor, I see a continuing stream of Playing/Paused line items while the sensor is being touched (attached is a screenshot of this).
Play_Pause Screen Shot .png
Play_Pause Screen Shot .png (106.1 KiB) Viewed 99 times
I am copying my code below in the hopes that someone may be able to help me figure this out. Thank you very much in advance for any advice!

CODE:


Code: Select all | TOGGLE FULL SIZE
/*
  AnalogReadSerial

  Reads an analog input on pin 0, prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/AnalogReadSerial
*/

// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// define the pins used
//#define CLK 13       // SPI Clock, shared with SD card
//#define MISO 12      // Input data, from VS1053/SD card
//#define MOSI 11      // Output data, to VS1053/SD card
// Connect CLK, MISO and MOSI to hardware SPI pins.
// See http://arduino.cc/en/Reference/SPI "Connections"

// These are the pins used for the breakout example
#define BREAKOUT_RESET  9      // VS1053 reset pin (output)
#define BREAKOUT_CS     10     // VS1053 chip select pin (output)
#define BREAKOUT_DCS    8      // VS1053 Data/command select pin (output)
// These are the pins used for the music maker shield
#define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

// These are common pins between breakout and shield
#define CARDCS 4     // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

Adafruit_VS1053_FilePlayer musicPlayer =
  // create breakout-example object!
  //Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
  // create shield-example object!
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
 
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  Serial.println("Adafruit VS1053 Simple Test");

  if (! musicPlayer.begin()) { // initialise the music player
     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
     while (1);
  }
  Serial.println(F("VS1053 found"));
 
   if (!SD.begin(CARDCS)) {
    Serial.println(F("SD failed, or not present"));
    while (1);  // don't do anything more
  }

 
  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(20,20);
}

// the loop routine runs over and over again forever:
void loop()
{
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  if(sensorValue > 100) {
    Serial.println(F("Playing track 001"));
  musicPlayer.startPlayingFile("/track001.mp3");
 
 if(sensorValue < 100);
    Serial.println(F("Paused"));
  musicPlayer.pausePlaying("/track001.mp3");
 }      }
Last edited by adafruit_support_bill on Wed Sep 04, 2019 12:59 pm, edited 1 time in total.
Reason: Please use [code] tags when submitting code to the forums

moonmansays
 
Posts: 13
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

by adafruit_support_bill on Wed Sep 04, 2019 1:08 pm

I've re-formatted your loop code so that it is easier to see where the coding problems are:
Code: Select all | TOGGLE FULL SIZE
void loop()
{
   // read the input on analog pin 0:
   int sensorValue = analogRead(A0);
   // print out the value you read:
   Serial.println(sensorValue);
   if(sensorValue > 100)
   {
      Serial.println(F("Playing track 001"));
      musicPlayer.startPlayingFile("/track001.mp3");

      if(sensorValue < 100);
      
      Serial.println(F("Paused"));
      musicPlayer.pausePlaying("/track001.mp3");
   }     
}


The scope of the first 'if' is everything between the brackets '{' and '}'. So it includes the second 'if' which will never be true.

The scope of the second 'if' is everything up to the semicolon ';'. So even if it did evaluate to true, it would not do anything.

What you want is probably something more like:

Code: Select all | TOGGLE FULL SIZE
void loop()
{
   // read the input on analog pin 0:
   int sensorValue = analogRead(A0);
   Serial.println(sensorValue);
   
   // Only start playing if not already playing
   if((sensorValue > 100) && !musicPlayer.playingMusic)
   {
      Serial.println(F("Playing track 001"));
      musicPlayer.startPlayingFile("/track001.mp3");
   }
   else // stop playing
   {
      Serial.println(F("Paused"));
      musicPlayer.pausePlaying("/track001.mp3");
   }
}     

adafruit_support_bill
 
Posts: 74337
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

by moonmansays on Wed Sep 04, 2019 1:54 pm

Thank you so much for your reply, Bill. I appreciate the reformatting and logic behind it. I applied your new coding and it did not change the behavior. When pressing the touch sensor the file starts 3 or 4 times in rapid succession and then no sound outputs, though the continuous stream of 'playing/paused' text occurs in the serial monitor. I reverted the coding back to 'playFullFile' versus 'startPlayingFile' since at least here the file plays through. Left to figure out is how to get it to stop when I release my touch from the sensor. Please let me know if you have any further ideas how I might accomplish this and thanks again for your help. - Chris

moonmansays
 
Posts: 13
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

by adafruit_support_bill on Wed Sep 04, 2019 2:03 pm

the continuous stream of 'playing/paused' text occurs in the serial monitor

I don't see how that is possible with the code I posted.
Please post your modified code and a sample of the output.

adafruit_support_bill
 
Posts: 74337
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

by moonmansays on Wed Sep 04, 2019 3:07 pm

It appears that the serial monitor IS registering when I touch and untouch the sensor but the MusicMaker only stutters when I first try it after an upload and after that does not respond (even with a stutter). Again, the serial monitor does continue to reflect the sensor input.
Playing_Paused Serial Monitor.png
Playing_Paused Serial Monitor.png (96.44 KiB) Viewed 80 times


Here is my code in full with your changes... and thank you so much!

Code: Select all | TOGGLE FULL SIZE
/*
  AnalogReadSerial

  Reads an analog input on pin 0, prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/AnalogReadSerial
*/

// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// define the pins used
//#define CLK 13       // SPI Clock, shared with SD card
//#define MISO 12      // Input data, from VS1053/SD card
//#define MOSI 11      // Output data, to VS1053/SD card
// Connect CLK, MISO and MOSI to hardware SPI pins.
// See http://arduino.cc/en/Reference/SPI "Connections"

// These are the pins used for the breakout example
#define BREAKOUT_RESET  9      // VS1053 reset pin (output)
#define BREAKOUT_CS     10     // VS1053 chip select pin (output)
#define BREAKOUT_DCS    8      // VS1053 Data/command select pin (output)
// These are the pins used for the music maker shield
#define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

// These are common pins between breakout and shield
#define CARDCS 4     // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

Adafruit_VS1053_FilePlayer musicPlayer =
  // create breakout-example object!
  //Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
  // create shield-example object!
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
 
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  Serial.println("Adafruit VS1053 Simple Test");

  if (! musicPlayer.begin()) { // initialise the music player
     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
     while (1);
  }
  Serial.println(F("VS1053 found"));
 
   if (!SD.begin(CARDCS)) {
    Serial.println(F("SD failed, or not present"));
    while (1);  // don't do anything more
  }

 
  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(20,20);
}

// the loop routine runs over and over again forever:
    void loop()
    {
       // read the input on analog pin 0:
       int sensorValue = analogRead(A0);
       Serial.println(sensorValue);
       
       // Only start playing if not already playing
       if((sensorValue > 200) && !musicPlayer.playingMusic)
       {
          Serial.println(F("Playing track 001"));
          musicPlayer.startPlayingFile("/track001.mp3");
       }
       else // stop playing
       {
          Serial.println(F("Paused"));
          musicPlayer.pausePlaying("/track001.mp3");
       }
    }
Last edited by adafruit_support_bill on Wed Sep 04, 2019 3:44 pm, edited 1 time in total.
Reason: please use [code] tags when posting code to the forums.

moonmansays
 
Posts: 13
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

by adafruit_support_bill on Wed Sep 04, 2019 3:51 pm

Please use the [code] button when posting code to the forums. Paste your code between the [code] tags.

adafruit_support_bill
 
Posts: 74337
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

by adafruit_support_bill on Wed Sep 04, 2019 3:54 pm

So it is not alternating between play and pause as it was before. But it is repeating the play command when you hold down the button.

Code: Select all | TOGGLE FULL SIZE
if((sensorValue > 200) && !musicPlayer.playingMusic)

The " && !musicPlayer.playingMusic" should prevent that. Not sure why it is not working.

Try adding some code to print out the value of musicPlayer.playingMusic in your loop.

adafruit_support_bill
 
Posts: 74337
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

by moonmansays on Wed Sep 04, 2019 5:06 pm

Please excuse my ignorance, but I'm not sure what you mean regarding "Try adding some code to print out the value of musicPlayer.playingMusic in your loop." What kind of code do you mean and where would I place it? Also, I'll be sure to put any future code for review in the place specified for it. Thanks again very much. Added note: I notice it also seems to be repeating the pause command over and over like is happening with the play command with no further input.

moonmansays
 
Posts: 13
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

by adafruit_support_bill on Wed Sep 04, 2019 6:05 pm

Use Serial.println() - the same way you are printing out the analog value:

Code: Select all | TOGGLE FULL SIZE
void loop()
{
   // read the input on analog pin 0:
   int sensorValue = analogRead(A0);
   Serial.println(sensorValue);
   Serial.println(musicPlayer.playingMusic);
   
   // Only start playing if not already playing
   if((sensorValue > 100) && !musicPlayer.playingMusic)
   {
      Serial.println(F("Playing track 001"));
      musicPlayer.startPlayingFile("/track001.mp3");
   }
   else // stop playing
   {
      Serial.println(F("Paused"));
      musicPlayer.pausePlaying("/track001.mp3");
   }



The pause command will repeat once you take your finger off the button since we don't have any code to prevent it. But that is harmless if nothing is playing.

It will be easy enough to add some code prevent that if we can verify that "musicPlayer.playingMusic" is working properly.

adafruit_support_bill
 
Posts: 74337
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

by moonmansays on Wed Sep 04, 2019 6:29 pm

Thank you for the feedback re the pause state. I tried the code you suggested and got something that doesn't look much different than the last serial monitor reading except for an added '0'. Significant? Here are two screens... Finger on and Finger off. Thank you very much for your help.

Finger On.png
Finger On.png (93.4 KiB) Viewed 53 times
Finger Off.png
Finger Off.png (70.95 KiB) Viewed 53 times


Code: Select all | TOGGLE FULL SIZE
/*
  AnalogReadSerial

  Reads an analog input on pin 0, prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/AnalogReadSerial
*/

// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// define the pins used
//#define CLK 13       // SPI Clock, shared with SD card
//#define MISO 12      // Input data, from VS1053/SD card
//#define MOSI 11      // Output data, to VS1053/SD card
// Connect CLK, MISO and MOSI to hardware SPI pins.
// See http://arduino.cc/en/Reference/SPI "Connections"

// These are the pins used for the breakout example
#define BREAKOUT_RESET  9      // VS1053 reset pin (output)
#define BREAKOUT_CS     10     // VS1053 chip select pin (output)
#define BREAKOUT_DCS    8      // VS1053 Data/command select pin (output)
// These are the pins used for the music maker shield
#define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

// These are common pins between breakout and shield
#define CARDCS 4     // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

Adafruit_VS1053_FilePlayer musicPlayer =
  // create breakout-example object!
  //Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
  // create shield-example object!
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
 
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  Serial.println("Adafruit VS1053 Simple Test");

  if (! musicPlayer.begin()) { // initialise the music player
     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
     while (1);
  }
  Serial.println(F("VS1053 found"));
 
   if (!SD.begin(CARDCS)) {
    Serial.println(F("SD failed, or not present"));
    while (1);  // don't do anything more
  }

 
  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(20,20);
}

// the loop routine runs over and over again forever:
    void loop()
    {
       // read the input on analog pin 0:
       int sensorValue = analogRead(A0);
       Serial.println(sensorValue);
       Serial.println(musicPlayer.playingMusic);
       
       // Only start playing if not already playing
       if((sensorValue > 100) && !musicPlayer.playingMusic)
       {
          Serial.println(F("Playing track 001"));
          musicPlayer.startPlayingFile("/track001.mp3");
       }
       else // stop playing
       {
          Serial.println(F("Paused"));
          musicPlayer.pausePlaying("/track001.mp3");
       }
    }

moonmansays
 
Posts: 13
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

by adafruit_support_bill on Thu Sep 05, 2019 5:41 am

Zero is equivalent to 'false'. Which means that the boolean flag musicPlayer.playingMusic has a value which is always false. It should be true if a track is actually playing. Are you getting any sound from it?

adafruit_support_bill
 
Posts: 74337
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

by moonmansays on Thu Sep 05, 2019 10:27 am

Only the stuttered beginnings of the music that happen for the first second or so when I touch the sensor. After that, there is no sound. If I remove my finger and put it back on the sensor again, no sound will happen. Only if I re-upload the code will the stuttering happen again. I count 6 stutters before it goes to no sound.

moonmansays
 
Posts: 13
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

by adafruit_support_bill on Thu Sep 05, 2019 11:29 am

That is strange. Looking at the library code, the value of playingMusic should change to true as soon as the file starts playing.

Let's try a different approach. Instead of looking at playingMusic, we can monitor the state of the button:

Code: Select all | TOGGLE FULL SIZE
void loop()
{
   // read the input on analog pin 0:
   int sensorValue = analogRead(A0);
   Serial.println(sensorValue);
   Serial.println(musicPlayer.playingMusic);
   
   int threshold = 200;

   // Only start playing if not already playing
   if(sensorValue > threshold)
   {
      Serial.println(F("Playing track 001"));
      musicPlayer.startPlayingFile("/track001.mp3");
      while(analogRead(A0) > threshold)
      {
         // do nothing
      }
   }
   else // stop playing
   {
      Serial.println(F("Paused"));
      musicPlayer.pausePlaying("/track001.mp3");
      while(analogRead(A0) <= threshold)
      {
         // do nothing
      }
   }

adafruit_support_bill
 
Posts: 74337
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

by moonmansays on Thu Sep 05, 2019 11:37 am

However, if I change startPlayingFile to playFullFile, the entire track will play (no stuttering). But then the release of the touch sensor has no effect. It just continues playing.

moonmansays
 
Posts: 13
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

by moonmansays on Thu Sep 05, 2019 11:48 am

Thank you for the new code and all your help. Behavior has changed with this new code. Not quite there but it feels closer... When I touch the sensor, one short burst of the music emits (a fraction of a second long) and then there is no sound. When I lift my finger off the sensor and touch it again, the same thing happens. This happens over and over as you can see in this serial monitor screen :
Screen Shot 2019-09-05 at 11.34.56 AM.png
Screen Shot 2019-09-05 at 11.34.56 AM.png (80.54 KiB) Viewed 31 times
Contrary to the serial monitor activity of the last code sequence which displayed a continuously streaming text whether I touched the sensor or not, this screen activity only prints text when I touch the sensor or remove touch from the sensor. So, right now it appears to be working as I want, except that the music only plays a very short burst each time I touch the sensor. Why is the music file stopping itself?

ADDED NOTE: In the serial monitor I see that when I touch the sensor a large number appears (usually 660-something) followed immediately by a 0. Is this the FALSE indication you mentioned previously that represents the music stopping before I release the touch sensor?

moonmansays
 
Posts: 13
Joined: Wed Sep 04, 2019 12:23 pm

Please be positive and constructive with your questions and comments.