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

Nathan Hall-Snyder - Final Project Source Code

Page history last edited by Nathan Hall-Snyder 13 years, 10 months ago

/*

  *   FILE URL: song11_final.pde
 * Nathan Hall-Snyder
 * Code for use with the Strobe mp3 Player, built for the first offering of EE 47 - Press Play: Interactive Device Design.
 * This code does the following:
 * Controls a Parallel Display
 * Plays Mp3s
 * Lists songs on the above screen
 * Accepts input from two rotary encoders, one pot, and three buttons
 * Controls the led strobing action

/* import the avr's power library for the clock_prescale_set macro. */

#include <avr/power.h>

/* import the full fatfs wrapper & mp3 library functions & defines. */

#include <diskio.h>
#include <fatfs.h>
#include <ff.h>
#include <ffconf.h>
#include <integer.h>
#include <LiquidCrystal.h>
#include <string.h>

//Definitions for use with the file listing program
#define maxLength 30
#define maxFiles 32
#define maxFileLength 13

//Includes for mp3 playing
#include <mp3.h>
#include <mp3conf.h>

//Chip select Pin Definitions for the Mp3 player and SD Card
#define mp3_cs      0             // 'command chip select' to cs pin
#define mmc_cs      14            // 'chip select' to microsd cs pin

//State machine things
#define PLAY 0song11_final.pde song11_final.pde song11_final.pde song11_final.pde song11_final.pde
#define PAUSE 1
#define SONGLIST 2

//MP3 Player Pin Definitions
#define dcs         13            // 'data chip select' to bsync pin
#define dreq        12            // 'data request line' to dreq pin
#define rst         11            // 'reset' to decoder's reset pin

//SD Card
#define read_buffer 512           // size of the microsd read buffer

//Initialize the LCD
LiquidCrystal lcd(15, 17, 18, 19, 20, 21);

//Define the Encoder Pins
#define encoder0PinA  9
#define encoder0PinB  7
#define encoder1PinA  10
#define encoder1PinB  8

// Define Potentiometer Pins
#define potPin  5

// Define Encoder Buttons
#define button0pin 6
#define button1pin 5
#define button2pin 22

//Globals for the encoder positions
volatile signed int encoder0Pos = 200;
volatile signed int encoder0Last = 200;
volatile unsigned int encoder1Pos = 30;
volatile unsigned int encoder1Last = 0;

//Global for checking volume
volatile unsigned int checkVolume = 0;

//Global for volume control
volatile unsigned int curPot = 0;

//Another Global for volume control
volatile unsigned int mp3_vol = 200;

//The state machine state variable
volatile unsigned int state = 2;

//Defines the LED pin
int ledPin = 4;

//Currently playing song
char *nowPlaying[maxFileLength];

//Global for the current song control
volatile unsigned int currentSong = 0;

//Global for the amount of files on the SD card
unsigned int files_found = 0;

//Counter for the strobe light
volatile int ticker = 0;

//Declare the char array
char songs[maxFiles][maxFileLength];

/*
 * initialize the processor speed, the encoders, setup the fatfs sd card (or, mms)
 * filesystem, setup mp3 playback and register the pins used (device
 * specific configuration)
 */
