Boite à sons

Bonjour tout le monde,

Voilà je me présente moi c’est Olivier j’ai 45 ans, marié et 3 enfants dont un qui veux réaliser un projet de boite à sons “Star War” pour son jeux de figurine SW Légion.

Je lui ai dis qu’il serait possible de le faire avec une carte Arduino et un lecteur DFplayer et quelques bouton poussoir ^^…Et me voilà avec tous les matériels !

Nous avons fait et testé un petit câblage simple avec 3 boutons (next/pause/previous) et un code simpliste sur le net pour jouer les fichiers wav de la carte SD. Tout fonctionne à merveille MAIS, parce qu’il y a un mais, j’ai fabriqué une boite avec 12 bouton poussoirs et on voudrait faire jouer 1 son aléatoire d’un dossier pour chaque bouton ni plus ni moins…

Après plusieurs test de code trouvé ici et là sur le net, rien ne correspond vraiment soit c’est trop compliqué soit pas assez.

Je n’ai aucune connaissance en programmation (à part Scratch ^^) mais j’ai une certaine logique, mon fils n’a que 13 ans et la programmation c’est inconnu aussi.

J’aurais besoin de votre aide ou un début de piste à explorer (code) pour le code.

En vous remerciant

postez le code fonctionnel que vous aviez trouvé avec 3 boutons

voici ce qui marche, mais c’est juste un play/pause/next/previous, mais moi je cherche juste à faire lire un son par bouton (12 bouton de prévus)

 // ///              MP3 PLAYER PROJECT
/// http://educ8s.tv/arduino-mp3-player/
//////////////////////////////////////////


#include "SoftwareSerial.h"
SoftwareSerial mySerial(10, 11);
# define Start_Byte 0x7E
# define Version_Byte 0xFF
# define Command_Length 0x06
# define End_Byte 0xEF
# define Acknowledge 0x00 //Returns info with command 0x41 [0x01: info, 0x00: no info]

# define ACTIVATED LOW

int buttonNext = 2;
int buttonPause = 3;
int buttonPrevious = 4;
boolean isPlaying = false;



void setup () {

  pinMode(buttonPause, INPUT);
  digitalWrite(buttonPause, HIGH);
  pinMode(buttonNext, INPUT);
  digitalWrite(buttonNext, HIGH);
  pinMode(buttonPrevious, INPUT);
  digitalWrite(buttonPrevious, HIGH);

  mySerial.begin (9600);
  delay(1000);
  playFirst();
  isPlaying = true;


}



void loop () {

  if (digitalRead(buttonPause) == ACTIVATED)
  {
    if (isPlaying)
    {
      pause();
      isPlaying = false;
    } else
    {
      isPlaying = true;
      play();
    }
  }


  if (digitalRead(buttonNext) == ACTIVATED)
  {
    if (isPlaying)
    {
      playNext();
    }
  }

  if (digitalRead(buttonPrevious) == ACTIVATED)
  {
    if (isPlaying)
    {
      playPrevious();
    }
  }
}

void playFirst()
{
  execute_CMD(0x3F, 0, 0);
  delay(500);
  setVolume(20);
  delay(500);
  execute_CMD(0x11, 0, 1);
  delay(500);
}

void pause()
{
  execute_CMD(0x0E, 0, 0);
  delay(500);
}

void play()
{
  execute_CMD(0x0D, 0, 1);
  delay(500);
}

void playNext()
{
  execute_CMD(0x01, 0, 1);
  delay(500);
}

void playPrevious()
{
  execute_CMD(0x02, 0, 1);
  delay(500);
}

void setVolume(int volume)
{
  execute_CMD(0x06, 0, volume); // Set the volume (0x00~0x30)
  delay(2000);
}

void execute_CMD(byte CMD, byte Par1, byte Par2)
// Excecute the command and parameters
{
  // Calculate the checksum (2 bytes)
  word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
  // Build the command line
  byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
                            Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte
                          };
  //Send the command line to the module
  for (byte k = 0; k < 10; k++)
  {
    mySerial.write( Command_line[k]);
  }
}

pour simplifier comme j'ai une arduino uno je pense faire avec 10 boutons (piste 2,3,4,5,6,7,8,9,12 et 13)

Merci de lire les règles du forum SVP

corrigez votre post ci dessus et rajoutez les code tags autour du code:
[code]`` [color=blue]// votre code ici[/color] ``[/code].

ça doit ressembler à cela:// votre code ici
(faites aussi ctrl-T (PC) or cmd-T (Mac) dans l'IDE avant de copier le code pour qu'il soit indenté correctement)

