Différences entre les versions de « LogClock & Cuckoo »

De Wiki LOGre
Aller à la navigation Aller à la recherche
Ligne 65 : Ligne 65 :
====Changement de modes en dynamique====
====Changement de modes en dynamique====


J’ai associé micro switch et un potentioètre pour :
J’ai associé micro switch et un potentiomètre pour :
*Le volume du son (fort/réduit) après un appui long sur le switch (la diode s'allume pour valider le fait qu'on est dans le mode réglade de volume)
*Le volume du son (fort/réduit) après un appui long sur le switch (la diode s'allume pour valider le fait qu'on est dans le mode réglade de volume)
*Le changement de mode de l'audio, machine à 3 états effectué sur appui court sur le switch (la diode clignote 3 fois rapidement pour valider le changement de mode)
*Le changement de mode de l'audio, machine à 3 états effectué sur appui court sur le switch (la diode clignote 3 fois rapidement pour valider le changement de mode)

Version du 21 juin 2016 à 05:58


Encore un projet néo-ringard : la LOGre Clock & Cuckoo

Genèse

Dans la tonne de vieilleries données au LOGre, figuraient deux énormes vumètres (un Voltmètre et un Ampèremètre) et toujours de nombreux vumètres Pekly de tailles plus raisonnables. Ayant déjà le GalvaCuckoo à la maison, il fallait trouver un lieu d'accueil pour ces vumètres destinés à la casse. J'ai donc décidé d'offrir une (autre) horloge au LOGre qui possède déjà une JIX Clock. Combat des technologies : le 19ème siècle contre le 21ème !!

Donc les deux gros galvanomètres seront dédiés aux heures et minutes, que faire d'original pour afficher les secondes ? L'idée retenue est de simuler le mieux possible la rotation d'une trotteuse d'une montre. Ce fut rapidement fait en installant deux galva en tête-bêche, l'un ayant une aiguille tournant dans le sens horaire de 0 à 30 secondes, et l'autre la tête en bas, prenant le relais à la trentième seconde avec une aiguille allant de 30 à 60 secondes !

Une fois l'heure affichée, que pouvait-on faire ? j'ai donc repris l'idée du coucou suisse, agrémenté du carillon de Westminster à midi et de BigBen à minuit. Et comme j'avais un lecteur de fichiers mp3, je complète les fonctions avec divers modes de diffusion de musique d'ambiance (séquentiel, aléatoire).


LOGre Clock & Cuckoo.jpg

Matériel nécessaire

  • un arduino Nano  : 1,80 € chez AliExpress
  • une horloge temps réel Dallas Semiconductor DS1307 (sauvegardée par batterie) : 0,76 € chez AliExpress
  • un module de lecture de fichiers audio (FN-M16P) : 1,95 € chez AliExpress
  • une carte SD 4GB : 1,78 € chez AliExpress
  • quelques composants : résistances, potentiomètres, diode, switch : 0 € (récupération)

Soit une horloge pour 6,29 € !!

Transformation des galvanomètres

Petit rappel grâce à wikipedia:

Un galvanomètre à cadre mobile, est constitué d'une bobine montée sur pivot, baignant dans le champ magnétique d'un aimant fixe. S ur cette bobine est fixée l'aiguille de visualisation et un ressort chargé de rappeler l'équipage mobile dans la position indiquant le zéro. La bobine de faible impédance est branchée en série dans le circuit dans lequel circule le courant à mesurer (ou le courant de commande dans mon cas). Le courant, en traversant la bobine, induit dans celle-ci un champ électromagnétique, ce qui provoque un pivotement par répulsion des champs magnétiques. Plus le courant est intense plus la bobine bascule. Il ne fonctionne qu'en courant continu.

Dans le stock donné, je trouve des voltmètres et ampèremètres, donc il faut les adapter pour les faire fonctionner avec les sorties PWM de l'Arduino.

C'est en fait très simple, il faut trouver la bonne valeur de la résistance interne à insérer avant la bobine pour que la valeur 255 (Vcc) de l'analogWrite soit au maximum de l'échelle. Je perce le corps du galva et insère (colle) un micro potentiomètre de 47kohms qui sera réglé in situ.

Restait à imprimer les écrans gradués en H, Mn et Secondes. Merci à Pekly, il y avait des écrans nativement gradués en 15 graduations (donc pour les heures) et en 300 pour les 60 minutes. Avec Pixelmator (photoshop pour Mac), ce fut très simple. Quant à celui des secondes, il était déjà gradué de 0 à 60, il ne restait qu’à imprimer les valeurs et l’unité de mesure !!


