Wednesday, May 13, 2015

Audino - Arduino MP3-Player (18) - PC-Software

Der Audino kann nun verwendet werden. Dazu werden auf der SD-Karte 10 Ordner mit den Namen 0, 1, 2, 3, 4, 5, 6, 7, 8 und 9 angelegt. In den Ordnern 1 bis 9 können nun MP3-Dateien kopiert werden. Die Dateinamen werden ebenfalls durchnummeriert (1.mp3, 2.mp3, 3.mp3, 4.mp3, ...). Die MP3-Dateien sollten dabei im Mono-Format vorliegen, da nur ein Kanal verwendet wird.

Um das Kopieren zu erleichtern, habe ich eine PC-Software erstellt, mit der die Abspiellisten geplant und erzeugt werden können.

Über "Select SD card" wird der Speicherort ausgewählt. dies sollte die SD-Karte sein. Wurden hier schon mit der PC-Software MP3-Tracks kopiert, so werden die gemachten Einträge ausgelesen, sodass diese bearbeitet werden können. Über "Copy to SD card" werden die MP3-Tracks auf die SD-Karte kopiert und umbenannt. Die MP3-Tracks sollten bereits im Mono-Format vorliegen. Mit "Reset" werden alle Einträge gelöscht.


In der Übersicht werden die 9 Knöpfe angezeigt. In den eckigen Klammern steht die Anzahl der Tracks gefolgt von der Spieldauer. Unten links steht die Gesamtanzahl der Tracks und die Gesamtspieldauer. Drückt man auf einen der 9 Knöpfe, kommt man in die Ansicht der hinzugefügten MP3-Tracks. Hier können weitere Tracks hinzugefügt oder wieder rausgelöscht werden.


Bei Interesse kann ich die PC-Software gerne zur Verfügung stellen.

Damit wäre das Projekt "Audino" nun endgültig abgeschlossen


Weitere Blogeinträge

  1. Auswahl der Komponenten
  2. Das Entwicklungsbrett
  3. Das erste Einschalten
  4. Die Entwicklungsumgebung
  5. Knöpfe (digital)
  6. Mehrere Knöpfe (digital)
  7. Mehrere Knöpfe (analog)
  8. Potentiometer
  9. Das MP3 Shield
  10. Auswahl der Komponenten 2
  11. Auswahl der Komponenten (Zusammenfassung) 
  12. Punkt-Streifenrasterplatine und Knöpfe
  13. Punkt-Streifenrasterplatine und weitere Komponenten
  14. Das Gehäuse
  15. Sketch 1 (setup-Methode)
  16. Sketch 2 (loop-Methode)
  17. Sketch 3 (Der komplette Code)
  18. PC-Software

Saturday, April 4, 2015

Audino - Arduino MP3-Player (17) - Sketch 3 (Der komplette Code)

Nachdem die letzten beiden Beiträge den Sketch behandelt und ausführlich erklärt haben, ist hier nochmal der ganze Quellcode dargestellt, der auf das Arduino-Board gespielt wird.
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>
 
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)
#define DREQ          3      // VS1053 Data request, ideally an Interrupt pin
#define CARDCS        4      // Card chip select pin
Adafruit_VS1053_FilePlayer musicPlayer =
    Adafruit_VS1053_FilePlayer(SHIELD_CSSHIELD_DCSDREQCARDCS);
 
// VS1053 play speed parameter
#define para_playSpeed 0x1E04
 
// constants won't change
 
// the number of the pin that is used for the pushbuttons
const int buttonsPin = A0;
 
// the pin of the potentiometer that is used to control the volume
const int volumePin = A1;
 
// wait before next click is recognized
const int buttonPressedDelay = 1000;
 
 
// variables will change
 
