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

Final Project Code - Kyle Moore

Page history last edited by Kyle Moore 12 years, 10 months ago

/* MP3 Stuff */

#include <mp3.h>

#include <mp3conf.h>

 

#define MP3_CS      5             // 'command chip select' to cs pin

 

#define DCS         14            // (Pin A0) 'data chip select' to bsync pin

#define RST         6             // 'reset' to decoder's reset pin

#define DREQ        15            // (Pin A1) 'data request line' to dreq pin

 

/* SD Stuff */

#include <SD.h>

 

#define SD_CS       4             // 'chip select' for SD card

 

static int clickingFinishedPin = 7;

 

#define MAX_FILE_COUNT 30

#define READ_BUFFER_SIZE 256 // Size of the microSD read buffer

 

Sd2Card card;

SdVolume volume;

SdFile root;

 

char **files;

int numFiles;

int currentFileIndex = -1;

 

byte playbackVolume = 230;

boolean dialing = false;

volatile boolean playing = false;

volatile int numClicks = 0;

 

unsigned long howFarIn = 0;

unsigned char bytes[READ_BUFFER_SIZE]; // buffer to send to the decoder

unsigned int numBytesRead;       // number of bytes read from sd card

SdFile currentFile;

 

unsigned long lastCheckTime = 0;

 

enum Mode {

  MODE_NORMAL,

  MODE_SET_VOLUME,

  MODE_SEARCH

};

int control_mode = MODE_NORMAL;

 

enum ModeLights {

  PLAYING_LIGHT,

  SET_VOLUME_LIGHT,

  SEARCH_LIGHT

};

static int lightPins[] = {0, 9, 2};

 

int listMP3Files(SdFile *dir, char **buf) {

  int count = 0;

  dir_t p;

 

  dir->rewind();

  while (dir->readDir(&p) > 0 && count < MAX_FILE_COUNT) {

    // done if past last used entry

    if (p.name[0] == DIR_NAME_FREE) break;

 

    if (DIR_IS_SUBDIR(&p)) continue;

 

    // skip deleted entry and entries for . and  ..

    if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') continue;

 

    // only list files

    if (!DIR_IS_FILE(&p)) continue;

 

   if(p.name[8] != 'M' || p.name[9] != 'P' || p.name[10] != '3') continue;

 

    char nameBuf[13];

    uint8_t pos = 0;

    for (uint8_t i = 0; i < 8; i++) {

      if (p.name[i] != ' ') {

        nameBuf[pos] = (char)p.name[i];

 

        pos++;

      }

    }

 

    nameBuf[pos] = '.';

    nameBuf[pos+1] = (char)p.name[8];

    nameBuf[pos+2] = (char)p.name[9];

    nameBuf[pos+3] = (char)p.name[10];

    pos += 4;

 

    // add the null terminator

    nameBuf[pos] = '\0';

 

    buf[count] = strdup((const char *)nameBuf);

 

    count++;

  }

  return count;

}

 

 

void switch_mode_light(int light, int state) {

  digitalWrite(lightPins[light], state);

}

 

void play_music() {

  Serial.println("Playing...");

  switch_mode_light(PLAYING_LIGHT, HIGH);

}

 

void pause_music() {

  Serial.println("Stopping...");

  switch_mode_light(PLAYING_LIGHT, LOW);

}

 

void skip_forward() {

  Serial.println("Skipping forward...");

  Serial.println(currentFileIndex);

  numBytesRead = 0;

}

 

void skip_backwards() {

  Serial.println("Skipping backwards...");

  Serial.println(howFarIn);

  numBytesRead = 0;

  if(howFarIn < 500){

    currentFileIndex -= 2;

  }else{

    currentFileIndex--;

  }

}

 

void set_volume(int v) {

  Serial.print("Seting volume to ");

  Serial.println(v);

  Mp3.volume(map(v, 0, 10, 0, 254));

}

 

