| 
  • If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • You already know Dokkio is an AI-powered assistant to organize & manage your digital files & messages. Very soon, Dokkio will support Outlook as well as One Drive. Check it out today!

View
 

MarceloMoreira_FinalProject

Page history last edited by Marcelo Aires Moreira 10 years, 8 months ago

Stanford University Student: Marcelo Aires Moreira

Stanford ID: 05923879

Press Play: Interactive Device Design

Summer 2013

 

 

Final Project

 

1. Introduction

     My final project for EE47- Interactive Device Design is a Bluetooth Mp3 playerthat is controlled by a Mac Book Pro.

 

2. Design point of view

     During the first weeks of class, the professor explained us about the projects and he said that we were pretty much free about the project issues, as soon as we were able to apply the learned course materials in a practical way. In this way, the first project idea I had was to design a kind of musical instrument or a musical modulator device based on MID. However, after talking to my brother and thinking about the context of my house, I figured out that I could build something more useful for now. It turns out that we live in a duplex apartment and in the second floor we have a nice lounge where we always listen to music using different devices (i.e. Iphone 5) connected to amplifiers, during social events. The problem is that we always have to reach the devices to control the music settings (such as change song, change volume, pause, play).

     Therefore, I had this idea of building a Bluetooth mp3 player that was controlled by my Mac Book Pro in such a way that I would be able to control the mp3 player from a fair distance via Bluetooth and I would not need to reach the device every time I needed to adjust its settings. 

 

3. Verplank diagram

 

 

4. Paper Prototype

 

5. State diagram

 

6. Execution

     During the whole class schedule, we had weekly labs, where we learned specific hardware and software issues related to device design. During the first labs we learned about different electrical and mechanical engineering concepts and we learned how to use different sensors. By the end of the last lab (lab 6), we were able to build a basic mp3 player that was just able to read all the songs in a SD card and play them all. Then, the execution of my project was an extension of lab 6, where I turned the basic mp3 player into a more real mp3 player and I added more features to it. I started designing and testing it using a breadboard, and my aim was to solder it in a perfboard and make a nice box to hold it afterwards.

     The first things I added to the basic mp3 player were a few switches in order to set buttons where I could control the mp3 player settings by hardware. So I added 5 buttons:

  • Button 1: mp3 plays/pauses;

  • Button 2: mp3 goes to next song;

  • Button 3: mp3 goes to previous song;

  • Button 4: mp3 increases volume;

  • Button 5: mp3 decreases volume.

 

Once I tested all those buttons and make sure all of them were working well, I went to the next step, that was to set up and test the Bluetooth Module to make sure it was working well, as well.

At this time I had either the real mp3 player or the Bluetooth Module working well, so it was time to attach those two things together.

So I changed the code in order to make the mp3 player to be controlled either by the hardware (5 buttons) or via Bluetooth, where I would send data from my Mac Book Pro, and the Arduino Micro would receive it and ask the mp3 player to perform each task correspondent to the data received. The correspondent Mac Book Pro sent data and mp3 tasks are listed below:

  • Mac book send a ‘2’: mp3 plays/pauses;

  • Mac book send a ‘3’: mp3 goes to next song;

  • Mac book send a ‘1’: mp3 goes to previous song;

  • Mac book send a ‘+’: mp3 increases volume;

  • Mac book send a ‘-’: mp3 decreases volume.

 

7.Challenges

          The main challenge I had it was while debugging the code.

I tested all the hardware before testing the whole code, and it worked fine. However, after testing and compiling the code for the first time, the mp3 player did not work. When one tried to listen to any music, the song was coming with a delay every second.

After spending a long time debugging the code, I realized with David Sirkin, the professor of the class, that the problem was a Memory Ram issue. The SD card was sending 512 bytes of data to be read at each time and the Memory Ram could not support this much. Then, after changing this rate to 64 bytes each time, the mp3 player worked well.

 

8. Project code

The project code is composed of two Arduino software modules:

 

Module 1 – Main Code:

 

#include <SD.h>

#include <EEPROM.h>

#include <mp3.h>

#include <mp3conf.h>

#include <Adafruit_GFX.h>

#include <Adafruit_PCD8544.h>

#include <SoftwareSerial.h>

 

#define sd_cs 17 // 'chip select' line for the microsd card

#define mp3_cs A0 // 'command chip select' connect to cs pin

#define mp3_dcs A1 // 'data chip select' connect to bsync pin

#define mp3_rst -1 // 'reset' connects to decoder's reset pin

