0

Help Combining Music Maker Code 1790 - No Amp with Class D M
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Help Combining Music Maker Code 1790 - No Amp with Class D M

by Larry67 on Wed Jul 11, 2018 6:18 pm

Forum Members

I have been working on combining the code for the Music Maker without the amp (1790 Product) with the Class D Amplifier MAX9744. Using the Adafruit Library for the Music Maker and the code for the amp from the product description, I can get them to work independently but when I try to combine the code, I get all kinds of compile errors. Instead of providing any code, which I think will confuse anyone trying to help, I am hoping someone would help a novice by providing the code for me.

I normally would not ask anyone to do this because you can learn from trial and error, but after two weeks of working on this, I am at my wits end.

So, in the ether, if someone sees a person on their knees asking for help, that is me!!

Thanks in advance for anyone with some free time helping me get this accomplished.

Note: I need to get past this in order to add logic to allow the Arduino to play sounds when a door is opened in my home.

Larry67
 
Posts: 30
Joined: Tue May 08, 2018 2:57 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by Larry67 on Wed Jul 11, 2018 6:24 pm

Sorry

Forgot to include the address for the two products

https://www.adafruit.com/product/1752

https://www.adafruit.com/product/1790

Larry67
 
Posts: 30
Joined: Tue May 08, 2018 2:57 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by adafruit_support_mike on Thu Jul 12, 2018 1:23 am

We operate on a 'show your work' policy, but will be happy to help on those terms.

Getting code from a forum is a fast way to learn some truly awful project-development habits. It starts with asking for something to demonstrate the principle, then asking for a couple of adjustments, then asking for some new features, and gradually drifting into the assumption that you have an on-demand software development team that works for free. Throughout the whole process, the "I don't know how to do the basics" part never goes away because it takes time and effort to understand code someone else writes, and asking for 'just one more tweak' is much easier. The longer the process runs, the farther over your head the codebase gets. The collapse tends to be ugly because the person getting the code has essentially been trained that project development means telling someone else what to do, and the people who've been writing code hit the point where they're ready to yank that rug away without pity.

It takes training and experience to avoid falling into that pattern.. a good 60% of commercial software projects fail because the professionals hired to manage said projects don't know how to stay out of it.

So we won't write the code for you, but are downright enthusiastic about helping you understand how to write the code for yourself.

The first step is to strip away as much extraneous detail as possible. Write two sketches that are the shortest and simplest you can manage, each of which talks to one of the devices in question. Get those running, or to a point where you can't figure out why they don't run, and post your results. If they do run, try merging the two into a single sketch, and see if that works.

adafruit_support_mike
 
Posts: 52679
Joined: Thu Feb 11, 2010 2:51 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by Larry67 on Thu Jul 12, 2018 3:15 pm

Dear Forum

What I did was back track to where I could get the code to compile stripping out all extra code from the Music Maker Library and the Code provided for the Amplifier. The code will compile and load but it will not play any of the tracks on the SD card.

I started with the library code for the music maker and verified that the code would work and it played the two tracks on the SD card. I did this before adding sections of the Provided Amplifier Code.

Here is my code that won't play the tracks on the SD card. It skips over the section to play the tracks and goes directly to the Loop section.

Hope you can provide some help with this. Thank you for looking at it.

/***************************************************
Code: Select all | TOGGLE FULL SIZE
  This is an example for the Adafruit VS1053 Codec Breakout

  Designed specifically to work with the Adafruit VS1053 Codec Breakout
  ----> https://www.adafruit.com/products/1381

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries. 
  BSD license, all text above must be included in any redistribution
 ****************************************************/

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

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

// From Amp Code
// 0x4B is the default i2c address
#define MAX9744_I2CADDR 0x4B
int8_t thevol = 63;  // I want Max Volume Always

Adafruit_VS1053_FilePlayer musicPlayer =
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
 