void setup() {
 
  //Setup delay to keep the arduino from crashing
  delay(100);
 
 //Serial.begin(115200);    
 
  //Set the clock speed
  // the avr atmega32u4 processor is only rated to 8mhz (rather than
  // 16mhz) when powered at 3.3v (rather than 5v).
  clock_prescale_set(clock_div_2); // fosc 8mhz as teensy is at 3.3V
  delay(200);
 
  //Start up the LCD
  lcd.begin(16, 2);

  //Nifty Startup Screen
  startupScreen();
 
  //Set up the LED
  pinMode(ledPin,OUTPUT);
 
  //Set up Encoder 0
  pinMode(encoder0PinA, INPUT);
  digitalWrite(encoder0PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder0PinB, INPUT);
  digitalWrite(encoder0PinB, HIGH);       // turn on pullup resistor
 
  //Set up Encoder 1
  pinMode(encoder1PinA, INPUT);
  digitalWrite(encoder1PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder1PinB, INPUT);
  digitalWrite(encoder1PinB, HIGH);       // turn on pullup resistor
 
  //Set up Buttons
  digitalWrite(button0pin, HIGH);
  digitalWrite(button1pin, HIGH);
  digitalWrite(button2pin, HIGH);
 
  //Attach interrupt pin
  attachInterrupt(0, largebuttonPress, CHANGE);  // encoder pin on interrupt 0 - pin 5
  attachInterrupt(1, buttonPress, FALLING);  // encoder pin on interrupt 1 - pin 6
  attachInterrupt(2, doEncoder0, CHANGE);  // encoder pin on interrupt 2 - pin 7
  attachInterrupt(3, doEncoder1, CHANGE);  // encoder pin on interrupt 3 - pin 8
 
  //Starts up the MP3 Player
  Mp3.begin(mp3_cs,dcs,rst,dreq);  // decoder cs, dcs, rst, dreq pin
  Mp3.volume(mp3_vol);             // default volume level is silent
 
  delay(200);
 
  //Starts up the SD Card
  FatFs.begin(mmc_cs);             // register microsd card's cs pin
 
  delay(100);
 
  // while only rated to 8mhz, the processor seems to work at 16MHz,
  // which is required to playback full-resolution 44.1kHz wav files

  clock_prescale_set(clock_div_1); // fosc 16mhz only for full waves
 
  //Initializes the state machine
  state = SONGLIST;
}
// This method reads the contents of the SD card, printing what it finds into an array
void dir_list (void){
  FILINFO file_info;            // information on file size and type
  files_found = 0;
  FatFs.opendir();
 
  do {
    FatFs.readdir(&file_info);
   
    if ((file_info.fattrib & AM_DIR) != AM_DIR) {
     
      //Adds the song name top the thing
      strcpy( songs[files_found] , file_info.fname);
      files_found++;
      delay(20);
    }
  }
  while (file_info.fname[0] != 0);
}

//The interrupt function for the left encoder button
void buttonPress(){
    
  if(state == PLAY){
    state = SONGLIST;
    delay(100);
   
  } else {
    //Serial.println("changed state to play");
    state = PLAY;
    delay(100);
 
  }
 }
 
 //The interrupt function called for the large button
 void largebuttonPress(){
   //Serial.println("large button pressed");
   delay(100);
  
   if(digitalRead(button1pin) == HIGH && state == PLAY){
     //Serial.println("pausing from the interrupt");
     state = PAUSE;
   }
  
   if(state == PAUSE && digitalRead(button1pin) == LOW) state = PLAY;
  
   if(state == SONGLIST && digitalRead(button1pin) == LOW){
     state = PLAY;
   }
  
 }
 
//Plays a specific song in a directory
void dir_play (char song[]) {

    //////Serial.println(song);
    char * fn = song;              // pointer to the filename
    char s = strlen(song);         // length of the filename

    if ((fn[s-3] == 'M' && fn[s-2] == 'P' && fn[s-1] == '3') ||
        (fn[s-3] == 'W' && fn[s-2] == 'A' && fn[s-1] == 'V')) {
     
      if (FatFs.open(song, FA_READ) == FR_OK) {
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(">>");
        lcd.println(song);
       
        mp3_play();
      }
    }
  //}
}

FILINFO fnfo; // information on file size & type, updated by readdir

