MusicMaker shield with touch sensor coding question

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

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
moonmansays
 
Posts: 34
Joined: Wed Sep 04, 2019 12:23 pm

MusicMaker shield with touch sensor coding question

Post by moonmansays »

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 266 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

/*
  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

User avatar
adafruit_support_bill
 
Posts: 88142
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

Post by adafruit_support_bill »

I've re-formatted your loop code so that it is easier to see where the coding problems are:

Code: Select all

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

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

User avatar
moonmansays
 
Posts: 34
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

Post by moonmansays »

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

User avatar
adafruit_support_bill
 
Posts: 88142
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

Post by adafruit_support_bill »

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.

User avatar
moonmansays
 
Posts: 34
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

Post by moonmansays »

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 247 times


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

Code: Select all

/*
  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.

User avatar
adafruit_support_bill
 
Posts: 88142
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

Post by adafruit_support_bill »

Please use the

Code: Select all

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

User avatar
adafruit_support_bill
 
Posts: 88142
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

Post by adafruit_support_bill »

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

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.

User avatar
moonmansays
 
Posts: 34
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

Post by moonmansays »

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.

User avatar
adafruit_support_bill
 
Posts: 88142
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

Post by adafruit_support_bill »

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

Code: Select all

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.

User avatar
moonmansays
 
Posts: 34
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

Post by moonmansays »

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 220 times
Finger Off.png
Finger Off.png (70.95 KiB) Viewed 220 times

Code: Select all

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

User avatar
adafruit_support_bill
 
Posts: 88142
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

Post by adafruit_support_bill »

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?

User avatar
moonmansays
 
Posts: 34
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

Post by moonmansays »

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.

User avatar
adafruit_support_bill
 
Posts: 88142
Joined: Sat Feb 07, 2009 10:11 am

Re: MusicMaker shield with touch sensor coding question

Post by adafruit_support_bill »

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

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
		}
	}
}  

User avatar
moonmansays
 
Posts: 34
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

Post by moonmansays »

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.

User avatar
moonmansays
 
Posts: 34
Joined: Wed Sep 04, 2019 12:23 pm

Re: MusicMaker shield with touch sensor coding question

Post by moonmansays »

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 198 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?

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

Return to “Arduino Shields from Adafruit”