void setup() {
  Serial.begin(9600);
 
// From Amp Code
Serial.println("MAX9744 demo");
  Wire.begin();
 
  if (! setvolume(thevol)) {
    Serial.println("Failed to set volume, MAX9744 not found!");
    while (1);
  }
}

// Setting the volume is very simple! Just write the 6-bit
// volume to the i2c bus. That's it!
boolean setvolume(int8_t v) {
  // cant be higher than 63 or lower than 0
  if (v > 63) v = 63;
  if (v < 0) v = 0;
 
  Serial.print("Setting volume to ");
  Serial.println(v);
  Wire.beginTransmission(MAX9744_I2CADDR);
  Wire.write(v);
  if (Wire.endTransmission() == 0)
    return true;
  else
    return false; 
 
 // From Adafruit Library for Music Maker Striped Down to What I need
 
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
  }

  // Play one file, don't return until complete
  Serial.println(F("Playing track 001"));
  musicPlayer.playFullFile("track001.mp3");
  // Play another file in the background, REQUIRES interrupts!
  Serial.println(F("Playing track 002"));
  musicPlayer.startPlayingFile("track002.mp3");
}

void loop() {
  if (musicPlayer.stopped()) {
    Serial.println("Done playing music");
    while (1) {
      delay(10);  // we're done! do nothing...
    }
  }
  }
Last edited by adafruit_support_mike on Fri Jul 13, 2018 12:21 am, edited 1 time in total.
Reason: fixesd CODE tags

Larry67
 
Posts: 30
Joined: Tue May 08, 2018 2:57 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by adafruit_support_mike on Fri Jul 13, 2018 12:44 am

It looks like you got caught by the cut-and-paste bug.

The is your setup() function:

Code: Select all | TOGGLE FULL SIZE
void setup() {
  Serial.begin(9600);

  // From Amp Code
  Serial.println("MAX9744 demo");
  Wire.begin();

  if (! setvolume(thevol)) {
    Serial.println("Failed to set volume, MAX9744 not found!");
    while (1);
  }
}
It doesn't talk to the Music Maker's VS1053 at all. Instead, it calls the function setVolume():

Code: Select all | TOGGLE FULL SIZE
boolean setvolume(int8_t v) {
  // cant be higher than 63 or lower than 0
  if (v > 63) v = 63;
  if (v < 0) v = 0;

  Serial.print("Setting volume to ");
  Serial.println(v);
  Wire.beginTransmission(MAX9744_I2CADDR);
  Wire.write(v);
  if (Wire.endTransmission() == 0)
    return true;
  else
    return false;

  // From Adafruit Library for Music Maker Striped Down to What I need

  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
  }

  // Play one file, don't return until complete
  Serial.println(F("Playing track 001"));
  musicPlayer.playFullFile("track001.mp3");
  // Play another file in the background, REQUIRES interrupts!
  Serial.println(F("Playing track 002"));
  musicPlayer.startPlayingFile("track002.mp3");
}
That contains the code that should talk to the VS1053, even though the name and the comment in setup() suggest it only talks to the MAX9744.

The problem is this chunk toward the top of the function:

Code: Select all | TOGGLE FULL SIZE
  if (Wire.endTransmission() == 0)
    return true;
  else
    return false;
No code past that point will ever execute. Those lines tell the CPU to go back to the calling function no matter what happens.

Functionally, this is your sketch:

Code: Select all | TOGGLE FULL SIZE
void setup() {
  Serial.begin(9600);

  // From Amp Code
  Serial.println("MAX9744 demo");
  Wire.begin();

  if (! setvolume(thevol)) {
    Serial.println("Failed to set volume, MAX9744 not found!");
    while (1);
  }
}