#define mp3_dreq A2 // 'data request line' connect to dreq pin

#define lcd_clk 7 // 'serial clock' connect to lcd's clk pin

#define lcd_din 6 // 'serial data input' connects to din pin

#define lcd_dc 5 // 'data/command input' connect to d/c pin

#define lcd_cs -1 // 'slave chip select' connects to cs pin

#define lcd_rst 4 // 'reset' connects to graphic lcd rst pin

#define read_buffer 64 // size (bytes) of the microsd read buffer

#define mp3_vol 175 // default volume. range min=0 and max=254

#define max_name_len 13

#define max_num_songs 40

#define max_title_len 60

 

Adafruit_PCD8544 lcd = Adafruit_PCD8544(lcd_clk, lcd_din, lcd_dc, lcd_cs, lcd_rst);

 

File sd_file; // object to represent a file on a microsd

unsigned char num_songs = 0, current_song = 0;

char fn[max_name_len];

char title[max_title_len + 1];

const int buttonPin1 = 8;

const int buttonPin2 = 9;

int buttonState1 = 0;

int buttonState2 = 0;

int vol = 0;

SoftwareSerial Genotronex(10, 11);

int BluetoothData;

 

enum state { DIR_PLAY, MP3_PLAY, PAUSED };

state current_state = DIR_PLAY;

 

void sd_file_open() {

 

get_current_song_as_fn();

sd_file = SD.open(fn, FILE_READ);

print_title_to_lcd();

}

 

void mp3_play() {

unsigned char bytes[read_buffer]; // buffer to read and send to the decoder

unsigned int bytes_to_read; // number of bytes read from microsd card

 

bytes_to_read = sd_file.read(bytes, read_buffer);

Mp3.play(bytes, bytes_to_read);

 

if (bytes_to_read < read_buffer) {

sd_file.close();

 

if (current_state == MP3_PLAY) {

current_state == PAUSED;

}

}

}

 

void dir_play() {

if (sd_file) {

mp3_play();

}

else {

 

if (current_song < (num_songs - 1)) {

current_song++;

sd_file_open();

 

}

else {

current_song = 0;

sd_file_open();

//current_state == PAUSED;

}

}

}

 

void PlayPause()

{

static unsigned long last_interrupt_time = 0;

unsigned long interrupt_time = millis();

// If interrupts come faster than 200ms, assume it's a bounce and ignore

if (interrupt_time - last_interrupt_time > 200)

{

if(current_state == DIR_PLAY){

current_state = PAUSED;

}

else{

current_state = DIR_PLAY;

}

}

last_interrupt_time = interrupt_time;//digitalWrite(pin, LOW);

}

 

void NextSong()

{

static unsigned long last_interrupt_time = 0;

unsigned long interrupt_time = millis();

// If interrupts come faster than 200ms, assume it's a bounce and ignore

if (interrupt_time - last_interrupt_time > 200)

{

sd_file.close();

current_state = DIR_PLAY;

}

last_interrupt_time = interrupt_time;//digitalWrite(pin, LOW);

}

 

void PreviousSong()

{

static unsigned long last_interrupt_time = 0;

unsigned long interrupt_time = millis();

// If interrupts come faster than 200ms, assume it's a bounce and ignore

if (interrupt_time - last_interrupt_time > 200)

{

sd_file.close();

if(current_song == 0){

current_song = num_songs-2;

}

else{

current_song = current_song - 2;

}

current_state = DIR_PLAY;

}

last_interrupt_time = interrupt_time;//digitalWrite(pin, LOW);

}

 

void setup() {

vol = mp3_vol;

lcd.begin(50);

lcd.print("Barebones Mp3!");

lcd.display();

Mp3.begin(mp3_cs, mp3_dcs, mp3_rst, mp3_dreq);

Mp3.volume(vol);

sd_card_setup();

sd_dir_setup();

sd_file_open();

attachInterrupt(2, PlayPause, FALLING);

attachInterrupt(0, NextSong, FALLING);

attachInterrupt(1, PreviousSong, FALLING);

pinMode(buttonPin1, INPUT);

pinMode(buttonPin2, INPUT);

Genotronex.begin(9600);

}

 