void handleHook() {

  static unsigned long last_interrupt_time = 0;

  unsigned long interrupt_time = millis();

  if (interrupt_time - last_interrupt_time > 8) {

    playing = (digitalRead(3) == LOW);

    if(playing){

      play_music();

    }else{

      pause_music();

    }

 

  }

  last_interrupt_time = interrupt_time;

}

 

void performAction(int action) {

  switch(action){

    case 1:

      skip_forward();

      break;

    case 2:

      skip_backwards();

      break;

    case 3:

      control_mode = MODE_SET_VOLUME;

      switch_mode_light(SET_VOLUME_LIGHT, HIGH);

      break;

//    case 4:

//      control_mode = MODE_SEARCH;

//      switch_mode_light(SEARCH_LIGHT, HIGH);

//      break;

  }

}

 

void handleClick() {

  static unsigned long last_interrupt_time = 0;

  unsigned long interrupt_time = millis();

  if (interrupt_time - last_interrupt_time > 20) {

    ++numClicks;

  }

  last_interrupt_time = interrupt_time;

}

 

 

void setup() {

  Serial.begin(9600);

 

  pinMode(clickingFinishedPin, INPUT);

  digitalWrite(clickingFinishedPin, HIGH);

 

  attachInterrupt(0, handleClick, CHANGE);

  attachInterrupt(1, handleHook, CHANGE);

 

  pinMode(3, INPUT); // Interrupt pin 1

  playing = (digitalRead(3) == LOW);

 

 

 

  pinMode(10, OUTPUT);

 

  if (!card.init(SPI_HALF_SPEED, 4)) {

    Serial.println("initialization failed!");

    return;

  }

 

  if (!volume.init(card)) {

    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");

    return;

  }

 

  root.openRoot(volume);

 

  files = (char **)malloc(MAX_FILE_COUNT * sizeof(char *));

  numFiles = listMP3Files(&root, files);

  Serial.print("Found ");

  Serial.print(numFiles);

  Serial.println(" files:");

  for(int i = 0; i < numFiles; ++i){

    int nameLen = strlen(files[i]);

    Serial.println(files[i]);

  }

 

  Mp3.begin(MP3_CS, DCS, RST, DREQ);  // decoder cs, dcs, rst, dreq pin

  Mp3.volume(playbackVolume);         // default volume level is silent

}

 

void loop() {

  if(playing){

    if(numBytesRead != READ_BUFFER_SIZE) { // Change songs

      currentFileIndex++;

      if(currentFileIndex >= numFiles) currentFileIndex = 0;

 

      Serial.print("Opening file: ");

      Serial.println(files[currentFileIndex]);

      currentFile.close();

      if(currentFile.open(root, files[currentFileIndex], O_RDONLY) > 0){

        currentFile.seekSet(0);

        Serial.print("Playing file: ");

        Serial.println(files[currentFileIndex]);

        howFarIn = 0;

        numBytesRead = currentFile.read(bytes, READ_BUFFER_SIZE);

      }else{

        Serial.println("Error opening file!");

        currentFileIndex++;

      }

    }else{

      numBytesRead = currentFile.read(bytes, READ_BUFFER_SIZE);

      Mp3.play(bytes, numBytesRead);

      howFarIn++;

    }

  }

 

  unsigned long currTime = millis();

  if(currTime >= lastCheckTime + 10){

    int clickingState = digitalRead(clickingFinishedPin);

    if(!dialing && clickingState == LOW){

      dialing = true;

    }else if(dialing && clickingState == HIGH){

      numClicks /= 2;

      Serial.println(numClicks);

      if(control_mode == MODE_NORMAL){

        performAction(numClicks);

      }else if(control_mode == MODE_SET_VOLUME){

        set_volume(numClicks);

        control_mode = MODE_NORMAL;

        switch_mode_light(SET_VOLUME_LIGHT, LOW);

      }

      numClicks = 0;

      dialing = false;

    }

    lastCheckTime = currTime;

  }

}

 

Comments (0)

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