——————

Si c'est pour jouer un son aléatoire, pourquoi avoir 12 boutons ? un seul suffit non ?

Sinon vous avez du code plus abouti ici au dessus d'une bibliothèque qui devrait vous simplifier la vie, avec quelques commandes pour la gestion des dossiers

Pour simplifier votre gestion des boutons, éventuellement utilisez la librairie de @bricoleau

désolé c'est modifié

En fait sur une console j'aurais mes 10 boutons, chaque bouton sera nommé sur le panel (ex: bouton 1 --> explosion; bouton 2 ---> laser;...) et lorsqu'on appui sur un bouton cela déclenchera un son correspondant voir un son aléatoire d'une banque sonore.

Sur ma carte SD j'ai préparé les 10 dossiers (01, 02, 03,...) où dedans j'ai ajouté un son (0001.wav, 0002wav,...)

je vais regarder du coté de la librairie simplebouton dans un 1er temps

Merci

Bon je suis vraiment nul en programmation et j'y comprends pas grand chose au final...

En me servant du code fullfonction de DfRobot qui pourrait correspondre à ce que je cherche, c'est sur la partie MP3 play qu'il faut que je programme mes boutons poussoirs, mais je ne sais pas le faire (notamment la fonction MyDFPlayer.playMp3Folder

 //----Mp3 play----
  myDFPlayer.next();  //Play next mp3
  delay(1000);
  myDFPlayer.previous();  //Play previous mp3
  delay(1000);
  myDFPlayer.play(1);  //Play the first mp3
  delay(1000);
  myDFPlayer.loop(1);  //Loop the first mp3
  delay(1000);
  myDFPlayer.pause();  //pause the mp3
  delay(1000);
  myDFPlayer.start();  //start the mp3 from the pause
  delay(1000);
  myDFPlayer.playFolder(15, 4);  //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255)
  delay(1000);
  myDFPlayer.enableLoopAll(); //loop all mp3 files.
  delay(1000);
  myDFPlayer.disableLoopAll(); //stop loop all mp3 files.
  delay(1000);
  myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535)
  delay(1000);
  myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535)
  delay(1000);
  myDFPlayer.stopAdvertise(); //stop advertise
  delay(1000);
  myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000)
  delay(1000);
  myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05.
  delay(1000);
  myDFPlayer.randomAll(); //Random play all the mp3.
  delay(1000);
  myDFPlayer.enableLoop(); //enable loop.
  delay(1000);
  myDFPlayer.disableLoop(); //disable loop.
  delay(1000);

Voilà si vous vous sentez de me faire comprendre, je suis tout ouïe ^^

  myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535)

Je ne vois pas où est la difficulté. playMp3Folder(4) permet d'écouter le morceau N°4 du répertoire nommé MP3.

Mais cela ne correspond pas à la description :

Sur ma carte SD j'ai préparé les 10 dossiers (01, 02, 03,...) où dedans j'ai ajouté un son (0001.wav, 0002wav,...)

Jouer un morceau au hasard d'un répertoire donné sera impossible de toutes façons.

Si un bouton parmi N permet de choisir un répertoire de 1 à N, il faudra faire cela toi-même :

  • appelons le répertoire choisi X
  • déterminer le nombre de morceaux M du répertoire X à l'aide de readFileCountsInFolder(X)
  • générer un nombre aléatoire Y à l'aide de random(1, M+1)
  • jouer le morceau à l'aide de playFolder(X, Y)

Super et vraiment merci à vous de votre patience ^^

Donc on va juste faire super simple pour commencer et jouer un seul son par bouton...

je reprends le code FullFonction de DFrobot et je n'utilise que la ligne ci dessus pour joue le son, mais comment modifié le code pour appliquer cette ligne à un bouton ?

Je vous joins le schema de cablage

mes boutons sont sur les pin 3,4,5,6,7,8,9,12 et 13 de la carte arduino Uno

pour mon schema

pour mon projet je voudrais arriver à cela mais avec moins de boutons

et le code sur cette vidéo est celui-ci

 //#include <Arduino.h>

#define BUTTON_COUNT 36
#define KEYPAD_OUTPUT_BEGIN 2
#define KEYPAD_OUTPUT_END 7
#define KEYPAD_INPUT_BEGIN 8
#define KEYPAD_INPUT_END 13



uint8_t keypad_button_pressed[BUTTON_COUNT];
volatile uint32_t ticks;
uint32_t lastTrigger, lastTriggerFrontButton;