Migration d'une horloge de base vers un coucou suisse.

Par rapport à mon premier projet, j'ai opté pour un module mp3 plus petit, pilotable via une liaison série pilotée par le Nano. Ce fut épique car le module est mal documenté, le module est buggué et quelques nuléros de pistes ne fonctionnent pas !!! On s'y fait et on conctourne le bug. Finalement je peux sélectionner la piste à jouer et c'est récurrent.

Horloge temps réel

Module RTC à base de DS1307 et fonctionnant sur BUS I2C. Avec l'utilisation de la bibliothèque adaptée (Wire.h) et les exemples du playground Arduino, pas de problèmes particuliers.


Expérimentation

j'ai repris globalsment le code du GalvaCuckoo. Ce fut le plus facile.

Ensuite, modification des galvanomètres; Pas trop compliqué sauf que les aiguilles sont très fragiles. En effet, un galva s'est retrouvé privé d'aiguille. Avec les sorties PWM, pas de problèmes pour afficher l'heure sur les galva.

l'utilisation du nouveau module mp3 ne réserve pas de ports digitaux, notamment des PWM, du coup, les sortie PWM sont utilisées nativement.

Affichage AM/PM

Pas de diodes WS2812 ce coup-ci, mais une diode rouge insérée dans le cadran des heures au niveau du 0h pour le AM et une diode verte au niveau du 15heures pour afficher PM. L'afficheur des heures va de 0 à 13 heures (mon choix !!!). A minuit les deux diodes (AM & PM) sont allumées.

Changement de modes en dynamique

J’ai associé micro switch et un potentiomètre pour :

  • Le volume du son (fort/réduit) après un appui long sur le switch (la diode s'allume pour valider le fait qu'on est dans le mode réglade de volume)
  • Le changement de mode de l'audio, machine à 3 états effectué sur appui court sur le switch (la diode clignote 3 fois rapidement pour valider le changement de mode)
    • Etat 00 : tic tac d'horloge comtoise, coucou, Bigben...
    • Etat 01 : musique d'ambiance en mode séquentiel (aujourd'hui 60 titres, max à 255)
    • Etat 02 : musique d'ambiance en mode aléatoire (aujourd'hui 60 titres, max à 255)

Fonctionnement

