17-08-2015, 00:22
Witajcie mam problem nie działa mi sciszanie,podgłasnianie + poprzenia piosenka sketch przerobiłem na tyle ile uwazałem ale problem pozostał, proszę o pomoc.
Jak już całe uruchomię to zapodam wtedy poradnik
Kod:
#include <SPI.h>
#include <SD.h>
#include <EEPROM.h>
#include <VS1053.h>
#include <SoftwareSerial.h>// import the serial library
#define max_title_len 60
#define max_name_len 13
#define max_num_songs 40
#define read_buffer 256
#define mp3_vol 100 //range from 0(louder) to 100(really low)
#define volumeMemoryAddress max_num_songs * max_name_len
#define sd_cs 10
VS1053 myVS(2, 7, 4, 8);
//Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, -1 ,4);
int BluetoothData; // the data given from Computer
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 , NEXT , PREV};
state current_state = DIR_PLAY;
// set pin numbers:
const int buttonPinUp = A3; // the number of the pushbutton pin
const int buttonPinDown = A4; // the number of the pushbutton pin
const int ledPin = 9; // the number of the LED pin
int buttonStateUp = 0; // variable for reading the pushbutton status
int buttonStateDown = 0; // variable for reading the pushbutton status
/*control volume variables*/
byte mp3_volume = 0; //variable to read initial value of volume
//Interrupt part
volatile int state = LOW;
void setup()
{
// initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// declare the ledPin as an OUTPUT:
// pinMode(sensorPin, INPUT); // sets pin A5 as input
//volume
// initialize the pushbutton pin as an input:
pinMode(buttonPinUp, INPUT);
//volume
// initialize the pushbutton pin as an input:
pinMode(buttonPinDown, INPUT);
//interrupt
pinMode(ledPin, OUTPUT);
attachInterrupt(0, previous, FALLING );
attachInterrupt(1, next, FALLING );
attachInterrupt(4, play_pause, FALLING);
SPI.begin();
myVS.begin();
//fetch volume from EEPROM
mp3_volume = EEPROM.read(volumeMemoryAddress);
//set volume
myVS.setVolume(mp3_volume);
sd_card_setup();
sd_dir_setup();
while (num_songs==0) {
Serial.println("No songs on card");
delay(5000);
}
openSongFile(current_song);
//song_title_to_display();
song_title_to_cell_display();
}
void dir_play() {
if (sd_file) {
mp3_play();
}
else {
if (current_song < (num_songs - 1)) {
current_song++;
openSongFile(current_song);
//song_title_to_display();
song_title_to_cell_display();
myVS.startSong();
}
else {
current_state = PAUSED;
}
}
}
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);
myVS.playChunk(bytes, bytes_to_read);
// Serial.println("Playing song");
// 'bytes_to_read' is only smaller than 'read_buffer' when the song's over.
if (bytes_to_read < read_buffer) {
Serial.println("stoping song");
sd_file.close();
myVS.stopSong();
// if we've been in the MP3_PLAY state, then we want to pause the player.
if (current_state == MP3_PLAY) {
current_state == PAUSED;
}
}
}
void previous_song(){
Serial.println("Changing song ...");
if (current_song >0) {
sd_file.close();
myVS.stopSong();
current_song--;
Serial.print("Going to song - ");
Serial.println(current_song);
openSongFile(current_song);
song_title_to_cell_display();
myVS.startSong();
current_state=DIR_PLAY;
}
else {
current_state = DIR_PLAY;
}
}
void next_song(){
Serial.println("Changing song ...");
if (current_song < (num_songs - 1)) {
sd_file.close();
myVS.stopSong();
current_song++;
Serial.print("Going to song - ");
Serial.println(current_song);
openSongFile(current_song);
song_title_to_cell_display();
myVS.startSong();
current_state=DIR_PLAY;
}
else {
current_state = MP3_PLAY;
}
}
/*interrupt services*/
void play_pause()
{
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 > 300)
{
state = !state;
if (current_state == DIR_PLAY) {
current_state = PAUSED;
}else{
current_state=DIR_PLAY;
}
}
last_interrupt_time = interrupt_time;
}
void next()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
//Serial.print("next interrrupt");
// 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 == MP3_PLAY) {
current_state = NEXT;
}
}
last_interrupt_time = interrupt_time;
}
void previous(){
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 == MP3_PLAY) {
current_state = PREV;
}
}
last_interrupt_time = interrupt_time;
}
void change_volume(){
// read the state of the pushbutton value:
buttonStateUp = digitalRead(buttonPinUp);
buttonStateDown = digitalRead(buttonPinDown);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonStateUp == LOW && mp3_volume>1) {
mp3_volume-=1;
}
else if(buttonStateDown == LOW && mp3_volume<150){
mp3_volume+=1;
}
}
void bluetoothProcessing(){
unsigned long positionToSeek = sd_file.position();
if (Serial.available()){
BluetoothData=Serial.read();
//Serial.print("BluetoothData");
//Serial.println(BluetoothData);
if(BluetoothData=='1'){ // if number 1 pressed ....
digitalWrite(ledPin,1);
Serial.println("Pause music ");
play_pause();
}
if (BluetoothData=='2'){// if number 2 pressed ....
digitalWrite(ledPin,0);
Serial.println("Next ");
next();
}
if (BluetoothData=='3'){// if number 3 pressed ....
digitalWrite(ledPin,0);
Serial.println("Previous ");
previous();
}
if (BluetoothData=='4'){// if number 4 pressed ....
if(mp3_volume>=1){
digitalWrite(ledPin,0);
Serial.println("Increase Vol ");
mp3_volume-=1;
}
}
if (BluetoothData=='5'){// if number 5 pressed ....
if(mp3_volume<150){
digitalWrite(ledPin,0);
Serial.println("Decrease Vol ");
mp3_volume+=1;
}
}
if (BluetoothData=='6'){// if number 6 pressed ....
digitalWrite(ledPin,0);
Serial.println("Seeking ");
//if(positionToSeek + 300 < sd_file.size() )
positionToSeek = sd_file.size()/2 ;
sd_file.seek(positionToSeek);
}
}
//delay(100);// prepare for next data ...
}
void loop()
{
digitalWrite(ledPin, state);
//check for volume change
change_volume();
EEPROM.write(volumeMemoryAddress, mp3_volume);
myVS.setVolume(mp3_volume);
switch(current_state) {
case DIR_PLAY:
dir_play();
break;
case MP3_PLAY:
mp3_play();
break;
case PAUSED:
break;
case NEXT:
next_song();
break;
case PREV:
previous_song();
break;
}
bluetoothProcessing();
}
//Id3Tag
// this utility function reads id3v1 and id3v2 tags, if any are present, from
// mp3 audio files. if no tags are found, just use the title of the file. :-|
void get_title_from_id3tag () {
unsigned char id3[3]; // pointer to the first 3 characters to read in
// visit http://www.id3.org/id3v2.3.0 to learn all(!) about the id3v2 spec.
// move the file pointer to the beginning, and read the first 3 characters.
sd_file.seek(0);
sd_file.read(id3, 3);
// if these first 3 characters are 'ID3', then we have an id3v2 tag. if so,
// a 'TIT2' (for ver2.3) or 'TT2' (for ver2.2) frame holds the song title.
if (id3[0] == 'I' && id3[1] == 'D' && id3[2] == '3') {
unsigned char pb[4]; // pointer to the last 4 characters we read in
unsigned char c; // the next 1 character in the file to be read
// our first task is to find the length of the (whole) id3v2 tag. knowing
// this means that we can look for 'TIT2' or 'TT2' frames only within the
// tag's length, rather than the entire file (which can take a while).
// skip 3 bytes (that we don't use), then read in the last 4 bytes of the
// header, which contain the tag's length.
sd_file.read(pb, 3);
sd_file.read(pb, 4);
// to combine these 4 bytes together into the single value, we first have
// to shift each one over to get it into its correct 'digits' position. a
// quirk of the spec is that bit 7 (the msb) of each byte is set to 0.
unsigned long v2l = ((unsigned long) pb[0] << (7 * 3)) +
((unsigned long) pb[1] << (7 * 2)) +
((unsigned long) pb[2] << (7 * 1)) + pb[3];
// we just moved the file pointer 10 bytes into the file, so we reset it.
sd_file.seek(0);
while (1) {
// read in bytes of the file, one by one, so we can check for the tags.
sd_file.read(&c, 1);
// keep shifting over previously-read bytes as we read in each new one.
// that way we keep testing if we've found a 'TIT2' or 'TT2' frame yet.
pb[0] = pb[1];
pb[1] = pb[2];
pb[2] = pb[3];
pb[3] = c;
if (pb[0] == 'T' && pb[1] == 'I' && pb[2] == 'T' && pb[3] == '2') {
// found an id3v2.3 frame! the title's length is in the next 4 bytes.
sd_file.read(pb, 4);
// only the last of these bytes is likely needed, as it can represent
// titles up to 255 characters. but to combine these 4 bytes together
// into the single value, we first have to shift each one over to get
// it into its correct 'digits' position.
unsigned long tl = ((unsigned long) pb[0] << (8 * 3)) +
((unsigned long) pb[1] << (8 * 2)) +
((unsigned long) pb[2] << (8 * 1)) + pb[3];
tl--;
// skip 2 bytes (we don't use), then read in 1 byte of text encoding.
sd_file.read(pb, 2);
sd_file.read(&c, 1);
// if c=1, the title is in unicode, which uses 2 bytes per character.
// skip the next 2 bytes (the byte order mark) and decrement tl by 2.
if (c) {
sd_file.read(pb, 2);
tl -= 2;
}
// remember that titles are limited to only max_title_len bytes long.
if (tl > max_title_len) tl = max_title_len;
// read in tl bytes of the title itself. add an 'end-of-string' byte.
sd_file.read(title, tl);
title[tl] = '\0';
break;
}
else
if (pb[1] == 'T' && pb[2] == 'T' && pb[3] == '2') {
// found an id3v2.2 frame! the title's length is in the next 3 bytes,
// but we read in 4 then ignore the last, which is the text encoding.
sd_file.read(pb, 4);
// shift each byte over to get it into its correct 'digits' position.
unsigned long tl = ((unsigned long) pb[0] << (8 * 2)) +
((unsigned long) pb[1] << (8 * 1)) + pb[2];
tl--;
// remember that titles are limited to only max_title_len bytes long.
if (tl > max_title_len) tl = max_title_len;
// there's no text encoding, so read in tl bytes of the title itself.
sd_file.read(title, tl);
title[tl] = '\0';
break;
}
else
if (sd_file.position() == v2l) {
// we reached the end of the id3v2 tag. use the file name as a title.
strncpy(title, fn, max_name_len);
break;
}
}
}
else {
// there is no id3 tag or the id3 version is not supported.
title[0]='\0';
}
}
//UTILITIES
/*
* example sketch to play audio file(s) in a directory, using the VS1053 library
* for playback and the arduino sd library to read files from a microsd card.
* pins are setup to work well for Arduino Micro.
*
* originally based on frank zhao's player: http://frank.circleofcurrent.com/
* utilities adapted from previous versions of the functions by matthew seal.
*
* (c) 2011, 2012 david sirkin sirkin@cdr.stanford.edu
* akil srinivasan akils@stanford.edu
*/
// first step, declare the variables used later to represent microsd objects.
File sd_root; // the sd partition's root ('/') directory
// check that the microsd card is present, can be initialized and has a valid
// root volume. 'sd_root' is a pointer to the card's root volume object.
void sd_card_setup() {
pinMode(sd_cs, OUTPUT); //set SS pin as output.
while (!SD.begin(sd_cs)) {
Serial.println("Card failed!");
}
sd_root = SD.open("/");
while (!sd_root) {
Serial.println("Couldn't mount root.");
delay(2000);
return;
}
}
// for each song file in the current directory, store its file name in eeprom
// for later retrieval. this saves on using program memory for the same task,
// which is helpful as you add more functionality to the program.
// it also lets users change songs on the microsd card without having to hard
// code file names into the program. ask an instructor if you want to use sub
// directories also.
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;
// only store current (not deleted) file entries, and ignore the . and ..
// directory entries. also ignore any sub-directories.
if (p.name()[0] == '~' || p.name()[0] == '.' || p.isDirectory()) {
continue;
}
// to find the position of the '.' that precedes the file name extension,
// we have to search through the file name (stored as an array of chars).
// fat16 prefers 8.3 type file names, and the sd library will shorten any
// names longer than that. so if we have an mp3 or wav file, the '.' will
// appear no later than position 8 ('max_name_len'-5) of the file name.
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')) {
// store each character of the file name (including the terminate-array
// character '\0' at position 12) into a byte in the eeprom.
for (char i = 0; i < max_name_len; i++) {
EEPROM.write(num_songs * max_name_len + i, p.name()[i]);
}
num_songs++;
}
}
}
// given the numerical index of a particular song to play, go to its location
// in eeprom, retrieve its file name and set the global variable 'fn' to it.
void getSongFilename(int songNum) {
for (char i = 0; i < max_name_len; i++) {
fn[i] = EEPROM.read(songNum * max_name_len + i);
}
}
void openSongFile(int songNum) {
// first, find the file name (that's stored in eeprom) of the current song.
getSongFilename(songNum);
// then open the file using the name we just found (stored in 'fn' global).
sd_file = SD.open(fn, FILE_READ);
}
void song_title_to_display() {
get_title_from_id3tag();
if (title[0]=='\0') {
// display.println("File Name:\n");
// display.print(fn);
} else {
//display.println("Song Title:\n");
//display.print(title);
}
//display.display();
delay(2000);
}
void song_title_to_cell_display() {
get_title_from_id3tag();
if (title[0]=='\0') {
Serial.print("File Name:\n");
Serial.println(fn);
} else {
Serial.print("Song Title:\n");
Serial.println(title);
}
//delay(2000);
}
Jak już całe uruchomię to zapodam wtedy poradnik