The music player reads uncompressed audio data from an SD card in an immobile "base station." A pair of Xbee transceiver modules are used to stream data and control signals between the base station and a portable module. The battery powered portable module can be connected to speakers at any location within 30 feet of the base station.
Overview
Rationale:
In recent years, advances in solid state storage and the steady increase in the density of magnetic storage devices have made large data capacities readily accessible. In spite of these advances, the data storage circuitry in a portable music player occupies a considerable amount of circuit board space. This tends to make music players bulky. In addition, the means of storage consume a signficant amount of power, limiting battery life. Both of these factors reduce the portability of music players.
By moving music storage to a fixed module, we can remove these drawbacks. The storage module can draw its power directly from the residential mains supply, thus extending the battery life of the portable module. Inspired by networked media center products, we decided to implement a wireless link between this storage module and a portable module for maximum usability. Many wireless headphones already provide audio streaming functionality by utilizing bluetooth. However, these headphones typically have limited range. In addition, the music player itself needs to be kept close at hand for controlling playback. By implementing a bidirectional wireless link (see Figure 1 below), our portable module allows the user to remotely control playback.
High-level Design:
Figure 1: High level flow diagram demonstrating the operation of the wireless mp3 player.
This project used an Atmega644 microcontroller clocked at 20MHz in each of the two functional modules for processing. Memory storage is provided by a standard Secure Digital (SD) card. Xbee modules provide bidirectional wireless communication and we use the TLV5616 DAC chip for generating analog audio. The LM358 dual op amp provides active filtering to the output of the DAC. Music files can be added to the SD card using any computer with a multimedia card reader. Once the base station detects an SD card inserted into the holder, it awaits data requests from the portable module. The portable module requests data when required and feeds these values into the DAC. The DAC output is low-pass filtered by the op amp, which also buffers the DAC output before it reaches the audio output jack.
The portable module can send navigation commands (play, stop, next track or previous track) to the base station, where they are implemented. These control signals are transmitted over the Xbee as well. The SD card and Xbee modules operate at 3.3V, while all our other hardware required a 5V power supply. Extra power regulation was required to enable the use of these devices. In addition, we needed circuitry to allow 3.3V devices to interface safely with 5V microcontrollers while allowing a throughput on the order of several hundred kilobits per second.
Trade-offs:
Initially, we had planned to use an mp3 decoder IC in our project. However, the chip we obtained did not work and debugging it took up a lot of our design time. We then decided to stream in the uncompressed .wav data format instead.
Since streaming audio is a very bandwidth intensive task, it is hard to accomplish with cheap RF hardware. We had thought about transmitting the audio as an amplitude-modulated analog wave. However, this mode of transmission would be very sensitive to environmental noise. Since the Xbee modules offered enough bandwidth to get passable audio quality with a digital transmission method, we decided to use them instead.
The RF baud rate of the Xbee modules we used was 250 Kbps. However, the overhead of the 802.15.4 protocol meant that the actual maximum transfer rate attainable was much lower. Due to this limitation, we had to limit our music data to a resolution of 8 bits at a sampling rate of 8 KHz. This resulted in a net required bandwidth of 64 Kbps for consistent audio playback. The 8 bit resolution of the music data reduced the quality of the sound, but the limitation was a necessary consequence of our wireless hardware and the lack of any usable audio compression schemes.
Standards and Copyrights:
This project used the IEEE 802.15.4 standard for the wireless link. We used a pair of Xbee devices that implement this protocol. SD card technology is patented and use of the SD mode interface requires an expensive license. We used the SPI interface instead, which lacks access to encryption and speed features available in the SD interface, but is free to use. The SD cards used were formatted in the FAT file system. Part of the FAT standard is patented by Microsoft, but it pertains to implementing long file name extensions in devices made for sale. We did use the file name extension feature of FAT in our software. However, we are not planning on commercializing our music player, so the patent does not apply in our case.
Hardware
Base Station:
Figure 2: Photograph of the base station hardware setup with superimposed functional divisions. Click within an area to view details about that circuit.
- Xbee Transceiver Module
- This module provides wireless communication to/from the base station and the portable module at the ISM band of 2.4 GHz. The four pins connected are 3.3V, ground and the serial communication lines.
- Microcontroller Board
- The standard 4760 prototyping board pictured above is populated with an Atmega644 microcontroller clocked at 20 MHz. The serial transceiver and DB-9 connector have been soldered on for debugging purposes. They remain unused in the final implementation. The board accepts a 9-12 V input and regulates it down to 5 V for the on board microcontroller. A 0.1 inch header has been soldered into the row of breakout vias along one edge to allow it to plug directly into a breadboard. The onboard programming header allows in-situ reprogramming of the microcontroller's flash.
- Level Transceiver
- This circuit allows the 3.3 V SD card to interface with a 5 V microcontroller even at high bus speeds. The circuit is illustrated in the schematic below.
Figure 3: Schematic illustrating the bus interface circuitry between the SD card and the microcontroller on the base module.
The 5 V output signals from the microcontroller are reduced in voltage by means of a simple voltage divider with appropriate resistor values. The 3.3 V output signals from the SD card are shifted up to 5 V by means of a transistor-based level shifter to keep rise times within the SPI spec.
- SD Card
- SD cards with music files can be plugged into this Molex SD card holder. The card holder is soldered to a small piece of perfboard. The perfboard has a 0.1 inch header connected to the pins of the card holder. This header can be used to indirectly plug the surface mount SD card holder into the base station's breadboard. The holder itself is spring loaded, allowing easy removal and insertion of SD cards.
- 3.3 V Regulator
- The LT1587 linear regulator receives a 5 V input from the microcontroller board and regulates it down to 3.3 V for the SD card and the Xbee module.
Portable Module:
Figure 4: Photograph of the portable module's hardware setup with superimposed functional divisions. Click within an area to view details about that circuit.
- Microcontroller Board
- The standard 4760 prototyping board pictured above is populated with an Atmega644 microcontroller clocked at 20 MHz. The serial transceiver and DB-9 connector have been soldered on for debugging purposes. They remain unused in the final implementation. The board accepts a 9-12 V input and regulates it down to 5 V for the on board microcontroller. A 0.1 inch header has been soldered into the row of breakout vias along one edge to allow it to plug directly into a breadboard. The onboard programming header allows in-situ reprogramming of the microcontroller's flash.
- Pushbuttons
- The row of four push buttons visible in the photograph above allow the user to control music playback. One side of each button is connected to ground while the other connects to a GPIO pin on the microcontroller. A button press causes the appropriate microcontroller pin to read a low instead of a high, registering a possible button press.
- Xbee Transceiver Module
- This module provides wireless communication to/from the base station and the portable module at the ISM band of 2.4 GHz. The four pins connected are 3.3V, ground and the serial communication lines.
- 9 V Alkaline Battery
- The alkaline battery provides enough power to run the portable module for about four and a half hours.
- Output Filter
- This circuit uses an LM358 dual op amp to implement two cascaded multiple-feedback (MFB) topology low-pass filters. The cutoff frequency for this filter is 3 KHz, which is a little below the Nyquist frequency of our audio DAC to allow for increased attenuation of out-of-band frequency components. The circuit is implemented as shown in the schematic below:
Figure 5: Schematic illustrating the filter on the output of our DAC.
We chose this topology from among a number of other candidates for its low passband ripple, which makes it suitable for audio applications. We used a filter design wizard provided by Texas Instruments for calculating the component values required for this filter.
- Digital-to-Analog Converter
- The DAC we used in our application was the TLV5616, which provided a maximum of 12 bits of resolution and a sample rate of up to 100 KHz. While not an audio-oriented DAC, this chip has an easy-to-use SPI interface and provides greater resolution and higher sample rates than we were planning on using in our music player.
- 3.3 V Regulator
- The LT1587 linear regulator receives a 5 V input from the microcontroller board and regulates it down to 3.3 V for the Xbee module.
Software
Base Station:
Figure 6: High level software flow diagram for the base station microcontroller.
The SD card is connected to the microcontroller via the SPI port. We used information from
http://elm-chan.org/docs/mmc/mmc_e.html and a previous ECE 4760 project that also used SD cards - the Car MP3 Player.
To use the SD card, it must first be initialized. This is done in the MMC_SD_Reset function. This function wakes up the SD card by sending 80 clock pulses, then sends the idle command (0x40) to the card. Once the card is in idle mode, the activate command (0x41) is sent to the card till it responds with 0x01. The last thing this function does is to set the sector size to 512. The sequence of events described above is specified in
this application note.
After a successful initialization, the card can be read from and written to. Reading from the card was done by the MMC_SD_ReadSingleBlock() function. This function takes in a sector number and a pointer to a 512 byte buffer, and reads 512 bytes of data from the SD card. There is also a MMC_SD_WriteSingleBlock() function, but we did not implement write support in our project and it is never called. Once we could initialize the SD card and read from it, we went on to implement FAT file system support.
We used a FAT library from an mp3 project on http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=795&item_type=project">AVR freaks. This library had been modified to improve music file support and was based off of the FAT32 library on the
elm-channel. It provided the following functions to operate our music player:
- FAT_Init()
- -initializes the SD card through the MMC_SD_Reset function, and sets up a file system handler.
- FAT_NextCluster(unsigned long cluster)
- -returns the address of the next cluster in the file system.
- Search(BYTE *dir, struct direntry *fileinfo,WORD *Count, BYTE *type)
- -can be used to search for specific files in the directory. It returns the file(struct direntry) specified by the number Count, or the total number of files in a directory if Count is 0.
- FAT_LoadPartCluster(unsigned long cluster,unsigned part,BYTE * buffer)
- -allows us to read 512byte data blocks in a cluster from the SD card.
The code starts up by calling MMC_SD_Init(), which initializes the SPI port. Next, FAT_Init() is called, to initialize the SD card, create a file system handler and speed up the SPI port to about 5MHz. Next, the listfiles() function is called and it searches through the SD card for all types of music files and lists them over serial. Listfiles() performs a recursive call when it comes across a folder. Once this is done, the play() function is called. This function plays any .WAV in the root directory of the SD card. They are played in the order they are stored on the folder.
Play() starts by calling the search() function with a count of 0 and dir set to “\\”, the root directory. This procedure finds the total number of music files in that folder. The number of files obtained is stored and Search() is called again, with a count parameter of 1. This returns a file handle (fileinfo) to the first file in the directory. This file handle has information on the start cluster of the file, file size, file name and other metadata. The total number of sectors is calculated (filesize/512), and then we loop through all the sectors, calling FAT_LoadPartCluster() to read 512 byte sectors until the song is complete. Count is incremented, and the next music file is read from the card. All this occurs on the base station. This data is sent over serial to the Xbee, which transmits it to the portable module. The portable module has to request data, before the base station sends it, therefore, there is code in the play() function that waits for a request command (0x01) over serial before transmitting data. Other commands that are implemented are skip to next song (0x02), previous song (0x03) and stop (0x04).
Portable Module:
Figure 7: High level software flow diagram for the microcontroller on the portable module.
The code on the portable module handles playback of the music data and user input. The data originating from the SD card at the base station needs to be transferred into a buffer, transmitted over serial, transferred into the receive buffer at the portable module and finally sent out over SPI to the DAC. Taking this sequence into account along with the overhead of the 802.15.4 protocol, the maximum attainable data rate is far below the Xbees' theoretical maximum of 250 Kbps. We settled for a sample rate of 8 Khz mono and a resolution of 8 bits for our music. This resulted in a bandwidth requirement of about 64 Kbps.
To ensure a continuous flow of audio data in spite of adverse network conditions, we implemented a ring buffer of 3072 bytes. A data request command (0x01) is sent to the base station if the amount of data in this buffer is less than 512 bytes. Once the command is sent, the code waits till the buffer is about 150 bytes smaller before sending another request.
Upon receiving a data request command, the base station transmits a data stream of 2048 bytes then stops and waits for a new request before sending out more data. RF systems like the Xbees are by nature half duplex; they can use their antenna for transmitting or receiving, but not both simultaneously. Once a data request command is sent to an Xbee, there will be an inevitable delay before it is transmitted, since the Xbee is also receiving an inbound data stream. We use a large ring buffer to decrease the probability of network latency causing buffer underflow and silent patches during music playback. The serial receive function on the portable module's microcontroller is interrupt driven. Data received is immediately added to the ring buffer and the write pointer is incremented.
We created a timer interrupt that fires every 125 milliseconds (8 KHz). Within this interrupt, a single sample is transmitted to the DAC from the ring buffer and the read pointer is incremented. Data is sent to the DAC via the SPI port on PORTB. The DAC we used (TLV 5616) is a 12 bit DAC, and has a 16 bit data packet structure. The first 4 bits form a command that defines speed and operating range while the lower 12 bits are the data. The SPI port is set to run at 10 MHz, to ensure that the microcontroller spends as little time in this interrupt as possible. This reduces the chance of dropped RF packets, since serial reads are handled in the main loop.
The last thing the code does is to check a set of pins on PORTC for user button presses. The pins are debounced via the task1() function, which runs every 30 milliseconds. There are 4 buttons in total, performing the functions listed:
- Play/Pause
- -this can be used to pause playback. Pause stops portable module from requesting new data or playing anything over the DAC. The base station does not need to be alerted about this button press as its default behavior is to wait till data is requested.
- Next
- -causes the portable module to send a command to the base station to skip to the next song. It also resets the ring buffer pointers to zero to start the new song.
- Previous
- -causes the portable module to send a command to the base station to skip to the previous song. It also resets the ring buffer pointers to zero to start the new song.
- Stop
- -sends a command to the base station to stop streaming data and to reset to the first song. It also resets the ring buffer. The play button must be pressed in order to restart music playback.
Results
Our wireless music player performed quite well given the limitations imposed by low bandwidth and the lack of audio compression schemes. Most of our test tracks were songs originally encoded in the MP3 format, then converted to WAV for the purposes of testing the music player. This meant that compression artefacts were audible at several points on each track. However, there was no severe distortion for the majority of the track's length. Our buffering scheme for the streaming audio data worked well, there were no detectable patches of silence during playback.
The pushbuttons meant for user control of playback were responsive and reliable. Though network latency sometimes introduced a detectable delay between a button push and the music player's response, it was never long enough to affect to prompt a second attempt on the user's part.
For testing the frequency accuracy for the system as a whole, we generated a 1 KHz tone using a trial version of the Soundpad software suite. This tone was saved to the SD card formatted as an uncompressed WAV file with a resolution of 8 bits and a sample rate of 8 KHz. We used the the base station to play the recorded tone from the SD card and measured the analog output from the portable module. The oscilloscope result of the output waveform from the portable module is shown below:
Figure 8: Oscilloscope view of 1 Khz sine wave output from the DAC on the portable module. Note the frequency measurement to the right of the oscilloscope trace.
The high frequency noise visible in the waveform above was most probably switching noise originating from the microcontroller, since the microcontroller and the DAC share power supplies. The 1 Khz tone itself is rendered very accurately. Most of the overtones from the DAC's output have been eliminated by the filter.
Our project did not involve high voltages or moving mechanical parts. Since the portable module uses a 9 volt battery as its power source, it is highly unlikely that a user could receive an electrical shock while operating our music player. Therefore, there are very few safety hazards associated with it. The volume on external speakers should be kept low when connecting or disconnecting the portable module's audio output. Such events tend to generate a loud popping or clicking noise which could damage the hearing of anyone standing too close to the speakers.
The Xbee transceiver modules we used for our project were capable of operating in an advanced programming mode that allows node addressing and point-to-point links. Since we had no real use for this functionality, we decided to operate them in their default transparent mode, where each message is simply broadcast to any compatible receiver. As a result, we had packet collisions with at least one other project group who were using the same transceivers.
Our wireless MP3 player can be used by anyone who is capable of interacting with electronic devices via tactile means and can of perceive auditory feedback.
Conclusions
The wireless music player met our expectations in terms of usability and quality of sound output. At the beginning of the project, we had hoped to stream and decode MP3s in addition to uncompressed music. Given more time, we would focus on debugging the MP3 decoder IC. A working decoder would have allowed us to use a much better DAC and would lead to a large improvement in audio quality over our current setup.
We originally planned to have a printed circuit board for the portable module fabricated and shipped to us after we had a working prototype. To this end, we applied for and obtained a scholarship worth $60 from a circuit board manufacturer known as
Sunstone Circuits. Unfortunately, time constraints meant that we were unable to take advantage of the scholarship. Nevertheless, we would like to take this opportunity to thank Sunstone Circuits for their support.
The implementation of the 802.15.4 wireless communication standard was handled entirely by the hardware and firmware on our Xbee transceiver modules, which were fully compliant with this standard.
We reused libraries written by different people in several different sections of our music player's software. In all cases, the author of the software specified his code as freely available for non-commercial use. Our project has no associated patent or publication opportunities. We did not have to sign any kind of non disclosure agreements in order to acquire samples.
Ethical Considerations:
All decisions we made in the development and design of this project adhere to the IEEE code of ethics. The music player does not pose a threat to the safety, health and welfare of the public. It was conscientiously designed with safety in mind. There are no sharp, or moving parts, and the wiring is safely done. The device operates at low voltages and the wireless transmission is 50mW in power and does not pose a radiation threat to the general public. As a music playing device, there may be some conflict of interest with other devices out in the market, but since we are not commercializing this product, the conflicts do not come into play. This document is accurate to the best of our knowledge and reflects all the relevant issues surrounding this project. We were not bribed by any parties during this project. This project has led to a deeper understanding of the technology we used, including SD storage devices, file systems, 802.15.4 transmission standard, DAC conversions and analog filters. We have looked into different technologies in researching our project and have learnt a lot about microcontroller based embedded systems. In addition, we consulted the T.A.’s and Professor Land on any issues that we did not understand or needed guidance on. This document discloses fully any work done by others, and the sources of said work. We accepted criticism and suggestions given to us over this project, and in the process offered such constructive criticism to others. There was no discrimination of any one in the process of developing this project and we did our very best to ensure that our fellow colleagues adhered to the IEEE code of ethics.
Legal Considerations:
This project utilized a pair of Xbee modules for wireless transmissions. The ZigBEE is based on the IEEE 802.15.4 protocol and adheres to the FCC’s standard for unlicensed short range digital transmissions i.e.
1. It operates in the 2.4GHz band which is unlicensed.
2. It does not interfere with the operation of devices in licensed bands, and accepts any intereferance from such devices.
3. The maximum power output of the modules is below 100mW.
Appendix
Task list
Base station hardware James and Saurav
Portable module hardware James and Saurav
FAT file system and SD card software interface James
Xbee wireless module configuration and interfacing Saurav
Portable module software James
Audio filter and DAC hardware Saurav
Ordering and buying parts Saurav and James
Report writing (webpage) Saurav and James
References
Atmega644 datasheet: http://www.atmel.com/dyn/resources/prod_documents/doc2593.pdf TLV5616 datasheet: http://focus.ti.com/lit/ds/symlink/tlv5616.pdf Xbee datasheet: http://www.digi.com/products/wireless/point-multipoint/xbee-series1-module.jsp FAT file system library: http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=795&item_type=project SD card interface: http://www.cs.ucr.edu/~amitra/sdcard/Additional/sdcard_appnote_foust.pdf Car MP3 player project: http://instruct1.cit.cornell.edu/courses/ee476/FinalProjects/s2007/cd247_maw72/cd247_maw72/index.html
Code
The Portable module code can be found in
dac.c
The FAT32 library is contained in
FAT.c and
FAT.h
Code to interface with the Sd card is found in
MMC_SD.c and
MMC_SD.h
The base station code is in
base.c
Schematics
Figure 9: Shematic of the audio dac we used. This is the TLV5616, a 12bit high speed DAC.
Figure 10: Shematic of the second order lowpass filter we used to smooth out the audio output.
Figure 11: Shematic of the level shifting SD card circuit we used.
Figure 12: Shematic of the protoboard provided by Bruce Land for 4760 projects.
Parts List:
Base Station-
Description | Quantity | Total Cost |
SD Card | 1 | $0.00 (In possession) |
SD socket | 1 | Sampled (molex) |
Custom PC board | 1 | $4.00 |
Xbee module | 1 | $20.00 |
White board | 1 | $6.00 |
Atmega644 | 1 | $8.00 |
Max233 | 1 | Sampled (maxim-ic) |
DIP Socket | 1 | $0.50 |
Total cost for base station parts = $38.50
Portable Module-
Description | Quantity | Total Cost |
Custom PC Board | 1 | $4.00 |
Mega16 | 1 | $2.00 |
Xbee module | 1 | $20.00 |
DAC (TV5616) | 1 | In possession |
Pushbuttons | 4 | In possession |
DIP Socket | 1 | $0.50 |
Opamp (LM358) | 1 | $2.00 |
3.5mm connector | 1 | $2.00 |
Resistors and Capacitors | 1 | $1.00 |
Total cost for portable module parts = $31.50
Total cost overall = $70.00
James Mwaura and Saurav Bhatia
©2005 Cornell University
Source: http://instruct1.cit.cornell.edu/