For the robotic xylophone to actually be functional, there needs to be some means of storing in memory data needed to play the songs. In general, for Arduino projects I have found four different options for data storage. I’m sure there are more than just these four, but these are the ones that seem to be mentioned most often in Arduino tutorials.
- Internal Arduino EEPROM
- External I2C EEPROM
- SPI Flash
- SD Card with Data Logger Shield
Internal Arduino EEPROM
The internal Arduino EEPROM is not really an option because it is just not large enough to be practical. The Arduino Uno has 1024 bytes of EEPROM, which would be enough for only about 60 seconds of music. It could be done this way, but it would not make for nearly as interesting of a project in the end. I have found, however, that the internal EEPROM is a very good place to store user-selectable settings, such as a selected Play List, or a selected Play Mode (e.g. Single, Sequential, or Shuffle). More information on programming with the Arduino internal EEPROM can be found here.
External I2C EEPROM
A second option, which could work fairly well is to use external I2C EEPROM. I2C EEPROM is available in the DIP8 form factor, such as this 256 kbit (32 KB) chip from SparkFun . By tying address pins to 5V or ground, it is possible to have up to 8 of these EEPROM together, for a total of 256 KB of memory. This would be enough space to hold approximate 4 hours of music, which is way more than most people doing this project would ever need. In fact my original robotic xylophone, shown in this YouTube video, used this External I2C EEPROM. Another positive on this option is that these EEPROM chips can handle 5V logic from the Arduino directly, so there is no need for voltage dividers or logic level shifter cicuits. Some tutorials for using this external EEPROM with Arduino are found here, here, and here. Also see the code examples on the official Arduino website.
SPI Flash is very similar to External I2C EEPROM, but with a few notable differences.
- SPI Flash, as the name suggests, uses the Serial Peripheral Interface (pins 10-13 on the Arduino Uno), whereas I2C uses pins A4 and A5 on the Arduino Uno
- Most SPI Flash chips cannot handle 5V logic from the Arduino directly, and so it is necessary to use either a logic level shifter, or a voltage divider made from resistors.
- SPI Flash chips are available in much larger capacities. I have seen Winbond SPI available in sizes ranging from 1 MB to 16 MB.
16 MB of data storage would be enough space for over 250 hours of music. (Who in their right mind would ever want to listen to a robotic xylophone play for 10 days straight? I’m sure no one, but it is an interesting thought.)
SD Card with Data Logger Shield
The final option is to use an SD card. There is not an easy was to connect an Arduino directly to an SD card, so most projects require using a Data Logger Shield, or some other board with the necessary hardware. The advantage to this one is that it is very easy to transfer data between a computer and the SD card. Just insert the SD card directly into the computer’s SD card reader. The disadvantage is that the SD card and Data Logger Shield together are more expensive than SPI Flash or I2C EEPROM, especially, if you do not need the Gigabytes of storage provided by the SD card. But in the world of Arduino projects, the SD card is probably used more than any of the other options for applications where a large amount of data needs to be stored.
Which Option is Best?
So which of these options is best for the robotic xylophone project? In 2015, when I started working on a new robotic xylophone, to be controlled by an Arduino, I was convinced that the answer was SPI Flash. Since I was trying to make the project as inexpensive as possible, I didn’t want to add the expense of a Data Logger Shield and SD card. SPI Flash seemed perfect. It had enough space for all the songs I would ever want to put on the xylophone, and it was very easy to use resistors and a soldierless breadboard to interface it with the Arduino Uno. See here for a wiring diagram, and a picture of my test setup. The challenge to using SPI Flash was how I would be able to load songs into the flash memory from a computer. I overcame this challenge by writing my own software library which would read and write data via the serial port. The computer uses serial to communicate with the Arduino, and then the Arduino does the actual reading/writing to/from the SPI Flash.
But as I was preparing to document and publish my software, I discovered something that would be a problem for someone else trying to following my instructions and build a device like this. The Winbond SPI Flash, in the DIP8 form factor that fit so nicely on a soldierless breadboard, was no longer available on the websites that I had purchased it previously. Adafuit now shows this part as discontinued, and none of my other go-to websites carried this part either. In fact, as of today (June 2018) when I do a Google Shopping search for “Winbond SPI Flash DIP8” the only place I can get this part is on eBay. So much for making this project easy for others to build.
Falling back to I2C EEPROM could still be an option. The library I wrote for interfacing with SPI Flash could also be used for I2C EEPROM. But then I considered something else. Although my code worked just fine for what I needed to do with it, it was not in a state that I could publish it, and be confident that others would be able to use it trouble free. I could put in a lot of time and effort into getting the code into a publishable state, but that just didn’t seem as much worth the effort, due to the much more limited capacity of the I2C EEPROM.
But then I considered the fourth option, an SD card with Data Logger shield. By that time, I wasn’t as much concerned with cost as when I first started. Adding an extra $10-$20 to the cost could be worth it, if the result would be something beneficial.
In order to use SPI Flash, I needed to write a PC-based software application which could decompile MIDI files, and then load the timing and notes into the SPI Flash in a format that could be read by the Arduino. The PC-based software had over 10,000 lines of code, while the Arduino program had nearly 5,000 lines of code. A large part of that code was for decompiling and re-arranging the midi data and transferring that data to the SPI Flash via Serial.
But with the SD Card, I wondered if there would be a way to save a MIDI file directly onto the SD card, and then have the Arduino read the MIDI file directly and play the notes in real time. The answer turned out to be a resounding Yes. I found an Arduino library MD_MidiFile by MajicDesigns, which would do exactly what I need. This library reads a MIDI file from an SD card, and then parses the events in real time. That eliminated a significant part of the code I needed to make it work with SPI Flash. I had to re-write the Arduino program almost from scratch, but in the end, the new program was just over 2,000 lines of code. But the biggest benefit was that I could completely eliminate the PC-based software application.
So which option is best? At this point, I have concluded that the SD Card works best. What you will see on in the Parts List and Instructions is “version 2.1” of the robotic xylophone, designed using the SD Card and Data Logger Shield. However, I have also kept links to Parts List and Instruction pages for “version 2.0” which is the robotic xylophone designed around SPI Flash. Even though using the SD Card is what currently seems the most practical, I still think there is value in showing how data storage could be done using SPI Flash.
Next: MIDI Files