A la mise sous tension, l'heure est lue à partir du DS1307:

  • A chaque heure, le coucou chante (autant de fois que l'heure pour les non voyants)
  • A 12 heures, c’est le carillon de Westminster (1 fois)
  • A minuit, sonnent les 12 coups de BigBen.

Petite singularité, l’horloge va de 1 AM à 13:59 heures et de 2PM à 24:59 !! C’est ma norme !!

Evolution

  • Pour changer les types de sonnerie, il suffit de remplacer les pistes audio existantes (001 à 005.mp3) par de nouvelles sur la carte microSD.

On peut rajouter également des plages musicales si celles choisies ne plaisent plus.

  • Si j'arrive à maitriser l'ESP8266, j'aimerai en ajouter un au projet pour ajuster l'heure à partir du réseau Wifi du LOGal et d'autres fonctions de pilotage...

Schéma de connexion

    • à faire !

Code arduino

C'est la version 0.3, restent quelques améliorations, simplifications à faire. L'important est que ça marche et que j'ai pris un grand plaisir à le faire.

/* LOGre Clock
 * version 0.3
 * with RTC + MP3 module + volume control + playing mode switching
 * 0 = tictac
 * 1 = sequential
 * 2 = random between limits
 * by Pja - LOGre - Grenoble
 * June 2016
 */
 
#include "Wire.h"               // used for Real Time Clock
#include <SoftwareSerial.h>     // used for MP3 module
#include <EEPROM.h>             // used for EEPROM management

//#define VERBOSE               // for display date and time on terminal
//#define reglage               // bool to switch for adjusting mode

// param for RTC
#define DS1307_I2C_ADDRESS 0x68 // This is the I2C address
#define I2C_WRITE Wire.write 
#define I2C_READ Wire.read

// define Arduino Pins - PWM
#define SecondS0030 6   //  PWM: lower meter for Seconds from 0 to 30
#define SecondS3060 5   //  PWM: lower meter for Seconds from 30 to 60
#define MinuteS     10  //  PWM: middle meter for Minutes
#define HourS       9   //  PWM: top meter for Hour
#define AnteM       7   //  bin: led AM
#define PostM       8   //  bin: led PM
#define VolumLED    2   // LED display : flashing when RandomMode validated (short push
                        // steady light for volume settings when push more than 1 sec                      
#define Button_INT  3   // interrupt
#define FreeForPlaying  A0  // (used as digital input) status of mp3 player (hi = free, Lo = playing)
#define Potar           A1  // analog value for audio volume read from potentiometer

// define message for MP3 module
# define Start_Byte     0x7E
# define Version_Byte   0xFF
# define Command_Length 0x06
# define End_Byte       0xEF
# define Acknowledge    0x00  //Returns no info
#define EQrock          2
#define EQJazz          3
#define EQClassic       4
#define EQPop           1

# define tictac           1   //001.mp3
# define shime            3   //002.mp3
# define coucou           4   //003.mp3
# define bigbenmidnight   5   //004.mp3


int EE_addr;              //adresse EEPROM for volume storage
byte Second, Minute, Hour, dayOfWeek, dayOfMonth, Month, Year, curSec, curHour;
String stringValeur ;
boolean isFreeForPlaying = false;  // status of the MP3 player 
int  VolumeLevel;         //  MP3 player intern volume settings
bool TicTic = true;       // boolean, when true >> tictac is playing
bool madCuckoo=true;      // boolean, when true >> cuckoo strikes as many times as Hour, when false only one time       
int  done_once = 0, RingType, repeat;
int  last_track_played=0;  // just to remember which tracks was played to avoid to be played twice
bool VolumeSetting = false;  // bool to start volume settings
boolean EasyMusicOn = false;   // request to play mp3 tracks as Easy Music player
bool RandomOn = false;      // bool for easy music listening in random mode
bool SequentialOn = false;    // bool for easy music listening in sequential mode
int  VolumePotar;           // value read at pot level
byte ModeStatus = 0x00;     // state machine (0=ticrac, 1 = random, 2=sequential)
int  LimBasse = 8, LimHaute = 68 ;
int  NextTrack = 0;         // init at 0 for first sequential trip

#ifdef VERBOSE
  byte Weekday = 0;
  byte Monthday = 0;
  const char* days[] =
  {"","Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
  const char* Months[] =
  {"","January", "February", "March", "April", "May", "June", "July", "August","September", "October", "November", "December"};
#endif
// create instance for Software Serial
SoftwareSerial mySerial(12,11);   //Rx, Tx  on my Nano

// init
void setup() {
  EE_addr = 0;
  VolumeLevel = EEPROM.read(EE_addr);
  if(VolumeLevel==0) VolumeLevel+=10;
  delay(1000);
  Wire.begin();
  Serial.begin(9600);
  // init pins
  pinMode(SecondS0030, OUTPUT);         
  pinMode(SecondS3060, OUTPUT);         
  pinMode(MinuteS, OUTPUT);  
  pinMode(HourS, OUTPUT);
  pinMode(AnteM, OUTPUT);
  pinMode(PostM, OUTPUT);
  pinMode(VolumLED, OUTPUT);   // LED on if Volume Setting mode
  pinMode(Button_INT, INPUT);
  digitalWrite(VolumLED, HIGH);  // status led off
  pinMode(isFreeForPlaying, INPUT);
  pinMode(Potar, INPUT);
  // init meters
  analogWrite(HourS,0);  
  analogWrite(MinuteS,0);      
  analogWrite(SecondS0030, 0);         
  analogWrite(SecondS3060, 0);  
  // attach interrupt on pin D3
  attachInterrupt(digitalPinToInterrupt(3), Switch_Mode, RISING);  // interrupt 0 on pin D3
  // init module mp3
  mySerial.begin (9600);
  delay(500);
  resetMP3();
  //delay(500);
  setVolume(VolumeLevel);           // init volume at value in EEPROM or 10 by default
  //delay(500);
  setEqualizer(EQrock);
  //delay(500);
  isFreeForPlaying =  getStatusPlaying();  // 
  //---
  #ifdef VERBOSE
    Serial.println(F("GLOGre Clock - Patrick version 0.3 "));
    Serial.print(F("Module audio ready ? "));Serial.println(isFreeForPlaying);
  #endif
  curSec=61;              // init
  curHour=25;             // init
  #ifdef  reglage
   Serial.println(F("Enter value 0 to 255 "));
  #endif
  ForceTicking();  // start tictac for the first time before synchronize with Second=0
}

void loop() 
{
// ===================
#ifdef  reglage
{
  reglage_afficheur();   //commenter le reste et décommenter réglage
}
#else
// ===================
{
 getDateDs1307();           // acquire time several times per Second
    
 if(curSec!=Second)
    {        // only once per Second
    DisplayOnMeter();                         // display time on meters
    isFreeForPlaying =  getStatusPlaying();   // update of status each Seconde
    switch (ModeStatus) 
      {
      case 0:    // tictac mode
        SingTime();             // sing a song each round Hour
        Ticking();              // Seconds are Ticking if requested
        break;
      case 1:   // Sequential Mode
        if(isFreeForPlaying==true) PlaySequential(); 
        break;
      case 2:   // Random Mode
        if(isFreeForPlaying==true) PlayRandom(); 
        break;
      default: 
        delay(1); // if nothing else matches, do the default
      }
    curSec=Second;          // change flag to display once per Second
    #ifdef VERBOSE
        printHour();      // display each Second on terminal when verbose
     // getValue();     // used during dev and maintenance
    #endif
    }
}
#endif
//==================
}

// ------ subroutines ---

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ((val/16*10) + (val%16));
}

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ((val/10*16) + (val%10));
}