uint8_t index = 1;
uint8_t volume = 25;

//uint8_t cmd_01[10]       = {0x7E, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x01, 0xFF, 0xE6, 0xEF};
uint8_t cmd_play_num[10] = {0x7E, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x01, 0xFF, 0xE6, 0xEF};
//uint8_t cmd_next[10]     = {0x7E, 0xFF, 0x06, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xE6, 0xEF};
uint8_t cmd_stop[10]     = {0x7E, 0xFF, 0x06, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF};
uint8_t cmd_set_vol[10]  = {0x7E, 0xFF, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF};


ISR(TIMER0_COMPA_vect, ISR_BLOCK) {
	ticks++;
}

void init_systicks() {

	TCCR0B = _BV(CS02) | _BV(CS00);
	TCCR0A = _BV(WGM01);
	TIMSK0 = _BV(OCIE0A);

	// 8000000/1024/78 == 100HZ -> 10 ms
	OCR0A = 77; // !!! must me set last or it will not work!
}

uint32_t math_calc_diff(uint32_t value1, uint32_t value2) {
	if (value1 == value2) {
		return 0;
	}
	if (value1 > value2) {
		return (value1 - value2);
	}
	else {
		// check for overflow
		return (0xffffffff - value2 + value1);
	}
}


void keypad_reset_output() {
	// configure pull ups
	digitalWrite(2, HIGH);
	digitalWrite(3, HIGH);
	digitalWrite(4, HIGH);
	digitalWrite(5, HIGH);
	digitalWrite(6, HIGH);
	digitalWrite(7, HIGH);
}

void clear_buttons() {
	for(int i=0; i < BUTTON_COUNT; i++) {
		keypad_button_pressed[i] = 0;
	}
}

void keypad_setup() {
	// initialize the digital pin as an output:
	pinMode(2, OUTPUT);
	pinMode(3, OUTPUT);
	pinMode(4, OUTPUT);
	pinMode(5, OUTPUT);
	pinMode(6, OUTPUT);
	pinMode(7, OUTPUT);

	keypad_reset_output();

	pinMode(8, INPUT);
	pinMode(9, INPUT);
	pinMode(10, INPUT);
	pinMode(11, INPUT);
	pinMode(12, INPUT);
	pinMode(13, INPUT);

	// configure pull ups
	digitalWrite(8, HIGH);
	digitalWrite(9, HIGH);
	digitalWrite(10, HIGH);
	digitalWrite(11, HIGH);
	digitalWrite(12, HIGH);
	digitalWrite(13, HIGH);
}



// the loop() method runs over and over again,
// as long as the Arduino has power

void keypad_read_buttons() {
	clear_buttons();
	uint8_t y=0;
	for(int i=KEYPAD_OUTPUT_BEGIN; i <= KEYPAD_OUTPUT_END; i++) {
		keypad_reset_output();
		digitalWrite(i, LOW);
		uint8_t x=0;
		for(int j=KEYPAD_INPUT_BEGIN; j <= KEYPAD_INPUT_END; j++) {
			if (digitalRead(j) == LOW) {
				uint8_t index = x+6*y;
				keypad_button_pressed[index] = 1;
			}
			x++;
		}
		y++;
	}
}


uint8_t keypad_button_is_pressed() {
	for (int i=0; i < BUTTON_COUNT; i++) {
		if (keypad_button_pressed[i]) {
			return 1;
		}
	}
	return 0; // no button pressed
}


void send_cmd(uint8_t* cmdbuf) {
	//calc checksum (1~6 byte)
	uint16_t sum = 0;
	for (int i=1; i<7; i++) {
		sum += cmdbuf[i];
	}
	sum=-sum;
	cmdbuf[7] = sum >> 8;
	cmdbuf[8] = sum & 0xFF;
	Serial.write(cmdbuf, 10);
	/*
	for(int i=0; i < 10;i++) {
		Serial.print((char) cmd[i]);
	}*/
	// print(char*) will not work due to 0-termination
	//Serial.print((char*) cmd);
}

void play_track(uint8_t num) {
	cmd_play_num[6] = num;
	send_cmd(cmd_play_num);
}

void set_volume() {
	cmd_set_vol[6] = volume;
	send_cmd(cmd_set_vol);
}

// The setup() method runs once, when the sketch starts
void setup() {
	init_systicks();
	keypad_setup();

	// setup stop, vol down, vol up buttons
	pinMode(A0, INPUT);
	pinMode(A1, INPUT);
	pinMode(A2, INPUT);
	digitalWrite(A0, HIGH);
	digitalWrite(A1, HIGH);
	digitalWrite(A2, HIGH);


	Serial.begin(9600);
}