byte currentFolder = 1;
unsigned int currentFile = 0;
unsigned int numberOfFiles[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
// the current volume level, set to min at start
byte volumeState = 254;
 
// last button that was pressed
byte lastPressedButton = 0;
// is the last pressed button released
boolean released = true;
// remember if the back button was pressed last time
byte lastReleasedButton = 0;
// the time at the back button was pressed last time
long lastBackButtonTime = 0;
 
char currentTrackFileName[] = "/0/current.txt";
 
// the setup routine runs once when you turn the device on or you press reset
void setup()
{
    // disable LED L
    pinMode(13, OUTPUT);
    digitalWrite(13, LOW);    
 
    // initialize serial communication at 9600 bits per second
    //Serial.begin(9600);
 
    // initialise the music player
    if (!musicPlayer.begin())
    {
        //Serial.println("VS1053 not found");
        while (1);  // don't do anything more
    }
 
    // initialise the SD card
    SD.begin(CARDCS);
 
 
    // If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background
    // audio playing
    musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int
 
    musicPlayer.sineTest(0x44, 100);    // Make a tone to indicate VS1053 is working 
 
    // read the number of tracks in each folder
    for (byte i = 0; i < 10; i++)
    {
        String temp = "/";
        temp.concat(i);
        char filename[3];
        temp.toCharArray(filename, sizeof(filename));
        numberOfFiles[i] = countFiles(SD.open(filename));
        //Serial.print(filename);
        //Serial.print(": ");
        //Serial.println(numberOfFiles[i]);
    }
 
    // read remembered track
    if (SD.exists(currentTrackFileName))
    {
        File file = SD.open(currentTrackFileName, FILE_READ);
        if (file)
        {
            currentFolder = file.readStringUntil('\n').toInt();
            currentFile = file.readStringUntil('\n').toInt() - 1;
        }
        file.close();
    }
 
 
    delay(100); // init delay
}
 
 
// counts the number of files in directory
unsigned int countFiles(File dir)
{
    unsigned int counter = 0;
    while (true)
    {
        File entry = dir.openNextFile();
        if (!entry)
        {
            // no more files
            break;
        }
 
        counter++;
        entry.close();
    }
    dir.close();
 
    return counter;
}
 
// the loop routine runs over and over again forever
void loop()
{
    // play next song if player stopped
    if (musicPlayer.stopped())
    {
        playNext();
    }
 
    // check the volume and set it
    checkVolume();
 
    // check if a button is pressed and perform some action
    checkButtons();
 
    delay(1); // delay in between reads for stability
}
 
 
// checks the value of the potentiometer
// if it has changed by 2 then set the new volume
void checkVolume()
{
    // read the state of the volume potentiometer
    int read = analogRead(volumePin);
 
    // set the range of the volume from max=0 to min=254
    // (limit max volume to 20 and min to 60) 
    byte state = map(read, 0, 1023, 20, 60);
 
 
    // recognize state (volume) changes in steps of two
    if (state < volumeState - 1 || state > volumeState + 1)
    {
        // remember the new volume state
        volumeState = state;
 
        // set volume max=0, min=254
        musicPlayer.setVolume(volumeState, 254);
 
        // print out the state of the volume
        //Serial.print(volumePin);
        //Serial.print(" volume ");
        //Serial.println(volumeState);
    }
}
 
// check if some button is pressed
// play first track, if button is not pressed last time
// play next track, if a button is pressed again
void checkButtons()
{
    // get the pressed button
    byte pressedButton = getPressedButton();
 
    // if a button is pressed
    if (pressedButton != 0)
    {
        //Serial.print("Taste: ");
        //Serial.println(pressedButton);
 
        // if a track/play list button is pressed
        if (pressedButton < 10 && released)
        {
            musicPlayer.stopPlaying();
            if (currentFolder == pressedButton)
            {
                playNext();
            }
            else
            {
                currentFolder = pressedButton;
                currentFile = 1;
                playCurrent();
            }
 
        }
        // if a function button is pressed
        else
        {
            if (pressedButton == 10 && released)
            {
                musicPlayer.stopPlaying();
                long time = millis();
 
                // this is the second press within 1 sec., so we 
                // got to the previous track
                if (lastReleasedButton == 10 && 
                    ((time - lastBackButtonTime) < buttonPressedDelay))
                {
                    playPrevious();
                }
                else
                {
                    playCurrent();
                }
                lastBackButtonTime = time;
            }
            else if (pressedButton == 11 && released)
            {
                // increase play speed
                musicPlayer.sciWrite(VS1053_REG_WRAMADDRpara_playSpeed);
                musicPlayer.sciWrite(VS1053_REG_WRAM, 3);
                //Serial.println("increase speed");
            }
        }
 
        released = false;
        lastReleasedButton = pressedButton;
    }
    else
    {
        released = true;
 
        // reset play speed
        if (lastPressedButton == 11)
        {
            musicPlayer.sciWrite(VS1053_REG_WRAMADDRpara_playSpeed);
            musicPlayer.sciWrite(VS1053_REG_WRAM, 1);
        }
    }
 
    // remember pressed button
    lastPressedButton = pressedButton;
}
 
 
void playPrevious()
{
    currentFile--;
    if (currentFile < 1)
    {
        currentFile = numberOfFiles[currentFolder];
    }
    playCurrent();
}
 
void playNext()
{
    currentFile++;
    if (currentFile > numberOfFiles[currentFolder])
    {
        currentFile = 1;
    }
    playCurrent();
}
 
void playCurrent()
{
    if (numberOfFiles[currentFolder] > 0)
    {
        rememberCurrentTrack();
 
        String temp = "/";
        temp.concat(currentFolder);
        temp.concat("/");
        temp.concat(currentFile);
        temp.concat(".mp3");
        char filename[temp.length() + 1];
        temp.toCharArray(filename, sizeof(filename));
        musicPlayer.startPlayingFile(filename);
 
        //Serial.print("Play ");
        //Serial.println(filename);
    }
}
 
void rememberCurrentTrack()
{
    if (SD.exists(currentTrackFileName))
    {
        SD.remove(currentTrackFileName);
    }
 
    File file = SD.open(currentTrackFileName, FILE_WRITE);
    if (file)
    {
        file.println(currentFolder);
        file.println(currentFile);
    }
    file.close();
}
 
 
// returns 0 if no button is pressed,
// else the number of the pressed button is returned (1 - 11)
byte getPressedButton()
{
    int buttonsPinValue = analogRead(buttonsPin);
    byte pressedButton = 0;
 
    if (buttonsPinValue > 823)
    {
        // button 6 has a value of about 878
        pressedButton = 6;
    }
    else if (buttonsPinValue > 725)
    {
        // button 5 has a value of about 768
        pressedButton = 5;
    }
    else if (buttonsPinValue > 649)
    {
        // button 4 has a value of about 683
        pressedButton = 4;
    }
    else if (buttonsPinValue > 586)
    {
        // button 3 has a value of about 614
        pressedButton = 3;
    }
    else if (buttonsPinValue > 535)
    {
        // button 2 has a value of about 559
        pressedButton = 2;
    }
    else if (buttonsPinValue > 492)
    {
        // button 1 has a value of about 512
        pressedButton = 1;
    }
    else if (buttonsPinValue > 450)
    {
        // if no button is pressed the value is of about 473
        pressedButton = 0;
    }
    else if (buttonsPinValue > 400)
    {
        // button 8 has a value of about 427
        pressedButton = 11;
    }
    else if (buttonsPinValue > 340)
    {
        // button 10 has a value of about 372
        pressedButton = 10;
    }
    else if (buttonsPinValue > 267)
    {
        // button 9 has a value of about 307
        pressedButton = 9;
    }
    else if (buttonsPinValue > 178)
    {
        // button 8 has a value of about 228
        pressedButton = 8;
    }
    else if (buttonsPinValue > 0)
    {
        // button 7 has a value of about 128
        pressedButton = 7;
    }
    return pressedButton;
}


Damit wäre das Projekt "Arduino MP3-Player" abgeschlossen. Die SD-Karte kann mit Tracks entsprechend der vorgesehenen Struktur befüllt werden, die dann über den Arduino abgespielt werden können. Allerdings kann das Befüllen und das Verwalten der Tracks noch über eine PC-Software vereinfacht werden. Näheres dazu aber das nächste Mal.



Weitere Blogeinträge

  1. Auswahl der Komponenten
  2. Das Entwicklungsbrett
  3. Das erste Einschalten
  4. Die Entwicklungsumgebung
  5. Knöpfe (digital)
  6. Mehrere Knöpfe (digital)
  7. Mehrere Knöpfe (analog)
  8. Potentiometer
  9. Das MP3 Shield
  10. Auswahl der Komponenten 2
  11. Auswahl der Komponenten (Zusammenfassung) 
  12. Punkt-Streifenrasterplatine und Knöpfe
  13. Punkt-Streifenrasterplatine und weitere Komponenten
  14. Das Gehäuse
  15. Sketch 1 (setup-Methode)
  16. Sketch 2 (loop-Methode)
  17. Sketch 3 (Der komplette Code)
  18. PC-Software


Tuesday, March 31, 2015

Audino - Arduino MP3-Player (16) - Sketch 2 (loop-Methode)

Nachdem wir uns das letzte Mal die setup() Methode angeschaut haben, schauen wir uns jetzt die loop() Methode an.

In der loop() Methode wird zuerst überprüft, ob gerade ein Track abgespielt wird. Ist das nicht der Fall, wird der nächste Track abgespielt.

Beim Einschalten des Geräts wird auch kein Track abgespielt. Da der zuletzt abgespielte Track wiedergegeben werden soll (und nicht der Nächste), wurde in der setup() Methode der Index auf den Vorgänger gesetzt.

// play next song if player stopped
if (musicPlayer.stopped())
{
    playNext();
}

In der playNext() Methode wird der Index für den aktuellen Track um eins hochgezählt. Ist der Index größer als die Anzahl der Tracks im aktuellen Ordner, wird der Index auf den ersten Track gesetzt. Anschließend wird die playCurrent() Methode aufgerufen.

void playNext()
{
    currentFile++;
    if (currentFile > numberOfFiles[currentFolder])
    {
        currentFile = 1;
    }
    playCurrent();
}

In der playCurrent() Methode wird überprüft, ob der aktuell ausgewählte Ordner überhaupt Tracks beinhaltet - nur dann wird fortgefahren. Anschließend wird abgespeichert welcher nun der aktuelle Track ist (rememberCurrentTrack() Methode), ehe der aktuelle Track-Name aus currentFolder und currentFile zusammengesetzt und abgespielt wird.

void playCurrent()
{
    if (numberOfFiles[currentFolder] > 0)
    {
        rememberCurrentTrack();
 
        String temp = "/";
        temp.concat(currentFolder);
        temp.concat("/");
        temp.concat(currentFile);
        temp.concat(".mp3");
        char filename[temp.length() + 1];
        temp.toCharArray(filename, sizeof(filename));
        musicPlayer.startPlayingFile(filename);
 
        Serial.print("Play ");
        Serial.println(filename);
    }
}

In der rememberCurrentTrack() Methode wird in einer Datei auf der SD-Karte currentFolder und currentFile abgespeichert. Dabei wird die Datei zuvor gelöscht, falls die Datei bereits existiert.

void rememberCurrentTrack()
{
    if (SD.exists(currentTrackFileName))
    {
        SD.remove(currentTrackFileName);
    }
 
    File file = SD.open(currentTrackFileName, FILE_WRITE);
    if (file)
    {
        file.println(currentFolder);
        file.println(currentFile);
    }
    file.close();
}

Als nächstes wird in der loop() Methode überprüft, ob die Lautstärke geändert werden soll. Dazu wird die checkVolume() Methode aufgerufen, in der als erstes der aktuelle Wert des Potentiometers abgerufen wird. Der ausgelesene Wert wird auf den Lautstärkebereich übertragen. Falls eine Änderung um 2 stattgefunden hat, wird der neue Wert gesetzt.

// the pin of the potentiometer that is used to control the volume
const int volumePin = A1;

// the current volume level, set to min at start
byte volumeState = 254;

// checks the value of the potentiometer
// if it has changed by 2 then set the new volume
void checkVolume()
{
    // read the state of the volume potentiometer
    int read = analogRead(volumePin);
 
    // set the range of the volume from max=0 (limit max volume to 20) to min=254 
    byte state = map(read, 0, 1023, 20, 60);
 
 
    // recognize state (volume) changes in steps of two
    if (state < volumeState - 1 || state > volumeState + 1)
    {
        // remember the new volume state
        volumeState = state;
 
        // set volume max=0, min=254
        musicPlayer.setVolume(volumeState, 254);
 
        // print out the state of the volume
        Serial.print(volumePin);
        Serial.print(" volume ");
        Serial.println(volumeState);
    }
}

Schließlich wird in der loop() Methode überprüft, ob ein Knopf gedrückt worden ist und gegebenenfalls eine entsprechende Aktion ausgeführt. Dazu wird die checkButtons() Methode aufgerufen. In dieser wird als erstes über getPressedButton() ermittelt, ob ein Knopf gedrückt worden ist und wenn ja welcher.

Ist ein Knopf gedrückt worden, wird überprüft ob der Knopf einem Track / einer Play List entspricht oder einem Funktionsknopf. Dabei wird nur eine Aktion ausgeführt, wenn zuvor kein Knopf (released=true) gedrückt worden war. Anschließend wird released=false gesetzt.

Handelt es sich um einen Track/Play List Knopf, wird der aktuelle Track angehalten. War der zuvor abgespielte Track schon in dem Ordner, dem der gedrückte Knopf entspricht, wird der nächste Track abgespielt. War der zuvor abgespielte Track nicht in dem Ordner, dem der gedrückte Knopf entspricht, wird der aktuelle Ordner gesetzt und der erste Track abgespielt.

Handelt es sich um einen Funktions-Knopf, wird überprüft um welchen es sich handelt. Beim Zurück-Knopf wird der aktuelle Track angehalten. Schließlich wird überprüft, ob der Zurück-Knopf wiederholt innerhalb einer Sekunde gedrückt worden ist oder ob der Zurück-Knopf das erste Mal gedrückt worden ist. Ist der Zurück-Knopf das erste Mal gedrückt worden, wird der zuletzt gespielte Track von Vorne abgespielt. Ist der Zurück-Knopf wiederholt innerhalb einer Sekunde gedrückt worden, wird die Methode playPrevious() aufgerufen. Beim Suchvorlauf-Knopf wird die Geschwindigkeit mit der der Track abgespielt wird erhöht.

Ist kein Knopf gedrückt worden, wird released=true gesetzt.Wurde zuletzt der Suchvorlauf-Knopf verwendet, wird die Abspielgewchwindigkeit wieder zurückgesetzt.

// wait before next click is recognized
const int buttonPressedDelay = 3000;
// last button that was pressed
byte lastPressedButton = 0;
// is the last pressed button released
boolean released = true;
// remember if the back button was pressed last time
byte lastReleasedButton = 0;
// the time at the back button was pressed last time
long lastBackButtonTime = 0;

// VS1053 play speed parameter
#define para_playSpeed 0x1E04
 

/// check if some button is pressed
// play first track, if button is not pressed last time
// play next track, if a button is pressed again
void checkButtons()
{
    // get the pressed button
    byte pressedButton = getPressedButton();
 
    // if a button is pressed
    if (pressedButton != 0)
    {
        //Serial.print("Taste: ");
        //Serial.println(pressedButton);
 
        // if a track/play list button is pressed
        if (pressedButton < 10 && released)
        {
            musicPlayer.stopPlaying();
            if (currentFolder == pressedButton)
            {
                playNext();
            }
            else
            {
                currentFolder = pressedButton;
                currentFile = 1;
                playCurrent();
            }
 
        }
        // if a function button is pressed
        else
        {
            if (pressedButton == 10 && released)
            {
                musicPlayer.stopPlaying();
                long time = millis();
 
                // this is the second press within 1 sec., so we 
                // got to the previous track
                if (lastReleasedButton == 10 && 
                    ((time - lastBackButtonTime) < buttonPressedDelay))
                {
                    playPrevious();
                }
                else
                {
                    playCurrent();
                }
                lastBackButtonTime = time;
            }
            else if (pressedButton == 11 && released)
            {
                // increase play speed
                musicPlayer.sciWrite(VS1053_REG_WRAMADDRpara_playSpeed);
                musicPlayer.sciWrite(VS1053_REG_WRAM, 3);
                //Serial.println("increase speed");
            }
        }
 
        released = false;
        lastReleasedButton = pressedButton;
    }
    else
    {
        released = true;
 
        // reset play speed
        if (lastPressedButton == 11)
        {
            musicPlayer.sciWrite(VS1053_REG_WRAMADDRpara_playSpeed);
            musicPlayer.sciWrite(VS1053_REG_WRAM, 1);
        }
    }
 
    // remember pressed button
    lastPressedButton = pressedButton;
}

Der gedrückte Knopf wird über den Code aus Mehrere Knöpfe (analog) ermittelt.

// the number of the pin that is used for the pushbuttons
const int buttonsPin = A0;

// returns 0 if no button is pressed,
// else the number of the pressed button is returned (1 - 11)
byte getPressedButton()
{
    int buttonsPinValue = analogRead(buttonsPin);
    byte pressedButton = 0;
 
    if (buttonsPinValue > 823)
    {
        // button 6 has a value of about 878
        pressedButton = 6;
    }
    else if (buttonsPinValue > 725)
    {
        // button 5 has a value of about 768
        pressedButton = 5;
    }
    else if (buttonsPinValue > 649)
    {
        // button 4 has a value of about 683
        pressedButton = 4;
    }
    else if (buttonsPinValue > 586)
    {
        // button 3 has a value of about 614
        pressedButton = 3;
    }
    else if (buttonsPinValue > 535)
    {
        // button 2 has a value of about 559
        pressedButton = 2;
    }
    else if (buttonsPinValue > 492)
    {
        // button 1 has a value of about 512
        pressedButton = 1;
    }
    else if (buttonsPinValue > 450)
    {
        // if no button is pressed the value is of about 473
        pressedButton = 0;
    }
    else if (buttonsPinValue > 400)
    {
        // button 8 has a value of about 427
        pressedButton = 11;
    }
    else if (buttonsPinValue > 340)
    {
        // button 10 has a value of about 372
        pressedButton = 10;
    }
    else if (buttonsPinValue > 267)
    {
        // button 9 has a value of about 307
        pressedButton = 9;
    }
    else if (buttonsPinValue > 178)
    {
        // button 8 has a value of about 228
        pressedButton = 8;
    }
    else if (buttonsPinValue > 0)
    {
        // button 7 has a value of about 128
        pressedButton = 7;
    }
    return pressedButton;
}

In der playPrevious() Methode wird der Index für den aktuellen Track um eins runtergezählt. Ist der Index kleiner als 1, wird der Index auf den letzten Track gesetzt. Anschließend wird die playCurrent() Methode aufgerufen.

void playPrevious()
{
    currentFile--;
    if (currentFile < 1)
    {
        currentFile = numberOfFiles[currentFolder];
    }
    playCurrent();
}


Weitere Blogeinträge

  1. Auswahl der Komponenten
  2. Das Entwicklungsbrett
  3. Das erste Einschalten
  4. Die Entwicklungsumgebung
  5. Knöpfe (digital)
  6. Mehrere Knöpfe (digital)
  7. Mehrere Knöpfe (analog)
  8. Potentiometer
  9. Das MP3 Shield
  10. Auswahl der Komponenten 2
  11. Auswahl der Komponenten (Zusammenfassung) 
  12. Punkt-Streifenrasterplatine und Knöpfe
  13. Punkt-Streifenrasterplatine und weitere Komponenten
  14. Das Gehäuse
  15. Sketch 1 (setup-Methode)
  16. Sketch 2 (loop-Methode)
  17. Sketch 3 (Der komplette Code)
  18. PC-Software


Wednesday, February 25, 2015

Audino - Arduino MP3-Player (15) - Sketch 1 (setup-Methode)

Um das MP3 Shield ansteuern zu können wird die zur Verfügung gestellte Bibliothek verwendet. Der Beispielcode, der hier (Das MP3 Shield) zum Laufen gebracht worden ist, ist ein erster Startpunkt. Die benötigten Bibliotheken werden hinzugefügt und ein Adafruit_VS1053_FilePlayer-Objekt angelegt.

#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>
 
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)
#define DREQ          3      // VS1053 Data request, ideally an Interrupt pin
#define CARDCS        4      // Card chip select pin
Adafruit_VS1053_FilePlayer musicPlayer =
    Adafruit_VS1053_FilePlayer(SHIELD_CSSHIELD_DCSDREQCARDCS);

