Der/ die Betrachter/in sitzt gegenüber eines Transparentes. Der Kopf steckt unter einer Friseurhaube. Im Inneren der Friseurhaube soll eine Geschichte (frei erzählt nach einer Kindheitserinnerung) ertönen.
Eine .mp3- Datei soll von einem YX5300- Modul, angeschlossen an einen Arduino Uno abgespielt werden und der Sound soll von zwei aktiven Lautsprechern wiedergegeben werden. Die Energie hierfür liefert eine Powerbank.
Hier ist eine Skizze des Setups:
#include <SerialMP3Player.h>
/******************************************************************************
Simple SerialMP3Player "Hello World" example of YX5300 chip.
Copy the "hello.mp3" file to an empty SD card
Connect the Serial MP3 Player to the Arduino board
GND → GND
VCC → 5V
TX → pin 10
RX → pin 11
After compile and upload the code you must hear “Hello world” over and over.
This example code is in the public domain.
https://github.com/salvadorrueda/ArduinoSerialMP3Player
by Salvador Rueda
*******************************************************************************/
#include "SerialMP3Player.h" // Einbinden der "SerialMP3Player.h- Bibliothek
const int Taster = 9;
unsigned long timestore; // variabler Speicher für Zeit
bool TasterStatus ; // Variable für Tasterstatus
#define TX 11 // TX wird als Pin 11 definiert // die Pins auf dem MP3 Player- Modul schein vertauscht zu sein, denn TX de YX5300 Moduls liegt an Pin 10 an...
#define RX 10 // RX wird als Pin 10 definiert //...und RX des YX5300- Moduls liegt an Pin 11 an
SerialMP3Player mp3(RX, TX);
void setup() {
pinMode (Taster, INPUT_PULLUP);
Serial.begin(9600); // starte die serielle Schnittstelle
mp3.begin(9600); // starte die mp3-Kommunikation
delay(500); // Wartezeit für den Anfang
mp3.sendCommand(CMD_SEL_DEV, 0, 2); //Auswählen der sd-card
delay(500); // Wartezeit für den Anfang
}
// the loop function runs over and over again forever
void loop() {
mp3.play(); // Spiele die mp3- Datei
if (millis() - timestore > 100000)
{
mp3.play(); // Spiele die mp3- Datei
timestore = millis();
}
if (digitalRead(Taster) == LOW)
{
mp3.play(); // Spiele die mp3- Datei
timestore = millis;
}
}
Das hier ist der Sketch mit dem ich das ganze gerade ausprobiert habe. Leider funktioniert es nicht. Kann es sein, dass es sich generell um einen ziemlich falschen Ansatz handelt?
#include <SerialMP3Player.h>
/******************************************************************************
Simple SerialMP3Player "Hello World" example of YX5300 chip.
Copy the "hello.mp3" file to an empty SD card
Connect the Serial MP3 Player to the Arduino board
GND → GND
VCC → 5V
TX → pin 10
RX → pin 11
After compile and upload the code you must hear “Hello world” over and over.
This example code is in the public domain.
https://github.com/salvadorrueda/ArduinoSerialMP3Player
by Salvador Rueda
*******************************************************************************/
#include "SerialMP3Player.h" // Einbinden der "SerialMP3Player.h- Bibliothek
#define TX 11 // TX wird als Pin 11 definiert // die Pins auf dem MP3 Player- Modul schein vertauscht zu sein, denn TX de YX5300 Moduls liegt an Pin 10 an...
#define RX 10 // RX wird als Pin 10 definiert //...und RX des YX5300- Moduls liegt an Pin 11 an
SerialMP3Player mp3(RX,TX);
void setup() {
Serial.begin(9600); // starte die serielle Schnittstelle
mp3.begin(9600); // starte die mp3-Kommunikation
delay(500); // Wartezeit für den Anfang
mp3.sendCommand(CMD_SEL_DEV, 0, 2); //Auswählen der sd-card
delay(500); // Wartezeit für den Anfang
}
// the loop function runs over and over again forever
void loop() {
mp3.play(); // Spiele die mp3- Datei
delay(100000); // wait for x seconds, bis sich der void loop Teil wiederholt
}
Diesen Sketch hier habe ich als Grundlage genommen ( er funktioniert ) und dann im oben geposteten Sketch versucht, das Neustarten der .mp3- Datei per Drücken des Tasters neu zu starten ( was bisher nicht funktioniert). Kann mir bitte jemand helfen und mir verraten wo der Fehler liegt?
Was mich wundert ist, dass RX ---- Pin 11 und TX ---- Pin 10 im Setup verbunden sind, und es so funktionert, obwohl sie hier
#define TX 11 // TX wird als Pin 11 definiert // die Pins auf dem MP3 Player- Modul schein vertauscht zu sein, denn TX de YX5300 Moduls liegt an Pin 10 an...
#define RX 10 // RX wird als Pin 10 definiert //...und RX des YX5300- Moduls liegt an Pin 11 an
rx und tx sind bei beiden Sketches gleich definiert, also im einen Sketch, der funktioniert, genauso wie im nicht funktionierenden. Das wird deshalb nichts nützen...
Tx und Rx sind immer "über Kreuz" zu verbinden:
Das T steht für Transmit - was der eine Chip sendet, empfängt der andere.
Das R steht für Receive - was der andere Chip gesendet hat, empfängt der eine.
Die Verkabelungsskizze stimmt also mit den defines überein: #define TX 11 geht an den Receive-Pin vom Soundmodul und #define RX 10 an den Transmit vom Sound.
Aber wie @my_xy_projekt schon bemerkte: Wenn Du serielle Kommunikation auf Pins 10 und 11 machen willst, sollte irgendwo im Code SoftwareSerial auftauchen. Da ist was faul...
Danke für die Info mit der "über Kreuz" Verbindung!
Okay, vielen Dank my_xy_projekt und wno158. Der YX5300 kommuniziert über SoftwareSerial und deshalb muss diese Bibliothek in dem Sketch auftauchen. Ich hatte anfangs einen anderen Ansatz, der auf einem anderen Sketch aufgebaut hat, den ich gefunden habe, den poste ich jetzt gleich nochmal, vielleicht sollte ich dort weiter machen...
Ne.
Mach hier weiter.
Das macht es nur aufwendiger - Denke dran, das die Nachwelt das auch verstehen sollte, wenn Du das fertig hast und nicht alle Posts gelesen werden....
#include <SoftwareSerial.h>
#define ARDUINO_RX 5 // TX - Arduino RX // Pin 5 wird als Arduino RX definiert // TX und RX dienen für die serielle Kommunikation zwischen dem Arduino Uno und dem YX5300- Modul
#define ARDUINO_TX 6 // RX - Arduino TX // Pin 6 wird als Arduino TX definiert
SoftwareSerial mySerial(ARDUINO_RX, ARDUINO_TX); //?
unsigned char playmode = 1; // Der Variablen playmode wird der Wert 1 zugeorndet
#define PLAY 1 // Der Compiler ersetzt zur Kompilierzeit Verweise auf diese Konstanten durch den definierten Wert // Play ist 1
#define PAUSE 0 // "" // Pause ist 0
static int8_t Send_buf[8] = {0} ; // Puffer zum Senden- Befehl
/************Command byte**************************/ // die Programmvariablen und die Zugriffsregisterasdressen des YX5300 Moduls werden definiert
#define CMD_NEXT_SONG 0X01 // nächsten Song spielen
#define CMD_PREV_SONG 0X02 // vorherigen Song spielen
#define CMD_PLAY_W_INDEX 0X03
#define CMD_VOLUME_UP 0X04
#define CMD_VOLUME_DOWN 0X05
#define CMD_SET_VOLUME 0X06
#define CMD_SINGLE_CYCLE_PLAY 0X08 // einen einzigen Titel im Zyklus spielen
#define CMD_SEL_DEV 0X09
#define DEV_TF 0X02
#define CMD_SLEEP_MODE 0X0A
#define CMD_WAKE_UP 0X0B
#define CMD_RESET 0X0C
#define CMD_PLAY 0X0D
#define CMD_PAUSE 0X0E
#define CMD_PLAY_FOLDER_FILE 0X0F
#define CMD_STOP_PLAY 0X16
#define CMD_FOLDER_CYCLE 0X17
#define CMD_SET_SINGLE_CYCLE 0X19
#define SINGLE_CYCLE_ON 0X00
#define SINGLE_CYCLE_OFF 0X01
#define CMD_SET_DAC 0X1A
#define DAC_ON 0X00
#define DAC_OFF 0X01
#define CMD_PLAY_W_VOL 0X22
/*********************************************************************/
// Das hier dient alles der Lautstärkeregelung
#define ROTARY_ANGLE_SENSOR A0 // definieren des Dreh- Knaufs, A0= analog Read, empfängt die Signale des Drehknaufs
#define ADC_REF 5//reference voltage of ADC is 5v // Die Bezugsspannung von ADC ist 5 Volt
#define VCC 5 //the default value of VCC of the control interface is 5v // der ursprüngliche Wert von VCC ist 5
#define FULL_ANGLE 280//full value of the rotary angle is 280 degrees // der volle Wert des Drehknaufs sind 280 Grad
//bis hier Lautstärkeregelung
void setup() // void setup()- Teil des Sketches, wird nur ein einziges Mal aufgerufen, wenn der Sketch startet
{
pinMode(2, INPUT); // Button - Pause&Play // Pin2 ist ein Eingang
Serial.begin(9600); // serielle Schnittstelle zwischen Arduino Uno...
mySerial.begin(9600); // und YX5300
delay(500);
attachInterrupt(0, playOrPause, RISING);//pin2 -> INT0, and the Touch Sensor // was passiert hier?
//is connected with pin2 of Arduino
sendCommand(CMD_SEL_DEV, DEV_TF);
delay(200);
sendCommand(CMD_PLAY_W_VOL, 0X0F01);
}
static int8_t pre_vol = 0x0f; // Der Variablen pre_vol wird ein Wert zugeorndet
void loop() // void loop- Teil es Sketches // wird immer wiederholt
{
int degrees; //
degrees = getDegree();
int8_t volume; // Die Variable int8_t wird definiert
/*The degrees is 0~280, should be converted to be 0~255 to control the*/
/*brightness of LED */
volume = map(degrees, 0, 280, 30, 0); // volume und map hat etwas zu tun mit der Lautstärke- Einstellung
if (volume != pre_vol)Die Funktion ist false wenn volume ungleich 0 ist und true wenn
{
sendCommand(CMD_SET_VOLUME, volume);
pre_vol = volume;
}
delay(100);
}
void sendCommand(int8_t command, int16_t dat)// unabhängige Funktion, die aufgerufen werden kann // keine Überschneidung mit anderen Variablen möglich
{
delay(20);
Send_buf[0] = 0x7e; //
Send_buf[1] = 0xff; //
Send_buf[2] = 0x06; //
Send_buf[3] = command; //
Send_buf[4] = 0x00;//
Send_buf[5] = (int8_t)(dat >> 8);//datah
Send_buf[6] = (int8_t)(dat); //datal
Send_buf[7] = 0xef; //
for (uint8_t i = 0; i < 8; i++) //
{
mySerial.write(Send_buf[i]);
}
}
int getDegree() // hat etwas zu tun mit der Lautstärke- Regelung
{
int sensor_value = analogRead(ROTARY_ANGLE_SENSOR);
float voltage;
voltage = (float)sensor_value * ADC_REF / 1023;
float degrees = (voltage * FULL_ANGLE) / VCC;
return degrees;
}
/*Interrupt service routine*/ //
void playOrPause() // eigene Funktion, die bei Bedarf aufgerufen werden kann // keine Überschneidung mit anderen Variablen des Sketches möglich
{
cli(); // Unterbrechungsroutine
if (playmode == PLAY) // wenn playmode und PLAY identisch sind...wann ist das der Fall?
{
playmode = PAUSE; // wird playmode gleich Pause
sendCommand(CMD_PAUSE, 0); // es wird der Befehl Pause gesendet
}
else //...wenn das nicht der Fall ist
{
playmode = PLAY; // wird playmode gleich PLAY
sendCommand(CMD_PLAY, 0); // Der Befehl (CMD_PLAY wird gesendet)
}
sei(); // Ende der Unterbrechungsroutine
}
Hier kann mit Hilfe eines Potentiometers die Lautstärke geregelt werden und mit einem Taster kann die laufende Sound- Datei angehalten (Pause) und weitergespielt (Play) werden. Ich habe den Sketch hier gefunden: rdiot/rdiot-b208: Serial MP3 Music Player Module for Arduino (YX5300) [B208] (github.com)
Ich versuche jetzt mal die Stellen mit dem Potentiometer aus dem Sketch rauszukürzen und den Taster auf das Neustarten der Sound- Datei umzumünzen...
Ich habe Schwierigkeiten mit dem Verstehen des Sketches, aber ich versuche mich da mal durchzuknuspern...
Wenn Du Fehler bekommst, dann klicke bitte auf den Button "Fehlermeldung kopieren" - dann braucht niemand raten.
Wichtig: Unter DATEI - VOREINSTELLUNGEN bitte den Haken setzen bei "ausführliche Ausgabe während : Kompilierung" und Kompilerwarnungen auf ALLE stellen.
Ich glaube, ich habe eine Ahnung was hier vorgeht.
Es gibt tatsächlich eine SerialMP3Player-Library von Salvador Rueda. Da ist ein Hello-World-Beispiel dabei. Es sieht mir so aus, als würdest Du in Post #5 genau dieses Beispiel verwenden.
Frage 1: Korrekt?
Dann ist es auch kein Wunder, dass Du keine SoftwareSerial siehst, denn die wird erst in der Library gebraucht und dort auch im passenden Konstruktor verwendet:
SerialMP3Player::SerialMP3Player(int RX, int TX){
//SoftwareSerial Serial3 = SoftwareSerial(RX, TX);
Serial3 = new SoftwareSerial(RX, TX);
_showDebugMessages = false;
}
Soweit also alles okay.
Frage 2: Der Beispiel-Sketch spielt das MP3 korrekt bis zum Ende ab (sofern es nicht länger ist als die drei Sekunden delay() - oder halt bei Dir 100 Sekunden) und startet danach das Spiel wieder neu?
Was Dir dann jetzt "nur" noch fehlt ist der Ersatz des delay() durch die Tastenbedienung. Frage 3: Korrekt?
ja, zumindest da nicht.
In dem Sketch in #4 hast Du oben sauber einkommentiert:
Aber der Code verwendet dort ganz normal SoftwareSerial. SerialMP3Player.h gibt es dort nicht.
Du hast zwei Codes vermutlich gemischt - und damit für Verwirrung gesorgt ....
Frage 1: Ja, das ist korrekt! Sry hätte ich mal erwähnen können:/
Frage 2: Ja, der Sketch spielt das MP3 bis zum Ende ab, wenn man das delay() lange genug einstellt und starte danach das Spiel wieder von vorn
Frage 3: Ja, genau!