// the loop() method runs over and over again,
// as long as the Arduino has power

void loop() {

	keypad_read_buttons();

	// allow button processing only every 300ms (30 systicks)
	if (keypad_button_is_pressed() && (math_calc_diff(ticks, lastTrigger) > 30)) {
		lastTrigger = ticks;

		for(int i=0; i < BUTTON_COUNT; i++) {
			if (keypad_button_pressed[i]) {
				play_track(i+1);
				break;
			}
		}
	}


	if (math_calc_diff(ticks, lastTriggerFrontButton) > 15) {
		lastTriggerFrontButton = ticks;
		// stop button
		if (digitalRead(A0) == LOW) {
			// send stop
			send_cmd(cmd_stop);
		}
		if (digitalRead(A1) == LOW) {
			// send vol down
			if (volume > 1) {
				volume--;
				set_volume();
			}
		}
		if (digitalRead(A2) == LOW) {
			// send vol up
			if (volume < 30) {
				volume++;
				set_volume();
			}
		}
	}
	delay(1);
}

int main(void) {

	init();
	setup();

	set_volume();
	while (true) {
		loop();
	}
}

Pourquoi pars-tu d'un machin aussi compliqué ?
L'auteur utilise un clavier matriciel.

Un bouton se lit avec digitalRead().
Je te conseille un câblage entre entrée et GND, avec :
pinMode(pin, INPUT_PULLUP); // pour chaque bouton

La logique sera inversée : ZERO = bouton appuyé

mes boutons sont sur les pin 3,4,5,6,7,8,9,12 et 13 de la carte arduino Uno

13 : c'est la pin de la LED de la carte. Évite, elle peut servir à autre chose.

Lis les boutons à tour de rôle avec digitalRead() et joue le premier morceau du répertoire.

Non je ne veux pas partir d'un code aussi complexe, mais j'essaye de comprendre à partir de projet qui ont été terminés et qui fournissent généreusement leur code, mais c'est trop dur pour moi...

Par manque de temps je n'ai que très peu de base en arduino, mais je ne vais pas avoir le choix car même si cela semble simple pour toi, moi c'est autre chose ^^

Malheureusement, sans temps, en informatique on ne fait pas grand chose.

Sans vouloir t'embrouiller, je voudrais juste préciser que la fonction random() n'est pas si aléatoire que ça.
J'en ai fait l'expérience en construisant un mémory sonore qui associait "alétoirement" des paires de son à des touches. Le résultat était qu'à chaque nouveau jeu, j'obtenais bien une distribution différente mais la énième distribution à partir d'une réinitialisation de l'arduino était toujours la même...
Donc à mon avis, de deux choses l'une :

  • soit le côté aléatoire n'est pas si important et on peut simplifier le code
  • soit il faut utiliser l'horloge ou le bruit de fond d'une broche libre de l'arduino pour générer un chiffre un peu plus aléatoire

randomseed()

Mais n'allons pas trop vite ...

Bon j’avance à petit pas et j’ai peut-être trouvé un code qui fonctionne, en tout cas apres compilation et formatage il n’y a aucune erreur c’est déjà ça ^^

J’ai fais avec 6 boutons dans un 1er temps avec 6 fichiers sons mp3 déposés sur la carte SD dans un dossier nommé “mp3” et nommés respectivement 0001.mp3, etc…

le soucis c’est que je n’entend pas les sons quand j’appuis sur les boutons, où se trouve mon problème ?

je vous met mon code :

//#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"



#define inter 2 //pull-up IN
#define button1 3 //pull-up IN
#define button2 4 //pull-up IN
#define button3 5 //pull-up IN
#define button4 6 //pull-up IN
#define button5 7 //pull-up IN
#define button6 8 //pull-up IN
volatile unsigned long button_time = 0;
int debounce = 50; // debounce latency in ms

volatile int trigger = 0;//Les variables boutons pour l'interruption
int total = 0;
int inta = 0;
int intb = 0;
int intc = 0;
int intd = 0;
int inte = 0;
int intf = 0;

///////////////MP3DFPlayer
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

int plagemp3 = 1;

void setup() {



  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);


  //////////SETUP BOUTONS INTERRUPTIONS//////////////
  initPins();

  attachInterrupt(0, detect, FALLING);


  //////////////SETUP MP3/////////////////////////////////

  mySoftwareSerial.begin(9600);
  Serial.begin(9600);

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while (true);
  }
  Serial.println(F("DFPlayer Mini online."));

  myDFPlayer.volume(20);  //Set volume value. From 0 to 30
  myDFPlayer.setTimeOut(500);


  ////////////////////////FIN SETUP MP3/////////////////

}