In der setup() Methode werden musicPlayer und SD-Karte initialisiert.

// initialise the music player
if (!musicPlayer.begin())
{
    Serial.println("VS1053 not found");
    while (1);  // don't do anything more
}
 
// initialise the SD card
SD.begin(CARDCS);

Damit das Abspielen der MP3-Dateien im Hintergrund ablaufen kann, wird Interrupt verwendet.

// If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background
// audio playing
musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int

Um zu überprüfen, dass das MP3 Shield erfolgreich initialisiert worden ist, wird ein Ton ausgegeben.

musicPlayer.sineTest(0x44, 100);    // Make a tone to indicate VS1053 is working 

Als nächstes wird analysiert wie viele MP3s in welchen Ordnern abgelegt sind. Die Anzahl der Dateien wird in einem Array abgelegt. Jeder Eintrag im Array entspricht einem Ordner auf der SD-Karte.

unsigned int numberOfFiles[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

Es wird davon ausgegangen, dass auf der SD-Karte 10 Ordner angelegt sind, die von 0 bis 9 durchnummeriert sind. In den Ordnern 1 bis 9 liegen jeweils beliebig viele MP3-Dateien. Diese sind ebenfalls durchnummeriert (1.mp3, 2.mp3, 3.mp3, ...). Im Ordner 0 sind Konfigurationsdateien abgelegt. Es wird durch alle Ordner durchiteriert

// read the number of tracks in each folder
for (byte i = 0; i < 10; i++)
{
    String temp = "/";
    temp.concat(i);
    char filename[3];
    temp.toCharArray(filename, sizeof(filename));
    numberOfFiles[i] = countFiles(SD.open(filename));
    Serial.print(filename);
    Serial.print(": ");
    Serial.println(numberOfFiles[i]);
}

und die Anzahl der Dateien im Ordner bestimmt.

// counts the number of files in directory
unsigned int countFiles(File dir)
{
    unsigned int counter = 0;
    while (true)
    {
        File entry = dir.openNextFile();
        if (!entry)
        {
            // no more files
            break;
        }
 
        counter++;
        entry.close();
    }
    dir.close();
 
    return counter;
}

Damit nach einem erneuten Einschalten der zuletzt gespielte Titel gespielt wird, wird dieser aus einer Datei ausgelesen. Aktueller Ordner und aktuelle Datei werden abgespeichert. Als aktuelle Datei wird der Vorgänger abgespeichert, da beim Start der nächste Track abgespielt wird.

char currentTrackFileName[] = "/0/current.txt";
byte currentFolder = 1;
unsigned int currentFile = 0;
// read remembered track
if (SD.exists(currentTrackFileName))
{
    File file = SD.open(currentTrackFileName, FILE_READ);
    if (file)
    {
        currentFolder = file.readStringUntil('\n').toInt();
        currentFile = file.readStringUntil('\n').toInt() - 1;
    }
    file.close();
}

Nachdem jetzt die setup() Methode abgehandelt worden ist, schauen wir uns als nächstes die loop() Methode an.


Weitere Blogeinträge

  1. Auswahl der Komponenten
  2. Das Entwicklungsbrett
  3. Das erste Einschalten
  4. Die Entwicklungsumgebung
  5. Knöpfe (digital)
  6. Mehrere Knöpfe (digital)
  7. Mehrere Knöpfe (analog)
  8. Potentiometer
  9. Das MP3 Shield
  10. Auswahl der Komponenten 2
  11. Auswahl der Komponenten (Zusammenfassung) 
  12. Punkt-Streifenrasterplatine und Knöpfe
  13. Punkt-Streifenrasterplatine und weitere Komponenten
  14. Das Gehäuse
  15. Sketch 1 (setup-Methode)
  16. Sketch 2 (loop-Methode)
  17. Sketch 3 (Der komplette Code)
  18. PC-Software

Tuesday, February 17, 2015

Audino - Arduino MP3-Player (14) - Das Gehäuse

Nachdem jetzt die Elektronik fertig ist, an dieser Stelle vielen Dank an Florian, der hier fachkundig zur Hilfe war und auch das Löten übernommen hat, kann die Elektronik in ein Gehäuse eingebaut werden. Auch bei der Erstellung des Gehäuses hatte ich Hilfe, großen Dank an Klaus, der in kürzester Zeit das Gehäuse erstellt hat.

Und so sieht das Gehäuse aus. Front und Rückseite können geöffnet werden.


Der Potentiometer und der Kippschalter können am Gehäuse befestigt werden.


Die Punkt-Streifenrasterplatine und der Lautsprecher mit dem Schutzgitter sind an der Front befestigt worden.


Über die Rückseite kann auf die verschraubten Komponenten zugegriffen werden.


Und so sieht der fertiggestellte MP3-Player aus.


Als nächstes ist die Software (Sketch) dran, die auf das Arduino-Board drauf gespielt wird.



Weitere Blogeinträge

  1. Auswahl der Komponenten
  2. Das Entwicklungsbrett
  3. Das erste Einschalten
  4. Die Entwicklungsumgebung
  5. Knöpfe (digital)
  6. Mehrere Knöpfe (digital)
  7. Mehrere Knöpfe (analog)
  8. Potentiometer
  9. Das MP3 Shield
  10. Auswahl der Komponenten 2
  11. Auswahl der Komponenten (Zusammenfassung) 
  12. Punkt-Streifenrasterplatine und Knöpfe
  13. Punkt-Streifenrasterplatine und weitere Komponenten
  14. Das Gehäuse
  15. Sketch 1 (setup-Methode)
  16. Sketch 2 (loop-Methode)
  17. Sketch 3 (Der komplette Code)
  18. PC-Software


Saturday, January 24, 2015

Audino - Arduino MP3-Player (13) - Punkt-Streifenrasterplatine und weitere Komponenten

Nachdem die Knöpfe auf der Punkt-Streifenrasterplatine angebracht worden sind und das Arduino-Board auf der Rückseite mit vier Distanzbolzen, Schrauben und Muttern aus dem Prototyping and Development Board befestigt worden sind, können die weiteren Komponenten auf die Punkt-Streifenrasterplatine angebracht beziehungsweise mit der Punkt-Streifenrasterplatine verbunden werden.


Neben das Arduino-Board kann der Batteriehalter platziert werden. Hierfür werden weitere zwei Löcher (3mm) in die Punkt-Streifenrasterplatine gebohrt. Mit zwei Schrauben M3/10 und zwei M3 Muttern kann der Batteriehalter befestigt werden.


Der Anschluss des Batteriehalters wird in die entsprechende Buchse des Arduino-Boards gesteckt.


Die Stromleitung des Batteriehalters wird durchtrennt damit der Kippschalter dazwischengeschaltet werden kann. Zwei Drahtbrücken mit Buchsen sind dazu an den Enden der durchtrennten Stromleitung und zwei Drahtbrücken mit Steckern an den Kippschalter angelötet und mit Schrumpfschlauch fixiert worden. Dadurch kann der Kippschalter an den Batteriehalter gesteckt werden.


An dem Lautsprecher werden zwei Drähte gelötet.


Die Drähte können mit dem MP3 Shield an einem der beiden Endstücke verbunden werden.


Das analoge Inputsignal der Knöpfe wird über die weiße Drahtbrücke gemessen. Das eine Ende ist an entsprechender Stelle an der Punkt-Streifenrasterplatine angelötet, das andere Ende wird in eines der analogen Pins des Arduino-Boards beziehungsweise des MP3 Shields gesteckt.

Die 5V-Stromversorgung der Knöpfe erfolgt über eine rote Drahtbrücke, die ebenfalls mit dem einen Ende an der Punkt entsprechenden Stelle an der Punkt-Streifenrasterplatine angelötet ist. Das andere Ende wird in die 5V-Buchse des Arduino-Boards/MP3 Shields gesteckt.

Auch für Gnd der Knöpfe wird eine schwarze Drahtbrücke an entsprechender Stelle an der Punkt-Streifenrasterplatine angelötet und das andere Ende in eines der Gnd-Pins gesteckt.


An dem Potentiometer sind drei Drahtbrücken mit Steckern gelötet und mit Schrumpfschläuchen fixiert. Die drei Drahtbrücken werden mit anderen drei Drahtbrücken mit Buchsen verbunden.

Die linke Drahtbrücke (rot) wird mit der 5V-Stromversorgung verbunden. Da das Arduino-Board nur eine 5V-Buchse hat, wird eine Drahtbrücke an der Stelle auf der Punkt-Streifenrasterplatine gelötet an der die 5V-Versorgung für die Knöpfe liegt und somit von dieser Stelle die 5V abgegriffen und mit dem Potentiometer verbunden.

Die mittlere Drahtbrücke (gelb) wird mit einem analogen Pin des Arduino-Boards/MP3 Shields verbunden.

Die rechte Drahtbrücke (schwarz) wird mit einem Gnd-Pin des Arduino-Boards/MP3 Shields verbunden.


Für die Befestigung der Punkt-Streifenrasterplatine ans Gehäuse werden in den Ecken vier Löcher in die Punkt-Streifenrasterplatine gebohrt (M3). Vorher kann die Punkt-Streifenrasterplatine noch zurecht geschnitten werden, sodass der Platzbedarf im Gehäuse reduziert wird. Durch die gebohrten Löcher können Kunststoff-Distanzbolzen gesteckt und mit Muttern befestigt werden. Die passenden Schrauben können verwendet werden, um die Punkt-Streifenrasterplatine ans Gehäuse zu befestigen.


Nachfolgend ist die Punkt-Streifenrasterplatine mit allen Komponenten dargestellt. Von vorne..


..und von hinten.


Das nächste Mal wird es um das Gehäuse gehen.




Weitere Blogeinträge

  1. Auswahl der Komponenten
  2. Das Entwicklungsbrett
  3. Das erste Einschalten
  4. Die Entwicklungsumgebung
  5. Knöpfe (digital)
  6. Mehrere Knöpfe (digital)
  7. Mehrere Knöpfe (analog)
  8. Potentiometer
  9. Das MP3 Shield
  10. Auswahl der Komponenten 2
  11. Auswahl der Komponenten (Zusammenfassung) 
  12. Punkt-Streifenrasterplatine und Knöpfe
  13. Punkt-Streifenrasterplatine und weitere Komponenten
  14. Das Gehäuse
  15. Sketch 1 (setup-Methode)
  16. Sketch 2 (loop-Methode)
  17. Sketch 3 (Der komplette Code)
  18. PC-Software

Sunday, January 11, 2015

Audino - Arduino MP3-Player (12) - Punkt-Streifenrasterplatine und Knöpfe

Die Knöpfe werden auf der Punkt-Streifenrasterplatine platziert. Hierbei kann mit den Abständen etwas variiert werden. Am Rand habe ich etwas Platz gelassen, da hier noch Leitungen kommen und auch die Befestigung der Punkt-Streifenrasterplatine ans Gehäuse benötigt etwas Platz.


Auf der Rückseite gegenüber den Knöpfen kann das Arduino-Board mit dem MP3 Shield platziert werden. Entsprechend werden Borlöcher (3mm) gebohrt, sodass das Leitungslayout nicht beeinträchtigt wird.


Die Knöpfe werden von der einen Seite durchgesteckt und auf der anderen Seite gelötet. Das gleiche gilt für die Widerstände und einige Draht-Leitungen.


Auf der gelöteten Seite werden benötigte Verbindungen gelötet.


Das Leitungslayout sollte, entsprechend zu Arduino MP3-Player (7) - Mehrere Knöpfe (analog), den nachfolgenden Abbildungen entsprechen. Diese weichen von den oberen Fotos ab. Im ursprünglichen Layout hatte sich ein Fehler eingeschlichen, der durch verschieben eines Widerstands behoben worden ist. Dieser Fehler ist nun hoffentlich behoben.

Die Leitungen, die mit dem Arduino-Board bzw. MP3 Shield verbunden werden sind hier die 5V Stromversorgung (rot), die Masse (schwarz) und das analoge Inputsignal (weiß). Da neben den Knöpfen noch der Potentiometer mit Strom versorgt werden muss, wird über eine weitere Leitung auf der Punkt-Streifenrasterplatine die 5V Stromversorgung abgegriffen.

Im nachfolgenden Bild sind die Frontansicht und die Rückansicht zusammen dargestellt.


In der Frontansicht sind die Knöpfe und Widerstände zu sehen. Ebenso wie einige Draht-Leitungen.


In der Rückansicht werden die Knöpfe, Widerstände und Draht-Leitungen angelötet. Zudem werden noch weitere Abschnitte der Rasterplatine miteinander verbunden.


Als nächstes werden die weiteren Komponenten, die noch auf die Punkt-Streifenrasterplatine platziert oder mit dieser verbunden werden sollen, betrachtet.



Weitere Blogeinträge

  1. Auswahl der Komponenten
  2. Das Entwicklungsbrett
  3. Das erste Einschalten
  4. Die Entwicklungsumgebung
  5. Knöpfe (digital)
  6. Mehrere Knöpfe (digital)
  7. Mehrere Knöpfe (analog)
  8. Potentiometer
  9. Das MP3 Shield
  10. Auswahl der Komponenten 2
  11. Auswahl der Komponenten (Zusammenfassung) 
  12. Punkt-Streifenrasterplatine und Knöpfe
  13. Punkt-Streifenrasterplatine und weitere Komponenten
  14. Das Gehäuse
  15. Sketch 1 (setup-Methode)
  16. Sketch 2 (loop-Methode)
  17. Sketch 3 (Der komplette Code)
  18. PC-Software