Stacking 3 of the same shields on top of each other and instructing them in sync

Context:
I have an audio track separated into individual channels grouped by frequency and speaker location. I need to play all three of these channels simultaneously and perform instructions like play, stop, repeat, skip across all channels to keep them in sync.

This is part of an outdoor installation so the solution must be modular and robust.

If possible, the most elegant solution I could come up with is to use an Arduino Leonardo and stack 3 Adafruit Music Maker Shield on each other.

Reasons why I think it might be technically feasible:

  1. Each shield can share communication over I2C
  2. Looking at the VS1053b Datasheet (the IC used in the shield) the chip at max load consumes Maximum 60mA, and typically 37mA. Arduino can drive a max of 500mA so these three shields should consume a small portion of that.
    The Arduino will also be powered via 12v power supply.

Details i’m not so clear on:

  1. How will I differentiate between each shield when sending instructions or do I need to even need consider this if I want them to function as one?

Thanks

The shields use SPI. There are more slave select pins on the shield for diffrent devices of the shield. The first shield can use the default pins, but on next shields you must bend the default pins of the shield to side and connect them with a female to male jumper cable to other set of pins of Arduino.

Then in sketch you need to define the select pins in constructor for each instance of the handling object Adafruit_VS1053.

MikeAbbages:

  1. How will I differentiate between each shield when sending instructions or do I need to even need consider this if I want them to function as one?

If you always want to control all three shields at the same time I suppose you could try to just plug them on top of each other, all using the same pins. It seems like that would work for sending commands from the Arduino to all the shields. However, if that communication goes both ways that might not work so well because all the shields will be trying to talk on the SPI bus at the same time. I'm also not sure how the DREQ pin is used.

If you want to control them individually, each shield would have a different object in your code. The constructor for each object defines the unique pins used for that shield. For example:

Adafruit_VS1053_FilePlayer channelA = Adafruit_VS1053_FilePlayer(9, 10, 8, 3, 4);
Adafruit_VS1053_FilePlayer channelB = Adafruit_VS1053_FilePlayer(0, 1, 2, 5, 6);
Adafruit_VS1053_FilePlayer channelC = Adafruit_VS1053_FilePlayer(7, 11, 12, 13, 14);

Then you can control each shield via its object:

channelB.startPlayingFile("track002.mp3");

pert:

Adafruit_VS1053_FilePlayer channelA = Adafruit_VS1053_FilePlayer(9, 10, 8, 3, 4);

Adafruit_VS1053_FilePlayer channelB = Adafruit_VS1053_FilePlayer(0, 1, 2, 5, 6);
Adafruit_VS1053_FilePlayer channelC = Adafruit_VS1053_FilePlayer(7, 11, 12, 13, 14);

not 11,12,13. that is SPI.
first set should be the default, the pins connected on shield.
only one SD card is needed
the shield has reset connected to reset.

Juraj:
not 11,12,13. that is SPI.

Not on the Leonardo that MikeAbbages is using. SPI is only broken out to the ICSP on the Leonardo. Of course this is assuming MikeAbbages has shorted the necessary jumpers and installed the ICSP header on the shields. It should be possible to use 11, 12, 13 for software SPI with the Adafruit library but I wouldn't recommend it.

Juraj:
first set should be the default

I copied the pin numbers for channelA from the example sketch from the Adafruit example sketch so it should be using the regular pins.

Juraj:
only one SD card is needed

Perhaps. It's not clear to me from the information provided. I was thinking each shield would be playing its own file.

from shield tutorial and schema:

MCS - this is the VS1053 chip select pin, connected to Digital #7
DCS - this is the VS1053 data select pin, connected to Digital #6
CCS - this is the SD Card chip select pin, connected to Digital #4
DREQ - this is the VS1053 data request interrupt pin - connected to digital #3

sorry, I overlooked "Leonardo"

Ah, from the example comments I see it was written for use with their breakout board, not the shield so that's the reason why the pins are wrong for the shield. Definitely use the default pins for the bottom shield.

from example

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