// Get the date and time from the ds1307
void getDateDs1307()
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(byte(0));
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  Second = bcdToDec(Wire.read());
  Minute = bcdToDec(Wire.read());
  Hour = bcdToDec(Wire.read());
  #ifdef VERBOSE
    dayOfWeek = bcdToDec(Wire.read());
    dayOfMonth = bcdToDec(Wire.read());
    Month = bcdToDec(Wire.read());
    Year = bcdToDec(Wire.read());
  #endif
}

#ifdef VERBOSE
void printHour()   // sur terminal
{
  if (Hour < 10) Serial.print("0");
  Serial.print(Hour, DEC);
  Serial.print(":");
  if (Minute < 10) Serial.print("0");
  Serial.print(Minute, DEC);
  Serial.print(":");
  if (Second < 10) Serial.print("0");
  Serial.print(Second, DEC);
  Serial.print("  ");
  Serial.print(days[dayOfWeek]);
  Serial.print(", ");
  Serial.print(dayOfMonth, DEC);
  Serial.print(" ");
  Serial.print(Months[Month]);
  Serial.print(" 20");
  if (Year < 10) Serial.print("0");
  Serial.println(Year, DEC);  
}
#endif

void DisplayOnMeter()
{   // specific case to reset meters at their zero (especially for the lower meter)
    if(Second==0) 
      {
      analogWrite(SecondS0030,0);
      analogWrite(SecondS3060,0);
      }
    // display Seconds
    if(Second<=30)
      {analogWrite(SecondS0030,map(Second,0,30,0,255));
      analogWrite(SecondS3060,0);}
    else
      {analogWrite(SecondS3060,map(Second-30,0,30,0,255));
      analogWrite(SecondS0030,255);}
    // display Minutes
    analogWrite(MinuteS,map(Minute,0,60,0,255));
    // display Hours with 0-13 format
    int temp_Hours;
    temp_Hours =  Hour;
    if(temp_Hours > 12 & temp_Hours <= 23)
       { 
       digitalWrite(AnteM,LOW);
       digitalWrite(PostM,HIGH);
       temp_Hours = temp_Hours - 12; 
       } 
    else
       {
        digitalWrite(AnteM,HIGH); // my choice is to display until 13 for 1PM
        digitalWrite(PostM,LOW);
        }
    if(temp_Hours == 0)  // trick for midnight, display 12 instead of 0 !
       {
        temp_Hours = 12;
        digitalWrite(PostM,HIGH);
        digitalWrite(AnteM,LOW);
        }
    analogWrite(HourS,map(temp_Hours,0,15,0,255)+(Minute*15/60));
      #ifdef VERBOSE  
        //Serial.println("exit displayHourMeter");   // used during debug
      #endif
}

void Ticking()
{
  if(TicTic==true)
    {                  // Ticking is allowed by switch
     if(Second==0&done_once==0)   // tictac not already started, will start at sec=0
       {
        ForceTicking();                       
        done_once=1;
        }
      if(Second>0&done_once==1)    // reset, ready for next start at sec==0
          done_once=0; 
    }  
}