void loop() {

switch(current_state) {

 

case DIR_PLAY:

dir_play();

break;

 

case MP3_PLAY:

mp3_play();

break;

 

case PAUSED:

break;

}

 

buttonState1 = digitalRead(buttonPin1);

if (buttonState1 == HIGH) {

if(vol<254){

vol = vol++;

}

}

 

buttonState2 = digitalRead(buttonPin2);

if (buttonState2 == HIGH) {

if(vol>0){

vol = vol--;

}

}

 

if (Genotronex.available()){

BluetoothData=Genotronex.read();

 

if(BluetoothData=='1'){ // if number 1 pressed ....

PreviousSong();

Genotronex.println("Going back to the previous song.");

}

if (BluetoothData=='2'){// if number 0 pressed ....

PlayPause();

Genotronex.println("Play/Pause song.");

}

if (BluetoothData=='3'){// if number 0 pressed ....

NextSong();

Genotronex.println("Going to the next song");

}

if(BluetoothData=='='){ // if number 1 pressed ....

if(vol<254){

vol = vol+10;

Genotronex.println("Volume Increased");

}

}

if(BluetoothData=='-'){ // if number 1 pressed ....

if(vol>0){

vol = vol-10;

Genotronex.println("Volume Decreased");

}

}

}

Mp3.volume(vol);

}

 

 

Module 2 – Utilities:

 

File sd_root;

 

void sd_card_setup() {

if (!SD.begin(sd_cs)) {

lcd.clearDisplay();

lcd.println("sd card failed\nor not present");

lcd.display();

return;

}

sd_root = SD.open("/");

 

if (!sd_root) {

lcd.clearDisplay();

lcd.println("couldn't mount\nsd root volume");

lcd.display();

return;

}

}

 

void sd_dir_setup() {

num_songs = 0;

 

sd_root.rewindDirectory();

 

while (num_songs < max_num_songs) {

// break out of while loop when we check all files (past the last entry).

 

File p = sd_root.openNextFile();

if (!p) break;

 

if (p.name()[0] == '~' || p.name()[0] == '.' || p.isDirectory()) {

continue;

}

 

char i;

 

for (i = max_name_len - 5; i > 0; i--) {

if (p.name()[i] == '.') break;

}

i++;

 

// only store mp3 or wav files in eeprom (for now). if you add other file

// types, you should add their extensions here.

 

if ((p.name()[i] == 'M' && p.name()[i+1] == 'P' && p.name()[i+2] == '3') ||

(p.name()[i] == 'W' && p.name()[i+1] == 'A' && p.name()[i+2] == 'V')) {

 

for (char i = 0; i < max_name_len; i++) {

EEPROM.write(num_songs * max_name_len + i, p.name()[i]);

}

num_songs++;

}

}

}

 

void get_current_song_as_fn() {

for (char i = 0; i < max_name_len; i++) {

fn[i] = EEPROM.read(current_song * max_name_len + i);

}

}

 

void print_title_to_lcd() {

get_title_from_id3tag();

 

lcd.clearDisplay();

lcd.println(title);

lcd.display();

}

 

9. Video of the final working player

 

Youtube link:

http://www.youtube.com/watch?v=rd3QcPuG9vQ&feature=youtu.be

 

10. Conclusion

     Thus, I had a nice experience developing my project. I learn a lot about electronics, mechanics and design. Designing the Bluetooth mp3 player took me a long time. As I said, the most challenge part for me was to debug the code. That was what took me the longest time. However, all the time spent on it was worth. Getting your own nice project to work brings such a great feeling.

     The next steps I want to perform are:

-Solder components in a perfboard;

-Build a box to hold my mp3 player.

     Therefore, I enjoyed a lot designing my final project and taking the class.

 

Comments (1)

kdade said

at 8:15 pm on Aug 19, 2013

Dear Marcelo,

You started this project with a great point of view: bluetooth speakers solve a very specific need of you and your brother. Your Verplank diagram and state diagram are clear, and the sketch provides a great visual tool for understanding the project.

We are impressed with your design process, and we think it was a great idea to get your MP3 player working first with onboard functionality, before progressing with wireless. We would love if you could elaborate more on how you designed your code for the bluetooth controller, and also about how you tackled the RAM issue. Remember, you want to aim for a report that helps other people follow in your footsteps, and this includes documenting how you solved the problems that arose.

You mention that you would like to solder up the circuit on a perfboard, and create a nice housing for it, and we would really love to see a finished project along those lines. Perhaps a real physical paper prototype would help you plan out the final look and feel of your device.

Overall, this is a great project, and it is awesome that you have built a wireless device in such a small amount of time!

Best,
Kevin, Matt, David, Jessica, Vivien

You don't have permission to comment on this page.