// Setting the volume is very simple! Just write the 6-bit
// volume to the i2c bus. That's it!
boolean setvolume(int8_t v) {
  // cant be higher than 63 or lower than 0
  if (v > 63) v = 63;
  if (v < 0) v = 0;

  Serial.print("Setting volume to ");
  Serial.println(v);
  Wire.beginTransmission(MAX9744_I2CADDR);
  Wire.write(v);
  if (Wire.endTransmission() == 0)
    return true;
  else
    return false;
}

void loop() {
  if (musicPlayer.stopped()) {
    Serial.println("Done playing music");
    while (1) {
      delay(10);  // we're done! do nothing...
    }
  }
}
It doesn't contain any of the parts that should talk to the VS1053.

It's easy to make that kind of mistake cutting and pasting code from one place to another.. a huge number of bugs are created that way. Experienced programmers have gotten caught by that enough times that they get mad at themselves any time they do it again, and try to avoid copy/pasting code anywhere, ever. Personally, even when I know a copy/paste is probably safe, I'll still re-type the code by hand just to make sure I'm not including anything I don't want, or putting instructions where I don't want them.

Never understimate the value of hand-copying code. It has to go through your brain on its way from your eyes to your hands, and you can't help identifying basic pieces as they go past.. variable names, constants, function names, the way functions are called, etc. You spend time learning things about the code while your hands are busy hitting the keys.

adafruit_support_mike
 
Posts: 52679
Joined: Thu Feb 11, 2010 2:51 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by Larry67 on Fri Jul 13, 2018 2:40 pm

Mike

I understand now what is happening. I will rework the code and see if I can get things to work. Unfortunately I am not a C++ or Python programmer. My basic Knowledge is from Udemy on-line courses. Being retired, I am just trying to keep up with my Grandson and help him when I can.

A related question. If I load the code for the Amplifier into the Arduino, I can get the volume to set at 63 and it stays at that level until power if removed from the Amplifier board. Is there a way to make the volume remain at 63 after the power is removed.

Thank you for you time and patience.

Larry67
 
Posts: 30
Joined: Tue May 08, 2018 2:57 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by adafruit_support_mike on Sat Jul 14, 2018 12:52 am

Don't worry about being at the beginner stage.. we all start there, and most of us keep finding new subjects where we're at the bottom of a long learning curve. The process is always the same: start by learning a little about something, then build out from there. Think of new things to try, experiment, and see what happens. The information accumulates pretty quickly. ;-)

The MAX9744 won't hold a volume setting you send through the I2C interface after you disconnect power, but our breakout has space for a potentiometer that you can use to set the volume by hand. The two methods are mutually exclusive: if you connect a potentiometer you can't set the volume from code, and if you remove the potentiometer you can only set the volume from code.

If you want to control the volume from code, you can tell the MAX9744 to go to a specific value in your setup() function, immediately after you turn it on. The code you already have does that, you just need to move things around a little so the "now play a track" code will execute after you set the volume.

adafruit_support_mike
 
Posts: 52679
Joined: Thu Feb 11, 2010 2:51 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by Larry67 on Sat Jul 14, 2018 5:10 pm

Mike

Thanks for the encouragement. I moved the code around and I was able to set the volume and play a track. I verified that the volume was being set in the code by first setting the volume to 0 with the Amp Only code. The combined code set the volume to 63 and played the track.

I now can help him as he tries to add a sensor so that when a door is opened, the track will play.

One question about the code. From the courses I have taken programming the Arduino, all code, other than the initial definition code, was included in the set up and loop sections.

The set volume code, starting with the statement boolean setvolume(int8_t v), is outside the set up section. Simply, can you tell me the reason for that and when one might code that way. I could not find anything googling and the courses I have been taken are pretty basic with more emphasis on making things rather than code instruction.

Thanks again for your help.

Larry67
 
Posts: 30
Joined: Tue May 08, 2018 2:57 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by adafruit_support_mike on Sun Jul 15, 2018 12:45 am

That's a question of style and taste.

You can put all of the code from the function directly in the setup() function:

Code: Select all | TOGGLE FULL SIZE
void setup() {
  Serial.begin(9600);
 
// From Amp Code
Serial.println("MAX9744 demo");
  Wire.begin();
 
  Serial.print("Setting volume to ");
  Serial.println( thevol );
  Wire.beginTransmission( MAX9744_I2CADDR );
  Wire.write( thevol );
  if ( ! ( Wire.endTransmission() == 0 )) {
    Serial.println("Failed to set volume, MAX9744 not found!");
    while (1);
  }
 
//  etc...
}
and it will work. The downside is that you have to write the same block of code again if you want to change the volume from any other part of the program.

Moving the code off to a separate function does a couple of things: it gives you the freedom to call the function from multiple parts of the program, and if you choose a good function name, it makes the code self-commenting. A setup() function written like this makes it easy to understand what's happening:

Code: Select all | TOGGLE FULL SIZE
void setup() {
    do_general_setup();
    set_max9744_volume_to( 63 );
    initialize_music_maker();
    initialize_sd_card();

    music_maker.startPlayingFile( "track002.mp3" );
}
Even without the code for any of the functions in that group, you have a general idea of what to expect just from reading their names.

Organizing code that way is useful. The CPU can run just about anything you throw at it, but humans have to understand the sequence of operations before they can write code, maintain it, or modify it. The source code is a document for humans first, and happens to be written in a form that can turn into something the CPU understands.

Philosophically, a programmer's job is to create a language that describes the problem they want to solve and the way they want to solve it. The language provides generic operations that tend to be useful, but they're tightly connected to the fine details of what they do.. you have to specify the bitwise representation of every variable, keep track of data types, and so on. Those details are necessary, but you don't want to fuss around with a pile of such details when you're trying to do something complicated. So programming languages give us abstraction tools like functions and objects.

With those, we can give blocks of code names that are more descriptive and less constrained by details like data representation and low-level operations. Then we use those functions to build more complex ones, with names that describe larger parts of the problem space and solution space, and even less connection to the low-level details.

That process is sometimes called 'programming in the large'. The more layers of abstraction you build, the less your code depends on any specific language, and the more it looks like a human-readable description of what the code should be doing.

You have a great deal of freedom to choose the parts of a program you want to collapse into functions, and how you want to build systems from the functions you've created, and there's no such thing as a 'best' or 'right' style. If it runs, it runs. You'll develop your own set of opinions about what's useful and what's more trouble than it's worth as you spend time writing code, and especially when you go back to code you've already written to see if you still understand what it does. Sometimes you have to backtrack, when a set of ideas that seemed good in the beginning turn out to make writing higher-level code too complicated.

It's been said that the first version of any program is written to figure out what problem you're actually trying to solve, the second version is the most dangerous because it gets filled with all the ideas you learned from the first version, and the third version is actually useful and well written.

adafruit_support_mike
 
Posts: 52679
Joined: Thu Feb 11, 2010 2:51 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by Larry67 on Tue Jul 17, 2018 4:04 pm

Mike

Thanks for the explanation. I now have a better understanding of what can be done with functions and documentation. Since I posted my question, I looked at other more complicated code and found others defining functions outside and inside the setup and loop sections. What I do appreciate is the documentation aspect. I sometimes find comments cumbersome and overused whereas function names better describe what is going on. However, as I can see, there is a place for both.

Thanks again

Larry67
 
Posts: 30
Joined: Tue May 08, 2018 2:57 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by adafruit_support_mike on Tue Jul 17, 2018 5:00 pm

Yeah, programming classes generally suck at teaching proper documentation.. partially because the assignments are small enough that they don’t need to be well documented.

There are two kinds of information that make understanding code easier: I call them in-band and out-of-band information.

In-band information is the stuff you do with descriptive variable and function names. It gives you a mental model for what the code does, so you can read the source basically thinking, “okay, how does it do what the name says?”