void loop() {




  if (trigger != 0) {
    total++;

    if (trigger == 1) {
      inta++;
      plagemp3 = 1; ;
      myDFPlayer.play(plagemp3);
    };
    if (trigger == 2) {
      intb++;
      plagemp3 = 2;
      myDFPlayer.play(plagemp3);
    };
    if (trigger == 3) {
      intc++;
      plagemp3 = 3;
      myDFPlayer.play(plagemp3);
    };
    if (trigger == 4) {
      intd++;
      plagemp3 = 4;
      myDFPlayer.play(plagemp3);
    };
    if (trigger == 5) {
      inte++;
      plagemp3 = 5;
      myDFPlayer.play(plagemp3);
    };
    if (trigger == 6) {
      intf++;
      plagemp3 = 6;
      myDFPlayer.play(plagemp3);
    };
    Serial.print(plagemp3);
    Serial.print(" |-n°MP3-| ");
    Serial.print(total);
    Serial.print(" || ");
    Serial.print(inta);
    Serial.print(" | ");
    Serial.print(intb);
    Serial.print(" | ");
    Serial.print(intc);
    Serial.print(" | ");
    Serial.print(intd);
    Serial.print(" | ");
    Serial.print(inte);
    Serial.print(" | ");
    Serial.println(intf);
    trigger = 0;


  }
  /////////////MSG LOOP MP3////////////
  if (myDFPlayer.available()) {
    printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
  }




}

void detect() {
  if (button_time > millis()) return;
  delayMicroseconds(56000);
  if (!digitalRead(button1)) trigger = 1;
  if (!digitalRead(button2)) trigger = 2;
  if (!digitalRead(button3)) trigger = 3;
  if (!digitalRead(button4)) trigger = 4;
  if (!digitalRead(button5)) trigger = 5;
  if (!digitalRead(button6)) trigger = 6;
  button_time = millis() + debounce;
}





////////////////MESSAGES DU MP3DFPLAYER///////////////////////////
void printDetail(uint8_t type, int value) {
  switch (type) {
    case TimeOut:
      Serial.println(F("Time Out!"));
      break;
    case WrongStack:
      Serial.println(F("Stack Wrong!"));
      break;
    case DFPlayerCardInserted:
      Serial.println(F("Card Inserted!"));


      ////////////////////////////////////////////////////////
      Serial.print(F("Number:"));
      Serial.print(value);
      Serial.println(F(" Play Finished!"));
      break;
    case DFPlayerError:
      Serial.print(F("DFPlayerError:"));
      switch (value) {
        case Busy:
          Serial.println(F("Card not found"));
          break;
        case Sleeping:
          Serial.println(F("Sleeping"));
          break;
        case SerialWrongStack:
          Serial.println(F("Get Wrong Stack"));
          break;
        case CheckSumNotMatch:
          Serial.println(F("Check Sum Not Match"));
          break;
        case FileIndexOut:
          Serial.println(F("File Index Out of Bound"));
          break;
        case FileMismatch:
          Serial.println(F("Cannot Find File"));
          break;
        case Advertise:
          Serial.println(F("In Advertise"));
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }

}



// INIT PINS
void initPins() {
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);
  pinMode(button5, INPUT);
  pinMode(button6, INPUT);
  pinMode(inter, INPUT);
  //pinMode(led, OUTPUT);
  digitalWrite(button1, HIGH);
  digitalWrite(button2, HIGH);
  digitalWrite(button3, HIGH);
  digitalWrite(button4, HIGH);
  digitalWrite(button5, HIGH);
  digitalWrite(button6, HIGH);
  digitalWrite(inter, HIGH);

}

Il semblerait que ce code utilise un inter (probablement un bouton poussoir) et 6 boutons, et que la lecture soit déclenchée par l'appui simultané sur l'inter et un bouton.
Est-ce bien ce que tu as testé ?

oui effectivement le gars qui avait fait ce montage, avait fait aussi un interrupteur à glissière au niveau de l'alimentation 5v de la carte Arduino, moi au final j'en aurait pas besoin car j'utiliserais un accu li-ion de 3,7v comme alimentation

Donc il faudrait que je supprime ces lignes de code relative à l'interrupteur ?

Oui, mais il faudra appeler la fonction detect() en début de loop().