Final project


Design POV

     When I go running and want to listen to music I need to carry my phone with me and as it is uncomfortable in my pocket I find myself holding it while I run. 

This is not a preferable method to listen to music as I prefer to keep my hands free. Something else that I don't like about carrying a phone around is that it 

keeps me connected to people (phone calls, texts, ect) and I would prefer to just run. The possibilities of damaging my phone is also something that makes

me very hesitant about lugging it around while I jog. Another problem with using a phone as a mp3 player, especially modern touch screen phones is that

you must look at the device in order to change the music. 

 

     So I had an idea to make a mp3 player that is specifically for running, comfortable, and nearly "disposable". Another aspect to the design that I wanted to 

implement was discreteness. I find the electronic devices that look as normal and common as possible to be the coolest and most appealing to me. Examples are 

the nike fuel band (looks just like a wrist band) and google glass (if smaller it would be just like glasses). So I decided to make the components of my mp3 player

as hidden as possible. I also wanted the UI to be hidden (only known to the user) and tactile so that one can just feel where the buttons are without looking for it.

So the main design points are:

 

The components that I used are

 

Housing

The way I would mount it to sew a armband out of a cloth material (neoprene preferable but anything will work for the prototype) and line the interior with a plastic liner

to make it splash proof. Velcro will be the way to attach instead of using lacing as it faster and easier to use. I also want the headphone jack to be exposed as well as the

SD card and the power switch for ease of use. Additional features I want to add are a credit card holder and headphone wire holder to keep it out of the way.

 

State diagram

 

Verplank Diagram

 

Paper Model

 

Housing

 

Features

  card holder

 

 cable managment

 

 

Code

comments removed to save page space

//code from mp3 library provided by the EE47 class 

 

#include <SD.h>

#include <SPI.h>

#include <EEPROM.h>

 

#include <mp3.h>

#include <mp3conf.h>

  

#include <Adafruit_GFX.h>

#include <Adafruit_PCD8544.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_dreq      A2        // 'data request line' connect to dreq pin

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

  

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

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

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

 

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

int 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

 

#define pausePin 3

  

File sd_file;           

  

unsigned char num_songs = 0, current_song = 0;

 

char fn[max_name_len];

 

char title[max_title_len + 1];

 

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_state = PAUSED;

    }

  }

}   

  

void setup() {

 

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

  

  sd_card_setup(); 

 

  sd_dir_setup();

 

  sd_file_open();

 

  pinMode(pausePin, INPUT_PULLUP);

  pinMode(2, INPUT_PULLUP);

  pinMode(0, INPUT_PULLUP);

  pinMode(7, INPUT_PULLUP);

  pinMode(1, INPUT_PULLUP);

 

  attachInterrupt(0, pauseDebounce, FALLING); //pin 3

  attachInterrupt(2, forwardDebounce, FALLING); //pin 2

  attachInterrupt(1, backwardDebounce, FALLING); //pin RX

  attachInterrupt(4, volUpDebounce, FALLING); //pin 7

  attachInterrupt(3, volDownDebounce, FALLING); // pin TX

}

 

void pauseDebounce() {

  static unsigned long last_pause_time = 0;

  unsigned long pause_time = millis();

  if (pause_time - last_pause_time > 20){

    pause();

  }

}

 

void forwardDebounce () {

  static unsigned long last_forward_time = 0;

  unsigned long forward_time = millis();

  if (forward_time - last_forward_time > 20){

    forward();

  }

}

 

void backwardDebounce() {

  static unsigned long last_back_time = 0;

  unsigned long back_time = millis();

  if (back_time - last_back_time > 20){

    backward();

  }

}

 

void volUpDebounce() {

  static unsigned long last_up_time = 0;

  unsigned long up_time = millis();

  if (up_time - last_up_time > 200){

    volUp();

  }

}

 

void volDownDebounce() {

  static unsigned long last_down_time = 0;

  unsigned long down_time = millis();

  if (down_time - last_down_time > 200){

    volDown();

  }

}

 

void loop() {

  switch(current_state) {

 

    case DIR_PLAY:

      dir_play();

      break;

 

    case MP3_PLAY:

      mp3_play();

      break;

 

    case PAUSED:

      break;

  }

}

 

void pause() {

  if(current_state == DIR_PLAY) {

    current_state = PAUSED;

  }

  else {

    current_state = DIR_PLAY;

  }

}

 

void forward() {

  if (current_song != num_songs - 1) {

    Mp3.cancel_playback();

    sd_file.close();

    current_song++;

    sd_file_open();

  }

}

 

void backward() {

  if (current_song != 0) {

    Mp3.cancel_playback();

    sd_file.close();

    current_song--;

    current_song--;

    sd_file_open();

  }

}

 

void volUp() {

  if(mp3_vol < 244){

    mp3_vol = mp3_vol + 5;

    Mp3.volume(mp3_vol);

    Serial.print(mp3_vol);

  }

}

 

 

void volDown() {

  if(mp3_vol >= 130) {

    mp3_vol = mp3_vol - 5;

    Mp3.volume(mp3_vol);

    Serial.print(mp3_vol);

  }

}