Out-of-band information is what the code *doesn’t* do. You might have to try three or four different approaches to a problem before you find something that works exactly the way you need. The final code probably won’t contain any of the options you rejected, but it’s tremendously useful to say things like, “testing showed that approach X, which is more straightforward, led to timing problems. This code is uglier, but is fast enough to do what’s necessary. ‘Fixing‘ this section will break other parts of the program.” That gives people context and insight that doesn’t fit neatly into in-band terms.

If your comment is a human-language description of what the code does, rewrite that block of code using all the nouns and verbs from the description as variable and function names, then delete the comment. Use comments, but only use them to talk about non-executable ideas. Stick to general philosophy and lessons learned.

adafruit_support_mike
 
Posts: 52679
Joined: Thu Feb 11, 2010 2:51 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by Larry67 on Wed Jul 18, 2018 3:13 pm

Mike

Thanks again for your thoughts. I hope to incorporate in what I do and help my grandson do the same.

My grandson found something interesting yesterday that I don't have an answer for. He was playing around with the examples library and decided to load the example for "player interrupts" after he had loaded the code I helped him put together to set the volume and play a sound. That code sets the amplifier volume to 63. We know the code is working because when we manually change the volume value in the program from 45 to 63, the volume does change. However, anything less than 45, results in no audible sound.

When he did this, the sound out of the speaker was close to double the volume we had set before. We looked at the “player_interrupts” code and found the statement "musicPlayer.setVolume(20,20); ". With a lower number resulting in a higher volume.

We tried inserting this line of code in the setup, loop or the section that “wires” the volume to the amplifier. It did not make a difference in the volume.

Just to refresh you with what we have. I bought the Music Maker shield without the amp and connected it to the 20-watt Class D amplifier. We are using a 20-watt 4-ohm speaker all of which I purchased from Adafruit. I was always surprised that at the volume set to 63, we were nowhere close to what I thought I should get for volume with a setting of 63.
So, could you give us some ideas on how we can get the volume to be higher in the amplifier once power is turned off and he moves it to its permanent location. As an aside, he added code that plays the sound whenever the IR sensor beam is broken when a door is opened. We would like the volume to be higher so it can be heard throughout the house.

Thank You

Our code:
Code: Select all | TOGGLE FULL SIZE
/***************************************************
  This is an example for the Adafruit VS1053 Codec Breakout

  Designed specifically to work with the Adafruit VS1053 Codec Breakout
  ----> https://www.adafruit.com/products/1381

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ****************************************************/

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

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

#define sensorPin 2  // For IR Breakbeam Sensor
#define MAX9744_I2CADDR 0x4B

int8_t thevol = 63;  // I want Max Volume Always
int counter = 0;
int sensorState = 0;

Adafruit_VS1053_FilePlayer musicPlayer =
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);

void setup() {
  Serial.begin(9600);

  SD.begin(CARDCS);
  musicPlayer.begin();

  pinMode(sensorPin, INPUT);

  Wire.begin();
  if (! setvolume(thevol)) {
    Serial.println("Failed to set volume, MAX9744 not found!");
    while (1);
  }
}

boolean setvolume(int8_t v) {
  // cant be higher than 63 or lower than 0
  if (v > 63) v = 63;
  if (v < 0) v = 0;

  Serial.print("Setting volume to ");
  Serial.println(v);
  Wire.beginTransmission(MAX9744_I2CADDR);
  Wire.write(v);
  if (Wire.endTransmission() == 0)
    return true;
  else
    return false;
}

void loop() {
  sensorState = digitalRead(sensorPin);

  if (sensorState == LOW) {
    counter = 0;
    Serial.println("Door Opened");
  }

  while (counter < 3) {
    musicPlayer.begin();
    Serial.println(F("Playing track 001"));
    musicPlayer.playFullFile("track001.mp3");
    delay (500);
    counter ++;
    Serial.println(counter);
  }

  musicPlayer.stopped();

}
Last edited by adafruit_support_mike on Thu Jul 19, 2018 1:23 am, edited 2 times in total.
Reason: added CODE tags