// sing at each Hour
void SingTime()
{
  switch (Hour) 
  {
    case 0:
     // Big Ben bells are ringing 12 strikes
     RingType = bigbenmidnight;
     repeat = 1;
     break;
    case 1:
      repeat = 1;
      break;
    case 2:
      repeat = 2;
      break;
    case 3:
      repeat = 3;
      break;
    case 4:
      repeat = 4;
      break;
    case 5:
      repeat = 5;
      break;
    case 6:
     repeat = 6;
     break;
    case 7:
     repeat = 7;
     break;
    case 8:
     repeat = 8;
     break;
    case 9:
     repeat = 9;
     break;
    case 10:
     repeat = 10;
     break;
    case 11:
     repeat = 11;
     break;
    case 12:
     RingType = shime;  
     repeat = 1;  // one special Westmister shime
     break;
    case 13:
   repeat = 1;  // back to cuckoo song
     break;
    case 14:
     repeat = 2;
     break;
    case 15:
     repeat = 3;
     break;
    case 16:
     repeat = 4;
      break;
    case 17:
     repeat = 5;
     break;
    case 18:
      repeat = 6;
      break;
    case 19:
     repeat = 7;
     break;
    case 20:
     repeat = 8;
     break;
    case 21:
     repeat = 9;
     break;
    case 22:
     repeat = 10;
     break;
    case 23:
     repeat = 11;
     break; 
    default: 
      delay(1); // if nothing else matches, do the default
  }
  dingDong(RingType,repeat);      // play sounds : 'cuckoo' for each Hour or 'bigben' or 'shime'
  RingType = coucou;              // back to 'cuckoo' after BigBen or Westminter shime
  #ifdef VERBOSE      // used during debug
     Serial.println("EXIT displayQuarter");
  #endif
}


void dingDong(int whichRing, int iter)
{ 
 if(madCuckoo==false) iter=1;    // if cuckoo should strike only once, iter is forced to 1
 if(curHour!=Hour)
  {   // in order to ring only once
  for(int xfois=0;xfois<iter;xfois++)
      {
      PlayMp3(whichRing);  // start reading track00x refenced by whichRing
      }  
  ForceTicking();
  curHour=Hour;
  }
}

void ForceTicking()
{
  playTrack(tictac);   // pulsing the Second is prioritary against other sound
  //delay(100);  
  isFreeForPlaying =  getStatusPlaying();  // 
}

void PlayMp3(int PlayTrack)
{
  playTrack(PlayTrack);   // sing the first cuckoo
  //delay(100);  
   isFreeForPlaying =  getStatusPlaying();  // 
   #ifdef VERBOSE      // used during debug
    Serial.print(F("ETAT apres musique : "));Serial.println(isFreeForPlaying);
   #endif
  while(isFreeForPlaying == LOW) 
    {
    delay(100);
    isFreeForPlaying =  getStatusPlaying();  // 
    }
}


void setDateDs1307()                
{
   Second = (byte) (0);       // Use of (byte) type casting to achieve result.  
   Minute = (byte) (0);
   Hour  = (byte) (0);
   dayOfWeek = (byte) (1);    // dummy value
   dayOfMonth = (byte) (1);   // dummy value
   Month = (byte) (1);        // dummy value
   Year= (byte) (16);         // dummy value
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   I2C_WRITE(0x00);
   I2C_WRITE(decToBcd(Second) & 0x7f);    // 0 to bit 7 starts the clock
   I2C_WRITE(decToBcd(Minute));
   I2C_WRITE(decToBcd(Hour));      // If you want 12 Hour am/pm you need to set
   I2C_WRITE(decToBcd(dayOfWeek));
   I2C_WRITE(decToBcd(dayOfMonth));
   I2C_WRITE(decToBcd(Month));
   I2C_WRITE(decToBcd(Year));
   Wire.endTransmission();
}

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

void setEqualizer(int EQ)
{
  execute_CMD(0x07, 0, EQ); 
  //delay(100);
}

void playTrack(byte track)   // limited to LSB = 255 mp3 tracks
{
  execute_CMD(0x03, 0,track);
  //delay(100);
}

void PlayRandom () 
{ 
   byte whichTrack = random(LimBasse, LimHaute);
   if(whichTrack==last_track_played) whichTrack+=1;  // this is to avoid to play twice the same track
   last_track_played=whichTrack;
   playTrack(whichTrack);
}