//The interrupt call called by the encoder interrupt.
//Reading the encoders is really finicky. It takes a lot of debouncing and output filtering to get them to work properly.
void doEncoder0() {
 
  if(state == PLAY || state == PAUSE){
    state = SONGLIST;
  }
 
  if (digitalRead(encoder0PinA) == HIGH) {   // found a low-to-high on channel A
    if (digitalRead(encoder0PinB) == LOW) {  // check channel B to see which way
                                             // encoder is turning
      encoder0Pos = encoder0Pos - 1;         // CCW
    }
    else {
      encoder0Pos = encoder0Pos + 1;         // CW
    }
  }
  else                                        // found a high-to-low on channel A
  {
    if (digitalRead(encoder0PinB) == LOW) {   // check channel B to see which way
                                              // encoder is turning 
      encoder0Pos = encoder0Pos + 1;          // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }

  }
}
//The interrupt call called by the encoder interrupt.
//Reading the encoders is really finicky. It takes a lot of debouncing and output filtering to get them to work properly.
//The second encoder either wasn't working right or was non-functional, but it would only increase, so
//this small bit of code lets you change the frequency of the flashing or turn off the flashing altogether
void doEncoder1() {
  delay(50);
  encoder1Pos += 2;
  if(encoder1Pos > 100) encoder1Pos = 0;
 
}

//The main loop, proceses the state machine
void loop() {

  switch( state )
  {
    case PLAY: playmp3();
    case PAUSE: pause();
    case SONGLIST: listsongs();
  }
 
}

//The menu-type loop, which allows the user to select what song they would like.
//I tried hard to implement a reasonable-seeming scrolling system on a two line
//display, with a moving arrow and associated scrolling
void listsongs(){
  dir_list();
 
  int cursorPos = 0;
 
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(">");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(1, 0);
  lcd.print(songs[currentSong]);
  lcd.setCursor(1, 1);
  lcd.print(songs[ currentSong + 1 ]);
 
  encoder0Last = encoder0Pos;
 
  while(state == SONGLIST){
   
    if(currentSong < 10){
      lcd.setCursor(15,1);
      lcd.print(currentSong);
      lcd.setCursor(14,1);
      lcd.print(" ");
    } else {
      lcd.setCursor(14,1);
      lcd.print(currentSong);
    }
     
    if(encoder0Pos != encoder0Last) delay(100);
   
    //Encoder A turned right
    if(encoder0Pos > encoder0Last){
     
      encoder0Last = encoder0Pos;
        
      if(currentSong < (files_found-1)){
        currentSong ++;
       
        if(cursorPos == 1){
          lcd.setCursor(1, 1);
          lcd.print(songs[currentSong]);
          lcd.setCursor(1, 0);
          lcd.print(songs[ currentSong - 1 ]);
        } else {
          lcd.setCursor(0, 0);
          lcd.print(" ");
          lcd.setCursor(0, 1);
          lcd.print(">");
          cursorPos = 1;
        }
      }
    }
   
    //Encoder A turned left
    if(encoder0Pos <  encoder0Last){
     
      encoder0Last = encoder0Pos;
       
        if(currentSong > 0){
          currentSong--;
       
        if(cursorPos == 0){
          lcd.setCursor(1, 0);
          lcd.print(songs[currentSong]);
          lcd.setCursor(1, 1);
          //TODO
          if(currentSong == (files_found-2)) lcd.print("          ");
          else lcd.print(songs[ currentSong + 1 ]);
        } else {
          lcd.setCursor(0, 0);
          lcd.print(">");
          lcd.setCursor(0, 1);
          lcd.print(" ");
          cursorPos = 0;
        }
        }
    }
  }
 
  lcd.clear();
  lcd.setCursor(0,0);
 
}

//The pause function for the state machine
void pause(){
  while(state == PAUSE){
    delay(20);
  }
}

//State machine function, plays an Mp3
void playmp3(void){
 
  dir_play(songs[currentSong]);
 
}

void startupScreen(void){
   lcd.clear();
  lcd.print("MP3");
    delay(100);
    lcd.clear();
  lcd.print("MP3.");
    delay(100);
    lcd.clear();
  lcd.print("MP3..");
    delay(100);
    lcd.clear();
  lcd.print("MP3...");
    delay(100);
    lcd.clear();
  lcd.print("MP3...ENGAGE!");
    delay(300);
    lcd.clear();
}

//Actually does the byte-by-byte copying of the data from the SD card, sending it to the mp3 player.
//Also, this loop is used by a variety of functions of the strobe mp3. In addition to playing mp3s, it:
// - Checks to see if the music has been paused
// - takes care of the strobing action
// - Controls the volume based on the pot input

void mp3_play (void) {
  unsigned char bytes[read_buffer]; // buffer to send to the decoder
  unsigned int bytes_read;          // number of bytes read from fat
  curPot = analogRead(potPin);
 
  do {
   
    FatFs.read(bytes, read_buffer, &bytes_read);
    Mp3.play(bytes, read_buffer);
   
   if(state == PAUSE) {
      while (1){
        lcd.setCursor(4,1);
        lcd.print("Paused");
        delay(20);
        if(state != PAUSE){
          lcd.setCursor(4,1);
          lcd.print("      ");
          break;
        }
      }
    }
     
    if(state == SONGLIST) break;
   
    ticker++;
  
    if(encoder1Pos < 75 && encoder1Pos > 2) {
   
      if(ticker >= encoder1Pos/4) digitalWrite(ledPin,HIGH);
     
      if(ticker >= (encoder1Pos/4)+2){
        digitalWrite(ledPin,LOW);
        lcd.setCursor(10,1);
        lcd.println(encoder1Pos);
        ticker = 0;
      }
     
    } else {
      lcd.setCursor(10,1);
      lcd.println(encoder1Pos);
      digitalWrite(ledPin,HIGH);
    }
   
    if(analogRead(potPin) != curPot){
      mp3_vol = (analogRead(potPin))/4;
      lcd.setCursor(0,1);
      lcd.print(mp3_vol);
      Mp3.volume(mp3_vol);
      curPot = analogRead(potPin);
    }
  }
  while (bytes_read == read_buffer);
  currentSong++;
}

/*
 * Nathan Hall-Snyder
 * Code for use with the Strobe mp3 Player, built for the first offering of EE 47 - Press Play: Interactive Device Design.
 * This code does the following:
 * Controls a Parallel Display
 * Plays Mp3s
 * Lists songs on the above screen
 * Accepts input from two rotary encoders, one pot, and three buttons
 * Controls the led strobing action

/* import the avr's power library for the clock_prescale_set macro. */

#include <avr/power.h>

/* import the full fatfs wrapper & mp3 library functions & defines. */

#include <diskio.h>
#include <fatfs.h>
#include <ff.h>
#include <ffconf.h>
#include <integer.h>
#include <LiquidCrystal.h>
#include <string.h>

//Definitions for use with the file listing program
#define maxLength 30
#define maxFiles 32
#define maxFileLength 13

//Includes for mp3 playing
#include <mp3.h>
#include <mp3conf.h>

//Chip select Pin Definitions for the Mp3 player and SD Card
#define mp3_cs      0             // 'command chip select' to cs pin
#define mmc_cs      14            // 'chip select' to microsd cs pin

//State machine things
#define PLAY 0
#define PAUSE 1
#define SONGLIST 2

//MP3 Player Pin Definitions
#define dcs         13            // 'data chip select' to bsync pin
#define dreq        12            // 'data request line' to dreq pin
#define rst         11            // 'reset' to decoder's reset pin

//SD Card
#define read_buffer 512           // size of the microsd read buffer

//Initialize the LCD
LiquidCrystal lcd(15, 17, 18, 19, 20, 21);

//Define the Encoder Pins
#define encoder0PinA  9
#define encoder0PinB  7
#define encoder1PinA  10
#define encoder1PinB  8

// Define Potentiometer Pins
#define potPin  5

// Define Encoder Buttons
#define button0pin 6
#define button1pin 5
#define button2pin 22

//Globals for the encoder positions
volatile signed int encoder0Pos = 200;
volatile signed int encoder0Last = 200;
volatile unsigned int encoder1Pos = 30;
volatile unsigned int encoder1Last = 0;

//Global for checking volume
volatile unsigned int checkVolume = 0;

//Global for volume control
volatile unsigned int curPot = 0;

//Another Global for volume control
volatile unsigned int mp3_vol = 200;

//The state machine state variable
volatile unsigned int state = 2;

//Defines the LED pin
int ledPin = 4;

//Currently playing song
char *nowPlaying[maxFileLength];

//Global for the current song control
volatile unsigned int currentSong = 0;

//Global for the amount of files on the SD card
unsigned int files_found = 0;

//Counter for the strobe light
volatile int ticker = 0;

//Declare the char array
char songs[maxFiles][maxFileLength];

/*
 * initialize the processor speed, the encoders, setup the fatfs sd card (or, mms)
 * filesystem, setup mp3 playback and register the pins used (device
 * specific configuration)
 */
void setup() {
 
  //Setup delay to keep the arduino from crashing
  delay(100);
 
 //Serial.begin(115200);     
 
  //Set the clock speed
  // the avr atmega32u4 processor is only rated to 8mhz (rather than
  // 16mhz) when powered at 3.3v (rather than 5v).
  clock_prescale_set(clock_div_2); // fosc 8mhz as teensy is at 3.3V
  delay(200);
 
  //Start up the LCD
  lcd.begin(16, 2);

  //Nifty Startup Screen
  startupScreen();
 
  //Set up the LED
  pinMode(ledPin,OUTPUT);
 
  //Set up Encoder 0
  pinMode(encoder0PinA, INPUT);
  digitalWrite(encoder0PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder0PinB, INPUT);
  digitalWrite(encoder0PinB, HIGH);       // turn on pullup resistor
 
  //Set up Encoder 1
  pinMode(encoder1PinA, INPUT);
  digitalWrite(encoder1PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder1PinB, INPUT);
  digitalWrite(encoder1PinB, HIGH);       // turn on pullup resistor
 
  //Set up Buttons
  digitalWrite(button0pin, HIGH);
  digitalWrite(button1pin, HIGH);
  digitalWrite(button2pin, HIGH);
 
  //Attach interrupt pin
  attachInterrupt(0, largebuttonPress, CHANGE);  // encoder pin on interrupt 0 - pin 5
  attachInterrupt(1, buttonPress, FALLING);  // encoder pin on interrupt 1 - pin 6
  attachInterrupt(2, doEncoder0, CHANGE);  // encoder pin on interrupt 2 - pin 7
  attachInterrupt(3, doEncoder1, CHANGE);  // encoder pin on interrupt 3 - pin 8
 
  //Starts up the MP3 Player
  Mp3.begin(mp3_cs,dcs,rst,dreq);  // decoder cs, dcs, rst, dreq pin
  Mp3.volume(mp3_vol);             // default volume level is silent
 
  delay(200);
 
  //Starts up the SD Card
  FatFs.begin(mmc_cs);             // register microsd card's cs pin
 
  delay(100);
 
  // while only rated to 8mhz, the processor seems to work at 16MHz,
  // which is required to playback full-resolution 44.1kHz wav files

  clock_prescale_set(clock_div_1); // fosc 16mhz only for full waves
 
  //Initializes the state machine
  state = SONGLIST;
}
// This method reads the contents of the SD card, printing what it finds into an array
void dir_list (void){
  FILINFO file_info;            // information on file size and type
  files_found = 0;
  FatFs.opendir();
 
  do {
    FatFs.readdir(&file_info);
    
    if ((file_info.fattrib & AM_DIR) != AM_DIR) {
      
      //Adds the song name top the thing
      strcpy( songs[files_found] , file_info.fname);
      files_found++;
      delay(20);
    }
  }
  while (file_info.fname[0] != 0);
}

//The interrupt function for the left encoder button
void buttonPress(){
     
  if(state == PLAY){
    state = SONGLIST;
    delay(100);
    
  } else {
    //Serial.println("changed state to play");
    state = PLAY;
    delay(100);
 
  }
 }
 
 //The interrupt function called for the large button
 void largebuttonPress(){
   //Serial.println("large button pressed");
   delay(100);
   
   if(digitalRead(button1pin) == HIGH && state == PLAY){
     //Serial.println("pausing from the interrupt");
     state = PAUSE;
   }
   
   if(state == PAUSE && digitalRead(button1pin) == LOW) state = PLAY;
   
   if(state == SONGLIST && digitalRead(button1pin) == LOW){
     state = PLAY;
   }
   
 }
 
//Plays a specific song in a directory
void dir_play (char song[]) {

    //////Serial.println(song);
    char * fn = song;              // pointer to the filename
    char s = strlen(song);         // length of the filename

    if ((fn[s-3] == 'M' && fn[s-2] == 'P' && fn[s-1] == '3') ||
        (fn[s-3] == 'W' && fn[s-2] == 'A' && fn[s-1] == 'V')) {
      
      if (FatFs.open(song, FA_READ) == FR_OK) {
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(">>");
        lcd.println(song);
        
        mp3_play();
      }
    }
  //}
}

FILINFO fnfo; // information on file size & type, updated by readdir

//The interrupt call called by the encoder interrupt.
//Reading the encoders is really finicky. It takes a lot of debouncing and output filtering to get them to work properly.
void doEncoder0() {
 
  if(state == PLAY || state == PAUSE){
    state = SONGLIST;
  }
 
  if (digitalRead(encoder0PinA) == HIGH) {   // found a low-to-high on channel A
    if (digitalRead(encoder0PinB) == LOW) {  // check channel B to see which way
                                             // encoder is turning
      encoder0Pos = encoder0Pos - 1;         // CCW
    }
    else {
      encoder0Pos = encoder0Pos + 1;         // CW
    }
  }
  else                                        // found a high-to-low on channel A
  {
    if (digitalRead(encoder0PinB) == LOW) {   // check channel B to see which way
                                              // encoder is turning  
      encoder0Pos = encoder0Pos + 1;          // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }

  }
}
//The interrupt call called by the encoder interrupt.
//Reading the encoders is really finicky. It takes a lot of debouncing and output filtering to get them to work properly.
//The second encoder either wasn't working right or was non-functional, but it would only increase, so
//this small bit of code lets you change the frequency of the flashing or turn off the flashing altogether
void doEncoder1() {
  delay(50);
  encoder1Pos += 2;
  if(encoder1Pos > 100) encoder1Pos = 0;
 
}

//The main loop, proceses the state machine
void loop() {

  switch( state )
  {
    case PLAY: playmp3();
    case PAUSE: pause();
    case SONGLIST: listsongs();
  }
 
}

//The menu-type loop, which allows the user to select what song they would like.
//I tried hard to implement a reasonable-seeming scrolling system on a two line
//display, with a moving arrow and associated scrolling
void listsongs(){
  dir_list();
 
  int cursorPos = 0;
 
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(">");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(1, 0);
  lcd.print(songs[currentSong]);
  lcd.setCursor(1, 1);
  lcd.print(songs[ currentSong + 1 ]);
 
  encoder0Last = encoder0Pos;
 
  while(state == SONGLIST){
    
    if(currentSong < 10){
      lcd.setCursor(15,1);
      lcd.print(currentSong);
      lcd.setCursor(14,1);
      lcd.print(" ");
    } else {
      lcd.setCursor(14,1);
      lcd.print(currentSong);
    }
      
    if(encoder0Pos != encoder0Last) delay(100);
    
    //Encoder A turned right
    if(encoder0Pos > encoder0Last){
      
      encoder0Last = encoder0Pos;
         
      if(currentSong < (files_found-1)){
        currentSong ++;
        
        if(cursorPos == 1){
          lcd.setCursor(1, 1);
          lcd.print(songs[currentSong]);
          lcd.setCursor(1, 0);
          lcd.print(songs[ currentSong - 1 ]);
        } else {
          lcd.setCursor(0, 0);
          lcd.print(" ");
          lcd.setCursor(0, 1);
          lcd.print(">");
          cursorPos = 1;
        }
      }
    }
    
    //Encoder A turned left
    if(encoder0Pos <  encoder0Last){
      
      encoder0Last = encoder0Pos;
        
        if(currentSong > 0){
          currentSong--;
        
        if(cursorPos == 0){
          lcd.setCursor(1, 0);
          lcd.print(songs[currentSong]);
          lcd.setCursor(1, 1);
          //TODO
          if(currentSong == (files_found-2)) lcd.print("          ");
          else lcd.print(songs[ currentSong + 1 ]);
        } else {
          lcd.setCursor(0, 0);
          lcd.print(">");
          lcd.setCursor(0, 1);
          lcd.print(" ");
          cursorPos = 0;
        }
        }
    }
  }
 
  lcd.clear();
  lcd.setCursor(0,0);
 
}

//The pause function for the state machine
void pause(){
  while(state == PAUSE){
    delay(20);
  }
}

//State machine function, plays an Mp3
void playmp3(void){
 
  dir_play(songs[currentSong]);
 
}

void startupScreen(void){
   lcd.clear();
  lcd.print("MP3");
    delay(100);
    lcd.clear();
  lcd.print("MP3.");
    delay(100);
    lcd.clear();
  lcd.print("MP3..");
    delay(100);
    lcd.clear();
  lcd.print("MP3...");
    delay(100);
    lcd.clear();
  lcd.print("MP3...ENGAGE!");
    delay(300);
    lcd.clear();
}

//Actually does the byte-by-byte copying of the data from the SD card, sending it to the mp3 player.
//Also, this loop is used by a variety of functions of the strobe mp3. In addition to playing mp3s, it:
// - Checks to see if the music has been paused
// - takes care of the strobing action
// - Controls the volume based on the pot input

void mp3_play (void) {
  unsigned char bytes[read_buffer]; // buffer to send to the decoder
  unsigned int bytes_read;          // number of bytes read from fat
  curPot = analogRead(potPin);
 
  do {
    
    FatFs.read(bytes, read_buffer, &bytes_read);
    Mp3.play(bytes, read_buffer);
    
   if(state == PAUSE) {
      while (1){
        lcd.setCursor(4,1);
        lcd.print("Paused");
        delay(20);
        if(state != PAUSE){
          lcd.setCursor(4,1);
          lcd.print("      ");
          break;
        }
      }
    }
      
    if(state == SONGLIST) break;
    
    ticker++;
   
    if(encoder1Pos < 75 && encoder1Pos > 2) {
    
      if(ticker >= encoder1Pos/4) digitalWrite(ledPin,HIGH);
      
      if(ticker >= (encoder1Pos/4)+2){
        digitalWrite(ledPin,LOW);
        lcd.setCursor(10,1);
        lcd.println(encoder1Pos);
        ticker = 0;
      }
      
    } else {
      lcd.setCursor(10,1);
      lcd.println(encoder1Pos);
      digitalWrite(ledPin,HIGH);
    }
    
    if(analogRead(potPin) != curPot){
      mp3_vol = (analogRead(potPin))/4;
      lcd.setCursor(0,1);
      lcd.print(mp3_vol);
      Mp3.volume(mp3_vol);
      curPot = analogRead(potPin);
    }
  }
  while (bytes_read == read_buffer);
  currentSong++;
}

Comments (0)

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