Larry67
 
Posts: 30
Joined: Tue May 08, 2018 2:57 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by adafruit_support_mike on Thu Jul 19, 2018 1:41 am

It looks like you've rolled your own version of setVolume, but a few details are off.

Here's the version from the VS1053 library:

Code: Select all | TOGGLE FULL SIZE
void Adafruit_VS1053::setVolume(uint8_t left, uint8_t right) {
  uint16_t v;
  v = left;
  v <<= 8;
  v |= right;

  noInterrupts(); //cli();
  sciWrite(VS1053_REG_VOLUME, v);
  interrupts();  //sei();
}

void Adafruit_VS1053::sciWrite(uint8_t addr, uint16_t data) {
  #ifdef SPI_HAS_TRANSACTION
  if (useHardwareSPI) SPI.beginTransaction(VS1053_CONTROL_SPI_SETTING);
  #endif
  digitalWrite(_cs, LOW); 
  spiwrite(VS1053_SCI_WRITE);
  spiwrite(addr);
  spiwrite(data >> 8);
  spiwrite(data & 0xFF);
  digitalWrite(_cs, HIGH);
  #ifdef SPI_HAS_TRANSACTION
  if (useHardwareSPI) SPI.endTransaction();
  #endif
}
The biggest difference is that the VS1053 communicates through the SPI bus, while the Wire library in your code talks to the I2C bus.. different pins and a different protocol.

The next detail is that the VS1053 uses a register-based control model. It has a set of numbered memory locations which hold the data that tells the chip what to do. To make the chip do something, you store a value in the appropriate memory location (or 'register'). To set the volume, you need register 0x0B, and you need to send it a 16-bit value that has volume settings for the left and right channels.

The volume settings are also technically attenuation settings. The VS1053 assumes the output it gets from the decoded MP3 or OGG track is appropriate to a speaker playing at full volume, then divides that down to lower the volume. The more attenuation you tell it to use, the softer the output.

To be honest, I'm not sure how your setVolume() function had any effect on the Music Maker's output.. it's kind of the software equivalent to a wrong number.

adafruit_support_mike
 
Posts: 52679
Joined: Thu Feb 11, 2010 2:51 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by Larry67 on Sat Jul 28, 2018 4:40 pm

Mike

I added your code but I am getting a compile error. I have done my best to look for a solution, but I am afraid these types of errors are beyond my Arduino knowledge. If you recall, I am attempting to set the volume of the 20 watt amplifier so it will store the equivalent of 20 watts of volume scaled back a little for a 9 volt source voltage after power is removed from the Arduino. I mentioned that my grandson discovered that if he downloaded the player interrupt code from the library after we downloaded our code to the Arduino, the volume essentially doubled but would not stay at that level. I realize that you mentioned that was the equivalent of a wrong number but it demonstrated that the amplifier can output more volume than we are getting with our current code. Thanks again for all your help.

I get the error for the following statement

Code: Select all | TOGGLE FULL SIZE
if (useHardwareSPI) SPI.beginTransaction(VS1053_CONTROL_SPI_SETTING);

So if I could ask for some more help with this compile error:

exit status 1
'VS1053_CONTROL_SPI_SETTING' was not declared in this scope

Here is our code:


#include <SPI.h>[code][/code]
#include <Adafruit_VS1053.h>
#include <SD.h>
#include <Wire.h>  // Amp Code

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

#define MAX9744_I2CADDR 0x4B

int8_t thevol = 63;  // I want Max Volume Always
int counter = 0;
int pirSensorPin = 2;
int ledPin   = A0;
int pirState = true;
int val = 0;
int minSecAfterPIRLow = 5000;

long unsigned int timeTurnedLow;
boolean takeLowTime;
int calibrationTime = 1;