void Switch_Mode()
  {
   static unsigned long last_interrupt_time = 0;
   unsigned long interrupt_time = millis();
   // If interrupts come faster than 200ms, assume it's a bounce and ignore
   if (interrupt_time - last_interrupt_time > 100)
   { int AlwaysOn = LOW;
     // faire le test si l'état est toujours HIGH après 1s
     for(int k2=0;k2<30000;k2++) {AlwaysOn=digitalRead(Button_INT);}  // pseudo tempo
     if(AlwaysOn == HIGH)
       { 
        ManualSetVolume();        // volume settings mode
       }
     else
       {
       //increase StateMachine status by one
       ModeStatus = (ModeStatus+0x01)%3;   // mod(3) will generate 3 status (0=tictac, 1 = random, 2 = sequential)
       #ifdef VERBOSE
         Serial.print(F("Changement de mode > "));  Serial.println(ModeStatus);
       #endif
       stopMP3();           // stop any playing MP3
       for(long int k1=0;k1<3;k1++)  // LED is toggling to display random mode
          {
          digitalWrite(VolumLED,LOW);   // LED blinks
          myDelay(4000);   
          digitalWrite(VolumLED,HIGH);
          myDelay(4000);  
          }
       digitalWrite(VolumLED,HIGH);
       isFreeForPlaying =  getStatusPlaying();  // latest status if HI return fast
       while(isFreeForPlaying == LOW)           // if not, wit until status is LOW
          {
          delay(100);
          isFreeForPlaying =  getStatusPlaying();  // 
          }
          if(ModeStatus==0) ForceTicking();   // when switching back to clock, ticking is forced
      }
   last_interrupt_time = interrupt_time;
  }
 }

void PlaySequential() 
{ 
   if(NextTrack <LimBasse||NextTrack >LimHaute) NextTrack =8;    // reset tracknumber to begining = LimBasse
   else NextTrack = NextTrack +1 ;   // play next track
   playTrack(NextTrack);
}

void ManualSetVolume()
 { int AlwaysOn,val; 
   digitalWrite(VolumLED,LOW);    //LED ON steady state for Volume Settings 
   #ifdef VERBOSE
      Serial.println(F("Passage en mode volume settings "));
   #endif
   for(long int k=0;k<1000;k++)   // change k limit to manage duration of volume settings
   {
     myDelay(500);
     VolumePotar=analogRead(Potar);
     val = map(VolumePotar, 0, 1023, 0, 48);
     #ifdef VERBOSE
       Serial.print(F("Valeur Potar "));Serial.println(val);
     #endif
    }  
   setVolume(val);     // transmit new volume level to mp3 module
   EE_addr=0;
   EEPROM.write(EE_addr,val);   // save volume into EEPROM for next power on
   digitalWrite(VolumLED,HIGH);   // LED OFF
 }

 void myDelay(long int myTime)
 {
 for(int k2=0;k2<myTime;k2++) {digitalRead(Button_INT);}  // pseudo tempo
 }

bool  getStatusPlaying()
{ int StatusPlaying = 0;
  bool Free4Playing = true;
  for(int k1=0;k1<5;k1++) 
   {
   StatusPlaying +=  digitalRead(FreeForPlaying);   //prin D3
   myDelay(4000);  
   }
  if(StatusPlaying/5 < 1) Free4Playing = false;
 return Free4Playing;
}

void stopMP3()
{
  execute_CMD(0x16,0,0);
  //delay(500);
}

void resetMP3()
{
  execute_CMD(0xC,0,0);
  //delay(500);
}

void execute_CMD(byte CMD, byte ParamMSB, byte ParamLSB)
{
  // Calculate checksum (2 bytes)
  word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + ParamMSB + ParamLSB);
  // Build the command line
  byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,ParamMSB, ParamLSB, 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]);}
  delay(100);
}

void reglage_afficheur()
{
   while (Serial.available() > 0) {
    stringValeur = String("Valeur: ");
    // look for the next valid integer in the incoming serial stream:
    int val = Serial.parseInt();

    // look for the newline. That's the end of your
    // sentence:
    if (Serial.read() == '\n') 
    {
      Serial.println(stringValeur += String(val));
      // display Seconds
      analogWrite(SecondS0030,val);
      analogWrite(SecondS3060,val);
      // display Minutes
      analogWrite(MinuteS,val);
      // display Hours
      analogWrite(HourS,val);
    }
   }
}