Je tente de faire un petit montage (que je pensais simple) qui consiste a jouer un mp3 aléatoirement quand mon capteur ultrason est a une distance de moins de 50cm.
Si je veux jouer un son seul ou dans un répertoire (CMD_PLAY_W_INDEX, CMD_PLAY_WITHFOLDER, ...) cela fonctionne, par contre avec CMD_SHUFFLE_PLAY que j'ai défini pas moyen.
Mon MP3 est un yx5300.
voici le sketch :
//code rearranged by Javier Muñoz 10/11/2016 ask me at javimusama@hotmail.com
#include <SoftwareSerial.h>
#define ARDUINO_RX 5//should connect to TX of the Serial MP3 Player module
#define ARDUINO_TX 6//connect to RX of the module
#define trigPin 13
#define echoPin 12
SoftwareSerial mySerial(ARDUINO_RX, ARDUINO_TX);//init the serial protocol, tell to myserial wich pins are TX and RX
////////////////////////////////////////////////////////////////////////////////////
static int8_t Send_buf[8] = {0} ;//The MP3 player undestands orders in a 8 int string
//0X7E FF 06 command 00 00 00 EF;(if command =01 next song order)
#define NEXT_SONG 0X01
#define PREV_SONG 0X02
#define CMD_PLAY_W_INDEX 0X03 //DATA IS REQUIRED (number of song)
#define VOLUME_UP_ONE 0X04
#define VOLUME_DOWN_ONE 0X05
#define CMD_SET_VOLUME 0X06//DATA IS REQUIRED (number of volume from 0 up to 30(0x1E))
#define SET_DAC 0X17
#define CMD_PLAY_WITHVOLUME 0X22 //data is needed 0x7E 06 22 00 xx yy EF;(xx volume)(yy number of song)
#define CMD_SEL_DEV 0X09 //SELECT STORAGE DEVICE, DATA IS REQUIRED
#define DEV_TF 0X02 //HELLO,IM THE DATA REQUIRED
#define SLEEP_MODE_START 0X0A
#define SLEEP_MODE_WAKEUP 0X0B
#define CMD_RESET 0X0C//CHIP RESET
#define CMD_PLAY 0X0D //RESUME PLAYBACK
#define CMD_PAUSE 0X0E //PLAYBACK IS PAUSED
#define CMD_PLAY_WITHFOLDER 0X0F//DATA IS NEEDED, 0x7E 06 0F 00 01 02 EF;(play the song with the directory \01\002xxxxxx.mp3
#define STOP_PLAY 0X16
#define CMD_SHUFFLE_PLAY 0X18//
#define PLAY_FOLDER 0X17// data is needed 0x7E 06 17 00 01 XX EF;(play the 01 folder)(value xx we dont care)
#define SET_CYCLEPLAY 0X19//data is needed 00 start; 01 close
#define SET_DAC 0X17//data is needed 00 start DAC OUTPUT;01 DAC no output
////////////////////////////////////////////////////////////////////////////////////
void setup()
{
Serial.begin(9600);//Start our Serial coms for serial monitor in our pc
mySerial.begin(9600);//Start our Serial coms for THE MP3
delay(500);//Wait chip initialization is complete
sendCommand(CMD_SEL_DEV, DEV_TF);//select the TF card
delay(200);//wait for 200ms
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop()
{
if(measureDistance(trigPin,echoPin)<50){
sendCommand(CMD_SET_VOLUME, 0X0F);//volume
sendCommand(CMD_SHUFFLE_PLAY, 0);//player
delay(5000);//wait to avoid errors
}
delay(300);
}
void sendCommand(int8_t command, int16_t dat)
{
delay(20);
Send_buf[0] = 0x7e; //starting byte
Send_buf[1] = 0xff; //version
Send_buf[2] = 0x06; //the number of bytes of the command without starting byte and ending byte
Send_buf[3] = command; //
Send_buf[4] = 0x00;//0x00 = no feedback, 0x01 = feedback
Send_buf[5] = (int8_t)(dat >> 8);//datah
Send_buf[6] = (int8_t)(dat); //datal
Send_buf[7] = 0xef; //ending byte
for(uint8_t i=0; i<8; i++)//
{
mySerial.write(Send_buf[i]) ;//send bit to serial mp3
Serial.print(Send_buf[i],HEX);//send bit to serial monitor in pc
}
Serial.println();
}
long measureDistance(int trigger,int echo){
long duration, distance;
digitalWrite(trigger, LOW); //PULSE ___|---|___
delayMicroseconds(2);
digitalWrite(trigger, HIGH);
delayMicroseconds(10);
digitalWrite(trigger, LOW);
duration = pulseIn(echo, HIGH);
distance = (duration/2) / 29.1;
Serial.println("distance:");
Serial.println(distance);
return distance;
}
Merci d'avance pour tout éclairage que vous pourrez m'apporter.
Il y a ici un exemple de code qui utilise la fonction shuffle.
Il fait :
/** Random playing */
void shufflePlay() {
send_kt_command(0x18, 0, 0, 20);
}
avec
/** Fonction de bas niveau pour envoyer une commande au module KT403A */
void send_kt_command(byte command, byte data_h, byte data_l, unsigned long cmd_delay) {
Serial.write(COMMAND_BYTE_START);
Serial.write(COMMAND_BYTE_VERSION);
Serial.write((byte) 0x06);
Serial.write(command);
Serial.write((byte) 0x00);
Serial.write(data_h);
Serial.write(data_l);
Serial.write(COMMAND_BYTE_STOP);
// 16-bits checksum is optionnal
delay(cmd_delay);
}
Je rame un peu avec ce code...(mais je continue d'explorer)
De mon coté j'ai trouvé ceci :
void loop() {
if (measureDistance(trigPin, echoPin) < 50) {
int randTrackNo;
randTrackNo = random(1, 6);
sendCommand(CMD_PLAY_W_INDEX, randTrackNo);
Serial.print("Playing track:");
Serial.println(randTrackNo);
delay(1000); //wait to avoid errors
}
delay(300);
}
Ca fonctionne ,MAIS comme mes sons ne sont pas tous identique en minutage, si l'on reste dans les 50cm, un autre démarre etc...et c'est plutôt chiant de caler le "Delay" du coup...
Il faut que tu utilises un 'drapeau' : une variable qui indique qu'un morceau est en train d'être joué et qu'il ne faut pas faire de mesure pendant ce temps. Le temps en question, tu dois le décider : 1 secondes, 5 secondes ? Et tu chronomètres avec millis() : dès que ce temps est dépassé tu changes la valeur du drapeau.
Je précise avoir tester avec Nano et Uno. et que quand je fais un test de lecture avec CMD_PLAY_WITHFOLDER 0X0F en indiquant 0x0102 il me lit bien le n°002.mp3 du dossier 01...donc pas un problème de codage ou de fichier j'ai tester plusieurs modules mp3 yx5300 idem sur chaque.
Il n'y a pas de raison qu'il ne joue que les impairs, random(1,6) renvoie un nombre entre 1 et 5 compris.
Par contre, c'est pas vraiment des nombres aléatoires, mais une série de nombres qui sera la même à chaque exécution.
Essaye d'ajouter
randomSeed(analogRead(0));
dans le setup pour que les séries soient différentes.
Sinon, tu peux utiliser la bibli TrueRandom qui génère de l'aléatoire plus aléatoire...
Si tu veux faire un shuffle, tu peux le coder toi-même. Il suffit de faire une liste de nombres allant de 1 à ton nombre de pistes N et de la mélanger.
Ca peut se faire comme ça :
for (int i=0;i<100;i++) {
int indice1 = random(1,N);
int indice2 = random(1,N);
int a = liste[indice1];
liste[indice1] = liste[indice2];
liste[indice2] = a;
}
100 est le nombre de fois que tu mélanges. Ce nombre peut être changé, je l'ai choisi au hasard.
Regarde le tableau de la réponse #5 : il semble qu'il range les tracks par groupes de 2. Si tu envoies :
7EFF0603000001EF : il lit la première
7EFF0603000002EF : il lit la seconde
Donc c'est un peu plus subtil : ton nombre aléatoire doit être choisi entre 1 et 73/2 = 36 (le nombre de groupes -- je ne suis pas sûr à 100% de ça) et tu dois faire un seconde tirage aléatoire (1 ou 2) pour choisir la première ou la seconde track...
Oui la broche A0 est bien libre, pour le 0x30 : 01, 02 etc... c'est les track pas des groupe? si? car si je fais sendCommand(0x03, 0x03); il me joue bien la piste 003.mp3 par contre si je fais sendCommand(0x03, 0x04); il ne joue rien...et si je fais sendCommand(CMD_PLAY_WITHFOLDER, 0x0104);, là le 004.mp3 du dossier 01 est bien joué.
là, voici ce qu'il me retourne :
distance: 182
distance: 5
7E FF 6 3 0 0 3F EF
Playing track:63
distance: 182
distance: 141
distance: 141
distance: 138
distance: 138
distance: 139
distance: 11
distance: 8
7E FF 6 3 0 0 22 EF
Playing track:34
#include <SoftwareSerial.h>
#define ARDUINO_RX 5 //should connect to TX of the Serial MP3 Player module
#define ARDUINO_TX 6 //connect to RX of the module
#define trigPin 13 //for the distance module
#define echoPin 12
SoftwareSerial mySerial(ARDUINO_RX, ARDUINO_TX);//init the serial protocol, tell to myserial wich pins are TX and RX
////////////////////////////////////////////////////////////////////////////////////
//all the commands needed in the datasheet(http://geekmatic.in.ua/pdf/Catalex_MP3_board.pdf)
uint8_t Send_buf[8] = {0} ;//The MP3 player undestands orders in a 8 int string
//0X7E FF 06 command 00 00 00 EF;(if command =01 next song order)
#define NEXT_SONG 0X01
#define PREV_SONG 0X02
#define CMD_PLAY_W_INDEX 0X03 //DATA IS REQUIRED (number of song)
#define VOLUME_UP_ONE 0X04
#define VOLUME_DOWN_ONE 0X05
#define CMD_SET_VOLUME 0X06//DATA IS REQUIRED (number of volume from 0 up to 30(0x1E))
#define SET_DAC 0X17
#define CMD_PLAY_WITHVOLUME 0X22 //data is needed 0x7E 06 22 00 xx yy EF;(xx volume)(yy number of song)
#define CMD_SEL_DEV 0X09 //SELECT STORAGE DEVICE, DATA IS REQUIRED
#define DEV_TF 0X02 //HELLO,IM THE DATA REQUIRED
#define SLEEP_MODE_START 0X0A
#define SLEEP_MODE_WAKEUP 0X0B
#define CMD_RESET 0X0C//CHIP RESET
#define CMD_PLAY 0X0D //RESUME PLAYBACK
#define CMD_PAUSE 0X0E //PLAYBACK IS PAUSED
#define CMD_PLAY_WITHFOLDER 0X0F//DATA IS NEEDED, 0x7E 06 0F 00 01 02 EF;(play the song with the directory \01\002xxxxxx.mp3
#define STOP_PLAY 0X16
#define PLAY_FOLDER 0X17// data is needed 0x7E 06 17 00 01 XX EF;(play the 01 folder)(value xx we dont care)
#define SET_CYCLEPLAY 0X19//data is needed 00 start; 01 close
#define SET_DAC 0X17//data is needed 00 start DAC OUTPUT;01 DAC no output
////////////////////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(9600); //Start our Serial coms for serial monitor in our pc
mySerial.begin(9600); //Start our Serial coms for THE MP3
delay(500); //Wait chip initialization is complete
sendCommand(CMD_SEL_DEV, DEV_TF); //select the TF card
delay(200); //wait for 200ms
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
randomSeed(analogRead(A0));
}
void loop() {
if (measureDistance(trigPin, echoPin) < 200) {
int randTrackNo;
randTrackNo = random(0, 142);
sendCommand(CMD_SET_VOLUME, 0x50);
sendCommand(0x03, randTrackNo);
Serial.print("Playing track:");
Serial.println(randTrackNo);
delay(5000); //wait to avoid errors
}
delay(300);
}
void sendCommand(int8_t command, int16_t dat) {
delay(20);
Send_buf[0] = 0x7e; //starting byte
Send_buf[1] = 0xff; //version
Send_buf[2] = 0x06; //the number of bytes of the command without starting byte and ending byte
Send_buf[3] = command; //
Send_buf[4] = 0x00; //0x00 = no feedback, 0x01 = feedback
Send_buf[5] = (int8_t)(dat >> 8); //datah
Send_buf[6] = (int8_t)(dat); //datal
Send_buf[7] = 0xef; //ending byte
for (uint8_t i = 0; i < 8; i++) {
mySerial.write(Send_buf[i]) ; //send bit to serial mp3
Serial.print(Send_buf[i], HEX); //send bit to serial monitor in pc
Serial.print(" ");
}
Serial.println();
}
long measureDistance(int trigger, int echo) {
long duration, distance;
digitalWrite(trigger, LOW); //PULSE ___|---|___
delayMicroseconds(2);
digitalWrite(trigger, HIGH);
delayMicroseconds(10);
digitalWrite(trigger, LOW);
duration = pulseIn(echo, HIGH);
distance = (duration / 2) / 29.1;
Serial.print("distance: ");
Serial.println(distance);
return distance;
}
Je pense que tu as intérêt à utiliser cette commande : le 01 correspond au répertoire dans lequel sont rangés les fichiers. Si on met 00, il s'emmêle et loupe des tracks.
Le problème est identifié ailleurs. Il indique un site où on peut télécharger une autre bilbiothèque avec une commande simple pour lire une track :