Abspielgerät über Serielle Schnittstelle steuern
14.01.2014, 17:31
Guten Tag,
das Board funktioniert bei mir perfekt. Da ich während des Abspielvorganges noch sehr viele andere Berechnungen für mein Projekt durchführen muss, wird das Shield auf einem separaten Arduino betrieben. Für die Ansteuerung nutz ich die Serielle Schnittstelle. Die Schnittstelle läuft mit 115200 Baud, sodass hier möglichst wenig Verzögerungen auftreten.
Falls noch jemand das Programm gebrauchen kann:
Seriell senden:
Die Funktionen p liefert den wert s für started zurück,
Sobald ein Song zuende ist wird das "e" gesendet.
Code auf einem zweiten Arduino:
Ein möglicher Aufruf kann nun wie folgt aussehen:
Quellcode auf dem Arduino mit dem ASA1 Shield
Anscheinend funktionieren hier die Code Tags nicht richtig. Die Zeilen mit gehören nicht in dem Programm Quelltext.
das Board funktioniert bei mir perfekt. Da ich während des Abspielvorganges noch sehr viele andere Berechnungen für mein Projekt durchführen muss, wird das Shield auf einem separaten Arduino betrieben. Für die Ansteuerung nutz ich die Serielle Schnittstelle. Die Schnittstelle läuft mit 115200 Baud, sodass hier möglichst wenig Verzögerungen auftreten.
Falls noch jemand das Programm gebrauchen kann:
Seriell senden:
- pxxx => p=play, xxx=entspricht dem Mp3-File auf der SD Karte
- lxxyyyzzz => l=loop, xx=Wiederholungsrate, yyy=Mp3-File, zzz=delay zwischen den wiedergaben
- s => stop playing
- + => volume + 1
- ++ => volume + 10
- - => volume - 1
- -- => volume - 10
- vxxx => v=set volume, xxx = Lautstärke zwischen 0 und 100 %
- c => check liefert r=ready zurück wenn nichts abgespielt wird oder p=playing falls gerade ein sound läuft
Die Funktionen p liefert den wert s für started zurück,
Sobald ein Song zuende ist wird das "e" gesendet.
Code auf einem zweiten Arduino:
Ein möglicher Aufruf kann nun wie folgt aussehen:
// variante 1
Serial.println("p001"); // das mp3 mit der Bezeichnung 001.mp3 wird gestartet
// variante 2
Serial.println("p761"); // das mp3 001 wird gestoppt und das neue gestartet
// variante 3
Serial.println("c"); // liefert den Wert "p" zurück, da gerade mp3 761 abgespielt wird
// variante 4
Serial.println("v90"); // volumen wird auf 90% gesetzt
// variante 5
Serial.println("s"); // die Wiedergabe wird gestoppt
Quellcode auf dem Arduino mit dem ASA1 Shield
#include <SD.h>
#include <SPI.h>
#include <AudioShield.h>
// Description
//=======================
// pxxx | play song xxx.mp3 | returns 's' for start
// lxxyyyzzz | loop a song xx => loops, yyy => song yyy.mp3, zzz => delay between songs
// s | stop playing | return 'e' for end
// + | volume + 1
// ++ | volume + 10
// - | volume - 1
// -- | volume - 10
// v000 | volume between 0 and 100
// c | returns r when nothing is playing (r=ready) or p for playing
&*****************************************************************************
* globale Variablen
******************************************************************************/
#define SERIAL_BUFFER_CNT 12
char g_mp3_filename = "xxx.mp3";
uint8_t g_mp3_volume = 50;
unsigned char g_mp3_buffer;
File g_mp3_SoundFile;
char g_mp3_mode = 0;
char g_mp3_mode_old = 0;
char g_serial_buffer_read;
char g_serial_buffer;
unsigned char g_serial_cnt = 0;
uint8_t g_error_code = 0;
uint8_t g_loop_cnt = 0;
uint16_t g_loop_delay = 0;
&*****************************************************************************
* function
******************************************************************************/
&
* convertVolume: Wandelt das Volumen in einen Bereich zwischen 0 und 100 % um
*/
void mp3_convertAndSetVolume(unsigned char volume)
{
//check limit
if(volume > 100) {
volume = 100;
}
if(volume > 0) {
//volumen berechnen
volume = 120-(int)((double)(120./100*volume));
//Verstärker einschalten
VS1011.UnsetMute();
VS1011.SetVolume(volume, volume);
} else {
VS1011.SetMute();
}
}
&*****************************************************************************
* setup
******************************************************************************/
void setup()
{
Serial.begin(115200);
SPI.setClockDivider(2);
pinMode(SD_POWER, OUTPUT);
SD_POWER_ON; //SD-Karte low-aktiv
//SD-Karte initialisieren
//SD_CS als parameter übergeben, da hier ChipSelect anders belegt
if( SD.begin( SD_CS ) == false ){ return; }
Serial.println("r");
//MP3-Decoder initialisieren
VS1011.begin();
}
&*****************************************************************************
* loop
******************************************************************************/
void loop()
{
// reset serial input counter
g_serial_cnt = 0;
// get serial input data
while(Serial.available()) {
if(g_serial_cnt >= (SERIAL_BUFFER_CNT)) {
break;
} else {
g_serial_buffer_read = Serial.read();
g_serial_cnt++;
}
delay(5);
}
// clean serial input data
if(g_serial_cnt > 0) {
for(uint8_t i=0; i<(SERIAL_BUFFER_CNT-1);i++) {
g_serial_buffer = 0;
}
for(uint8_t i=0; i<g_serial_cnt; i++) {
g_serial_buffer = g_serial_buffer_read;
}
g_mp3_mode_old = g_mp3_mode;
g_mp3_mode = g_serial_buffer;
}
Serial.flush();
//select programm data
switch(g_mp3_mode) {
// -
// - system schleifen -
// -
// init audio player
case 1:
//open file
if(g_mp3_SoundFile = SD.open(g_mp3_filename)) {
mp3_convertAndSetVolume(g_mp3_volume); // Set Volume
g_mp3_mode = 3; // goto: play file
Serial.println("s");
} else {
g_mp3_mode = 0; // goto: nothing found
}
break;
// stop audio player
case 2:
mp3_convertAndSetVolume(0);
VS1011.Send2048Zeros();
g_mp3_mode = 0;
break;
// play audio file
case 3:
if(g_mp3_SoundFile.available()) {
g_mp3_SoundFile.read( g_mp3_buffer, sizeof(g_mp3_buffer) );
VS1011.Send32( g_mp3_buffer );
} else {
if(g_loop_cnt > 0) {
delay(g_loop_delay);
g_loop_cnt--;
g_mp3_mode = 1;
} else {
g_mp3_mode = 2; // Song Ende => goto: stop
Serial.println("e");
}
}
break;
// -
// - user input -
// -
case 'c':
if(g_mp3_mode_old == 3) {
Serial.println("p");
} else {
Serial.println("r");
}
g_mp3_mode = g_mp3_mode_old;
break;
//p => play xxx song
case 'p':
g_mp3_filename = g_serial_buffer;
g_mp3_filename = g_serial_buffer;
g_mp3_filename = g_serial_buffer;
g_mp3_mode = 1;
break;
//l => play song in loop
case 'l':
g_mp3_filename = g_serial_buffer;
g_mp3_filename = g_serial_buffer;
g_mp3_filename = g_serial_buffer;
g_loop_cnt = (g_serial_buffer-48)*10+(g_serial_buffer-48);
g_loop_delay = (g_serial_buffer-48)*100+(g_serial_buffer-48)*10+(g_serial_buffer-48);
g_mp3_mode = 1;
break;
//s => stop song
case 's':
g_mp3_mode = 2;
break;
//- => volume --
case '-':
if(g_serial_cnt == 1 && g_mp3_volume > 0) {
g_mp3_volume--;
} else if(g_serial_cnt == 2 && g_mp3_volume > 10) {
g_mp3_volume-= 10;
} else {
g_mp3_volume = 0;
}
mp3_convertAndSetVolume(g_mp3_volume);
g_mp3_mode = 3;
break;
//+ => volume ++
case '+':
if(g_serial_cnt == 1 && g_mp3_volume < 100) {
g_mp3_volume++;
} else if(g_serial_cnt == 2 && g_mp3_volume < 90) {
g_mp3_volume+= 10;
} else {
g_mp3_volume = 100;
}
mp3_convertAndSetVolume(g_mp3_volume);
g_mp3_mode = 3;
break;
// set volume
case 'v':
if(g_serial_cnt == 2) {
g_mp3_volume = (g_serial_buffer-48);
} else if(g_serial_cnt == 3) {
g_mp3_volume = (g_serial_buffer-48)*10+(g_serial_buffer-48);
} else if(g_serial_cnt == 4) {
g_mp3_volume = 100;
}
mp3_convertAndSetVolume(g_mp3_volume);
g_mp3_mode = 3;
break;
//other inputs
default:
break;
}
}
Anscheinend funktionieren hier die Code Tags nicht richtig. Die Zeilen mit gehören nicht in dem Programm Quelltext.