Adafruit_VS1053_FilePlayer musicPlayer =
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);

void setup() {
  pinMode(pirSensorPin, INPUT);
  pinMode(ledPin, OUTPUT);
  takeLowTime = LOW;

  Serial.begin(9600);

  Serial.println("Waiting for the sensor to warm up.");
  delay(calibrationTime * 1000); // Convert the time from seconds to milliseconds.
  Serial.println("SENSOR ACTIVE");

  SD.begin(CARDCS);

  Wire.begin();
  if (! setvolume(thevol)) {
    Serial.println("Failed to set volume, MAX9744 not found!");
    while (1);
  }
}

boolean setvolume(int8_t v) {
  // cant be higher than 63 or lower than 0
  if (v > 63) v = 63;
  if (v < 0) v = 0;

  Serial.print("Setting volume to ");
  Serial.println(v);
  Wire.beginTransmission(MAX9744_I2CADDR);
  Wire.write(v);
  if (Wire.endTransmission() == 0)
    return true;
  else
    return false;
}
void Adafruit_VS1053::setVolume(uint8_t left, uint8_t right) {
  uint16_t v;
  v = left;
  v <<= 8;
  v |= right;

  noInterrupts(); //cli();
  sciWrite(VS1053_REG_VOLUME, v);
  interrupts();  //sei();
}

void Adafruit_VS1053::sciWrite(uint8_t addr, uint16_t data) {
#ifdef SPI_HAS_TRANSACTION
  if (useHardwareSPI) SPI.beginTransaction(VS1053_CONTROL_SPI_SETTING);
#endif
  digitalWrite(_cs, LOW);
  spiwrite(VS1053_SCI_WRITE);
  spiwrite(addr);
  spiwrite(data >> 8);
  spiwrite(data & 0xFF);
  digitalWrite(_cs, HIGH);
#ifdef SPI_HAS_TRANSACTION
  if (useHardwareSPI) SPI.endTransaction();
#endif
}
void loop() {

  val = digitalRead(pirSensorPin);  // read input value

  if (val == HIGH) {            // check if the input is HIGH
    digitalWrite(ledPin, HIGH);  // turn LED ON
    while (counter < 3) {
      musicPlayer.begin();
      Serial.println(F("Playing track 001"));
      musicPlayer.playFullFile("track001.mp3");
      delay (100);
      counter ++;
      Serial.println(counter);
    }
    if (pirState == LOW) {
      // we have just turned on
      Serial.println("Motion detected!");
      // We only want to print on the output change, not state
      pirState = HIGH;
    }
  } else {

    if (pirState == HIGH) {
      // we have just turned off
      Serial.println("Motion ended!");
      // We only want to print on the output change, not state
      pirState = LOW;
      timeTurnedLow = millis(); //take the millis at the moment the sensor went LOW
    }
  }
  //This block checks to see if enough time has passed after the PRI went LOW.
  //If yes, and assuming that the PIR sensor did not go HIGH again, turn off the LED
  if (!pirState && (millis() - timeTurnedLow) > minSecAfterPIRLow) {
    Serial.println("Extended time HIGH ended!");
    digitalWrite(ledPin, LOW); // turn LED OFF
    counter = 0;

  }
  delay(1000);

  musicPlayer.stopped();
}
Last edited by adafruit_support_mike on Thu Aug 16, 2018 1:12 am, edited 1 time in total.
Reason: added CODE tags

Larry67
 
Posts: 30
Joined: Tue May 08, 2018 2:57 pm

Re: Help Combining Music Maker Code 1790 - No Amp with Class

by Larry67 on Wed Aug 15, 2018 4:14 pm

Mike

Did you give up on us? Or is this something that cannot be fixed?

Thanks

Larry67
 
Posts: 30
Joined: Tue May 08, 2018 2:57 pm

Please be positive and constructive with your questions and comments.