Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

Code source autonome

Moteurs pas-à-pas 28BYJ-48 et contrôleur UNL2003AN

Bonjour,

Ce tutoriel explique comment monter un circuit qui utilise :

 Une carte Arduino Uno (Funduino Uno)
 Une planche d'expérimentation "Solderless Breadboard"
 Un moteur pas-à-pas 28BYJ-48 bipolaires
 Une carte contrôleur K1208064 (ULN2003)
 Un capteur infrarouge TSOP1838 (VS1838B)
 Une mini télécommande style MP3
 Deux boutons-poussoirs "Push Button Switches" à 4 pattes

Le code source vous permettra de contrôler un moteur pas-à-pas 28BYJ-48, de l'arrêt jusqu'à sa vitesse limite et même au-delà. Le tout contrôlé par mini télécommande, et minimalement par deux boutons sur la planche d'expérimentation.

En soi, le code source est très explicite et donne tous les détails requis pour son utilisation et le montage du circuit à réaliser.

Faites un copier-coller de ce code source dans l'éditeur Arduino et prenez le temps de le lire avant de l'exécuter, vous serez à même d'en apprécier toute la richesse et cela vous évitera bien des écueils.

Notez que le code source est plus lisible une fois copié dans l'éditeur Arduino. Ici la largeur d'une ligne de code n'est que de 40 à 50 caractères et le code source est mis en page pour une présentation sur 80 colonnes. Aussi, la coloration et la tabulation du code sont plus conforment et intéressantes dans l'éditeur Arduino. De ces faits, ici plusieurs lignes sont très difficiles a interpréter.


//*****************************************************************************
/*
Programme Arduino : MoteurPas_A_PasControleurK1208064_ULN2003_Boutons2

Écrit par : René Ross

Date : 2013-08-18

Bibliothèques :
Bibliothèque télécommande infrarouge pour Arduino, envoyer et recevoir des
signaux infrarouges avec de multiples protocoles :
https://github.com/shirriff/Arduino-IRremote
La librairie Stepper pour le contrôle des moteurs pas à pas :
https://arduino.cc/fr/Main/LibrairieStepper
*/

//*****************************************************************************
// Testé avec : Arduino 1.5.2 sur Funduino Uno
//*****************************************************************************
/*
Testé avec les produits suivants :
Funduino Uno :
https://dx.com/p/funduino-uno-r3-mega328p-board-for-hw-sw-engineers-development-tools-150802
Planche d'expérimentation "Solderless Breadboard" :
https://dx.com/p/solderless-breadboard-white-large-size-121529
Capteur infrarouge TSOP1838 (VS1838B) :
https://dx.com/p/tsop1838-ir-infrared-37-9khz-receiver-18m-range-2-7-5-5v-135045
Télécommande style MP3 :
https://dx.com/p/mcu-development-board-21-button-remote-control-1-x-cr2025-132290
Moteur pas à pas 28BYJ-48 bipolaires et Contrôleur K1208064 (ULN2003) :
https://www.kiatronics.com/arduino-compatible/28byj-48-stepper-motor-5vdc-code-70289.html
https://www.sensors.co.nz/datasheet/28BYJ-48%20Stepper%20Motor.pdf
https://dx.com/p/4-phase-5-wires-stepper-motor-with-ul2003-driver-board-153945
https://www.sensors.co.nz/datasheet/942102570285.pdf
Bouton-poussoir "Push Button Switches" a 4 pattes :
https://dx.com/p/square-style-electrical-power-control-4-pin-push-button-switches-10-pcs-158030
Autres liens en rapport avec le sujet :
https://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ArduinoExpertSerie2
https://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ArduinoExpertSerieCanTerminalPC
*/

//*****************************************************************************

//*****************************************************************************
// Matériel requis ?
//*****************************************************************************
/*
1 x Contrôleur Arduino UNO.
1 x Planche d'expérimentation Circuit-Test MB-102J « BreadBoard ».
1 x 9V 1A Power Adapter for Arduino (DX.com SKU: 126288)
1 x Mini télécommandes type MP3 (DX.com : 132290).
1 x Capteur infrarouges VS1838B
1 x Condensateur 100uF 10V
1 x Condensateur 104
1 x Résistance 100 Ohm
1 x Résistance 20 KOhm
1 x Contrôleur K1208064 (ULN2003)
1 x Moteur pas-à-pas 28BYJ-48 bipolaires
2 x Bouton.
2 x Résistance 100 Ohm

Et des petits câbles électriques et connecteurs appropriés (mâle mâle, femelle
femelle et mâle femelle). Pour référence : MB-940, MB-910, MB-900, MB-102J,
LS-MMPJ-6, LS-FFPJ-6, etc.
*/

//*****************************************************************************

//*****************************************************************************
// Circuit à réaliser.
//*****************************************************************************
/*
Dans cette section, toutes les connexions des composantes du montage sont
listé, qu'ils soient utilisés ou non, et cela pour éviter tout oublie et
rendre le copier / coller par bloc complet pour une pièce plus facile d'un
montage à l'autre. Le plus souvent possible le libelle de la pièce précédé du
nom court de la pièce est utilisé, par exemple « ARDUINO_A3 », pour la broche
analogique A3 d'une carte contrôleur Arduino Uno R3.

Plaque d'expérimentation « BreanBoard » :

Pour identifier les broches d'une plaque d'expérimentation « BreanBoard »,
comme dans le jeu de bataille navale "Battle Ship", les lignes sont identifiées
pas des numéro (ici, de 1 a 63) et les colonnes sont identifiées par lettre des
lettres (ici, de a a j) et des signes (+) et (-). Donc (i10) indique
l'intersection de la colonne "i" avec la ligne numéro "10". Pour une broche
des colonnes négatives (-) ou GND et positives (+) ou Vcc, c'est le
signe de la colonne « + » ou « - », suivi du numéro de la rangée (de 1 a 63),
et suivit du côté de la plaque en majuscule, gauche « G » ou droite « D ».
Donc pour la colonne positive de la rangée 3, côté gauche, cela donne (+3G).
Le tout entre parenthèse « ( » et « ) » pour bien spécifier une position de la
planche d'expérimentation et pour éviter toutes confusions.
*/

/*
Câblage de l'Arduino Uno sur une planche d'expérimentation MB-104 :

ARDUIBO_USB    :
ARDUIBO_PWR12V : Adaptateur de 5  12 Volts
ARDUIBO_RESET  : ARDUIBO_2
ARDUIBO_3_3V   :
ARDUIBO_5V_1   : (+3D)
ARDUIBO_GND1   : (-3D)
ARDUIBO_GND2   : CONTROLE_MOTEUR_1_5V_NEGATIF
ARDUIBO_VIN    : CONTROLE_MOTEUR_1_5V_POSITIF

ARDUIBO_A0     :
ARDUIBO_A1     :
ARDUIBO_A2     :
ARDUIBO_A3     :
ARDUIBO_A4     :
ARDUIBO_A5     :

ARDUIBO_AREF   :
ARDUIBO_GND3   :
ARDUIBO_13     :
ARDUIBO_12     : BOUTON_1_PATTE_3
ARDUIBO_11_PWM : BOUTON_2_PATTE_3
ARDUIBO_10_PWM :
ARDUIBO_9_PWM  :
ARDUIBO_8      : (e1)
ARDUIBO_7      : CONTROLE_MOTEUR_1_IN4
ARDUIBO_6_PWM  : CONTROLE_MOTEUR_1_IN2
ARDUIBO_5_PWM  : CONTROLE_MOTEUR_1_IN3
ARDUIBO_4      : CONTROLE_MOTEUR_1_IN1
ARDUIBO_3_PWM  :
ARDUIBO_2      : ARDUIBO_RESET
ARDUIBO_1_TX0  :
ARDUIBO_0_RX0  :

Câblage du contrôle moteur 1 sur une planche d'expérimentation MB-104 :

CONTROLE_MOTEUR_1_5V_NEGATIF : ARDUIBO_GND2
CONTROLE_MOTEUR_1_5V_POSITIF : ARDUIBO_VIN
CONTROLE_MOTEUR_1_IN1        : ARDUIBO_4_PWM
CONTROLE_MOTEUR_1_IN2        : ARDUIBO_6_PWM
CONTROLE_MOTEUR_1_IN3        : ARDUIBO_5_PWM
CONTROLE_MOTEUR_1_IN4        : ARDUIBO_7_PWM
CONTROLE_MOTEUR_1_MOTEUR     : MOTEUR_1_CONTROLE (5 fils)

Câblage du moteur 1 sur le contrôle moteur 1 :

MOTEUR_1_CONTROLE : CONTROLE_MOTEUR_1_MOTEUR (5 fils)

Câblage du bouton 1 sur une planche d'expérimentation MB-104 :

BOUTON_1_PATTE_1            : (d7)
BOUTON_1_PATTE_2            : (d9)
BOUTON_1_PATTE_3            : (g9)
BOUTON_1_PATTE_4            : (g7)
Câble broche 1              : (j7)
Câble broche 2              : (+7D)
Câble broche 1              : (i9)
Câble broche 2              : ARDUIBO_12
Résistance 100 Ohm broche 1 : (j9)
Résistance 100 Ohm broche 2 : (-9D)

Câblage du bouton 2 sur une planche d'expérimentation MB-104 :

BOUTON_2_PATTE_1            : (d13)
BOUTON_2_PATTE_2            : (d15)
BOUTON_2_PATTE_3            : (g15)
BOUTON_2_PATTE_4            : (g13)
Câble broche 1              : (j13)
Câble broche 2              : (+13D)
Câble broche 1              : (i15)
Câble broche 2              : ARDUIBO_11
Résistance 100 Ohm broche 1 : (j15)
Résistance 100 Ohm broche 2 : (-15D)

Câblage pour le capteur infrarouge utiliser avec la télécommande, sur la
planche d'expérimentation  :

CAPTEUR_IR_1_SORTIE broche 1 : (c1)
CAPTEUR_IR_1_GND broche 2    : (c2)
CAPTEUR_IR_1_VIN broche 3    : (c3)
Condensateur 100uF 10V-      : (e2)
Condensateur 100uF 10V+      : (e3)
Condensateur 104 broche 1    : (d2)
Condensateur 104 broche 2    : (d3)
Câble broche 1               : (-3G)
Câble broche 2               : (a2)
Câble broche 1               : ARDUINO_8
Câble broche 2               : (e1)
Résistance 100 Ohm broche 1  : (+3G)
Résistance 100 Ohm broche 2  : (a3)
Résistance 22 KOhm broche 1  : (b1)
Résistance 22 KOhm broche 2  : (b3)
*/

//*****************************************************************************

//*****************************************************************************
// Inclusion des librairies utilisées.
//*****************************************************************************
#include <IRremote.h>
/*
Il s'agit de la bibliothèque irRemote pour l'Arduino.

Pour télécharger depuis github :

https://github.com/shirriff/Arduino-IRremote

Cliquez sur le lien "Télécharger" en haut à droite, cliquez sur « Télécharger
au format Zip", pour obtenir un fichier zip. Décompressez-le et renommez-le
répertoire « Shirriff-Arduino-irRemote-NNN » pour « irRemote ». Pour
l'installer, déplacer le répertoire de irRemote téléchargée dans votre dossier
des bibliothèques Arduino « ~/Arduino/libraries/IRremote ». Pour avoir accès à la
nouvelle bibliothèque, vous devez redémarrer l'éditeur Ardouino. Pour plus de
détails sur la bibliothèque voir le wiki sur github ou le poste :

https://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html blog

Copyright 2009-2012 Ken Shirriff #include <IRremote.h>

Merci à cette personne pour sa grande contribution !
*/


#include <Stepper.h>
/*
Cette librairie vous permet de contrôler des moteurs pas-à-pas unipolaires et
bipolaires. Les moteurs pas à pas sont des moteurs capables d'exécuter des
rotations "cran par cran" d'une grande précision. Pour utiliser cette
librairie avec votre carte Arduino, voua avez besoin d'un moteur pas à pas et
d'une interface de puissance adaptée pour contrôler le moteur.

Source : https://arduino.cc/fr/Main/LibrairieStepper
*/

//*****************************************************************************

//*****************************************************************************
// Déclaration des constantes.
//*****************************************************************************
/*
Par convention, pour nommer une constante, nous utiliserons des noms écrits
tout en majuscule, en capitale, ce qui facilitera leur repérage et rendra le
code plus facilement compréhensible. Le mot devant notre nom de constante
indique à l'Arduino l'espace mémoire à réserver pour stocker cette donnée.
Après le nom de notre constante, on lui attribue sa valeur.
*/

/*
Constante pour franciser le code source du programme. Ici nous définissons que
la constante « ENTREE » est l'équivalent du paramètre « INPUT ». Ce paramètre
est pour prépare l'Arduino a recevoir une tension électrique pour ce
connecteur, sur ce port de communication, sur ce "pin".
*/

const byte ENTREE = INPUT;

/*
Constante pour franciser le code source du programme. Ici nous définissons que
la constante « ENTREE_ET_RESISTENCE_INTERNE » est l'équivalent du paramètre
« INPUT_PULLUP ». Ce paramètre est pour prépare l'Arduino en activant sa
résistance interne et a recevoir une tension électrique pour ce connecteur,
sur ce port de communication, sur ce "pin".
*/

const byte ENTREE_ET_RESISTENCE_INTERNE = INPUT_PULLUP;

/*
Constante pour franciser le code source du programme. Ici nous définissons que
la constante « SORTIE » est l'équivalent du paramètre « OUTPUT ». Ce paramètre
est pour prépare l'Arduino a émettre une tension électrique pour ce connecteur,
sur ce port de communication, sur ce "pin".
*/

const byte SORTIE = OUTPUT;

/*
Constante pour franciser le code source du programme. Ici nous définissons que
la constante « HAUT » est l'équivalent du paramètre « HIGH ». Ce paramètre fait
que l'Arduino maintiendra un voltage haut sur ce connecteur, soit 3.3 Volts,
soit 5 Volts, selon sa propre tension d'alimentation. En électronique, cela
correspondra aux valeurs logiques « 1 », « Oui », ou « Vrai », etc.
*/

const byte HAUT = HIGH;

/*
Constante pour franciser le code source du programme. Ici nous définissons que
la constante « BAS » est l'équivalent du paramètre « LOW ». Ce paramètre fait
que l'Arduino maintiendra un voltage bas sur ce connecteur, soit 0 Volt. En
électronique, cela correspondra aux valeurs logiques « 0 », « Non », ou
« Faut », etc.
*/

const byte BAS = LOW;

/*
Constante pour franciser le code source du programme. Ici nous définissons que
la constante « NON » est l'équivalent du paramètre « false », cela
correspondra aux valeurs logiques « 0 », « Non », ou « Faut », etc.
*/

const byte NON = false;

/*
Constante pour franciser le code source du programme. Ici nous définissons que
la constante « OUI » est l'équivalent du paramètre « true », cela
correspondra aux valeurs logiques « 1 », « Oui », ou « Vrai », etc.
*/

const byte OUI = true;

/*
Constante pour franciser le code source du programme. Ici nous définissons que
la constante « FAUX » est l'équivalent du paramètre « false », cela
correspondra aux valeurs logiques « 0 », « Non », etc.
*/

const byte FAUX = false;

/*
Constante pour franciser le code source du programme. Ici nous définissons que
la constante « VRAI » est l'équivalent du paramètre « true », cela
correspondra aux valeurs logiques « 1 », « Oui », etc.
*/

const byte VRAI = true;

// Pour la fonction « delay », qui compte le temps en milliseconde.
const int UneSeconde = 1000;
// ...
//*****************************************************************************

//*****************************************************************************
// Constantes des connecteurs.
//*****************************************************************************
// Pour activer et déactiver la DEL sur le contrôleur Arduino.
const byte ARDUINO_DEL = 13;

// Pour réinitialiser la carte Arduino par la broche RESET.
const byte BROCHE_REINITIALISER = 2;

// Pour démarrer la boucle principale les deux boutons simultanément.
// Pour diminuer la vitesse du moteur d'un facteur de 10.
const byte BOUTON_1_PORT = 12;
// Pour augmenter la vitesse du moteur d'un facteur de 10.
const byte BOUTON_2_PORT = 11;

// Broche d'Arduino pour recevoir le signale du capteur infrarouge.
const byte CAPTEUR_IR_1_SORTIE = 8;

// Nombre de degrés que fait le moteur pour un pas.
// Pour un moteur 28BYJ-48 cette valeur est 5.625°.
const float MOTEUR_1_NB_DEGRE_PAR_PAS = 5.625;

/*
Indique le nombre de pas que doit faire le moteur pour faire un tour complet
de 360° sur lui-même et cela ne tien pas compte d'un éventuel engrenage
démultiplicateur intégré au moteur (voir la fiche technique du moteur). Si
votre moteur indique un nombre de degrés par pas de 3.6°, alors diviser 360°
par ce nombre pour obtenir le nombre de pas. Donc 360° / 3.6° donne 100 pas.

Le type de la variable doit-être « int ». Pour un moteur 28BYJ-48 cette valeur
est 5.625°, donc (360° / 5.625°) = 64 pas "Step" pour 1 tour.
*/

const int MOTEUR_1_NB_PAS_PAR_360 = (360 / MOTEUR_1_NB_DEGRE_PAR_PAS);

/*
Vitesse maximum pour le moteur pas à pas.

Noter bien que la vitesse réfère au nombre de boucles de pulsations par
seconde envoyé au moteur et donc au nombre de pas par seconde que fera le
moteur (boucle de pulsations = pas du moteur/seconde).

Pour un moteur 28BYJ-48, selon la fiche technique du fabricant, les valeurs
sont les suivantes :
- En plaine charge (Couple = 29.4mN.m) V-Max = 100 pps
- A vide en traction V-Max = 500 pps
- A vide en propulsion V-Max = 1000 pps
*/

const long MOTEUR_1_VITESSE_MAXIMUM = 1000; // De 100 ~ 1000.
// Vitesse par défaut pour ce moteur.
const long MOTEUR_1_VITESSE_DEFAUT = 100;

// Broche d'Arduino pour émettre les impulsions au servo moteur 1.
const byte CONTROLE_MOTEUR_1_IN1 = 4;
const byte CONTROLE_MOTEUR_1_IN2 = 5;
const byte CONTROLE_MOTEUR_1_IN3 = 6;
const byte CONTROLE_MOTEUR_1_IN4 = 7;
//*****************************************************************************

//*****************************************************************************
// Déclaration des variables globales.
//*****************************************************************************
/*
Par convention, pour nommer une variable, nous utiliserons des noms écrits
avec une majuscule pour la première lettre de chaque mot composant le nom de la
variable, ce qui facilitera leur repérage et rendra le code plus facilement
compréhensible. Le mot devant notre nom de variable indique à l'Arduino l'espace
mémoire à réserver pour stocker cette donnée. Après le nom de notre variable, on
lui attribue sa valeur.
*/

/*
Ici, nous définissons la variable qui contrôlera la grande boucle principale,
qui s'active avec le bouton « Power » de la télécommande. Par défaut, le robot
ne fait rien a l’exception d'initialiser ses périphériques.
*/

boolean Boucler = NON;

// Recois l'état du bouton, pressé ou non.
boolean EtatBouton1 = 0;
boolean EtatBouton2 = 0;

/*
Définition de la valeur retournée par les boutons de la télécommande.
*/

const unsigned long TelecommandeBoutonRebond    = 4294967295;
const unsigned long TelecommandeBoutonPower     = 16753245;
const unsigned long TelecommandeBoutonMode      = 16736925;
const unsigned long TelecommandeBoutonSon       = 16769565;
const unsigned long TelecommandeBoutonPlayPause = 16720605;
const unsigned long TelecommandeBoutonDebut     = 16712445;
const unsigned long TelecommandeBoutonFin       = 16761405;
const unsigned long TelecommandeBoutonEQ        = 16769055;
const unsigned long TelecommandeBoutonMoins     = 16754775;
const unsigned long TelecommandeBoutonPlus      = 16748655;
const unsigned long TelecommandeBouton0         = 16738455;
const unsigned long TelecommandeBoutonRecycle   = 16750695;
const unsigned long TelecommandeBoutonU_SD      = 16756815;
const unsigned long TelecommandeBouton1         = 16724175;
const unsigned long TelecommandeBouton2         = 16718055;
const unsigned long TelecommandeBouton3         = 16743045;
const unsigned long TelecommandeBouton4         = 16716015;
const unsigned long TelecommandeBouton5         = 16726215;
const unsigned long TelecommandeBouton6         = 16734885;
const unsigned long TelecommandeBouton7         = 16728765;
const unsigned long TelecommandeBouton8         = 16730805;
const unsigned long TelecommandeBouton9         = 16732845;
const unsigned long TelecommandeBoutonAutre     = 4294967295;
// Pour contenir la valeur du dernier bouton pressé.
      unsigned long TelecommandeBoutonValeur = 0;

// Vitesse maximale pour un moteur.
int ControleMoteur1Vitesse = MOTEUR_1_VITESSE_DEFAUT;
//*****************************************************************************

//*****************************************************************************
// Création en mémoire des objets pour les interfaces des périphériques.
//*****************************************************************************
// Pour le capteur infrarouge crée un objet sur la broche voulue.
IRrecv         Capteur_IR_1 (CAPTEUR_IR_1_SORTIE);
decode_results Capteur_IR_1_Results;

// Initialiser l'objet Stepper de la bibliothèque du même nom.
Stepper ControleMoteur1 (MOTEUR_1_NB_PAS_PAR_360, CONTROLE_MOTEUR_1_IN1,
                        CONTROLE_MOTEUR_1_IN2, CONTROLE_MOTEUR_1_IN3,
                        CONTROLE_MOTEUR_1_IN4);
//*****************************************************************************

//*****************************************************************************
// FONCTION SETUP = Code d'initialisation.
//*****************************************************************************
/*
La fonction setup () est exécutée en premier et 1 seule fois, au démarrage du
programme. Pour éviter de mettre des composantes sous tension avec la dernière
version du programme chargé dans l'Arduino, nous utilisons une boucle « while »,
tant qu'une première action n'est pas accomplie par l'utilisateur, on ne fait
rien (Télécommande, bouton, etc.).

L'activation du rappel au + interne des connecteurs en entrée si nécessaire.
L'instruction « digitalWrite (pin, HIGH); » écrit la valeur HIGH, qui vaux 1
sur le connecteur en entrée, ce qui active la résistance de "rappel au +"
(pullup) au plus de ce connecteur. L'utilisation de cette résistance interne
est une protection minimale pour l'intégrité physique pour la puce principale.
*/

void setup ()
{
  // Ici les instructions à exécuter au démarrage.
  // IMPORTANT : régler le terminal côté PC avec la même valeur de
  // transmission.
  Serial.begin (115200);

  // Pour affichage dans le Moniteur série de l'éditeur Arduino.
  Serial.println ();
  Serial.print ("*********************************************************");
  Serial.println ();
  Serial.print ("Debut de la procedure d'initialisation du systeme...");
  Serial.println ();
  Serial.print ("*********************************************************");
  Serial.println ();
  Serial.println ();
  Serial.print ("MOTEUR_1_VITESSE_DEFAUT  : ");
  Serial.print (MOTEUR_1_VITESSE_DEFAUT);
  Serial.println ();
  Serial.print ("MOTEUR_1_VITESSE_MAXIMUM : ");
  Serial.print (MOTEUR_1_VITESSE_MAXIMUM);
  Serial.println ();
  Serial.print ("ControleMoteur1Vitesse   : ");
  Serial.print (ControleMoteur1Vitesse);
  Serial.println ();
  Serial.println ();
  Serial.print ("Attante du bouton (Power) de la telecommande...");
  Serial.println ();

  // Connecteurs en entrées et sorties.

  // Pour le bouton Marche/Arret sur la planche d'expérimentation.
  // Configurer le port Arduino en entrée pour le bouton 1.
  pinMode (BOUTON_1_PORT, ENTREE);
  // Ativer la résistance au plus PULLUP.
  digitalWrite (BOUTON_1_PORT, HAUT);
  // Configurer le port Arduino en entrée pour le bouton 2.
  pinMode (BOUTON_2_PORT, ENTREE);
  // Ativer la résistance au plus PULLUP.
  digitalWrite (BOUTON_2_PORT, HAUT);

  // Configurer le port Arduino en entrée pour le capteur infrarouge.
  pinMode (CAPTEUR_IR_1_SORTIE, ENTREE);
  // Initialisation et début de la réception du capteur infrarouge.
  Capteur_IR_1.enableIRIn ();

  // Boucle pour éviter qu'un ancien progamme chargé ne s'exécute avec un
  // nouveau montage installé, en attente du chargement du nouveau programme.
  // Jusqu'ici, c'est le minimum qui est activé, le reste des connexions
  // seront activé après la boucle d'attente.
  Boucler = NON;
  while (Boucler != OUI)
  {
    delay (UneSeconde);
    // Gerer les deux boutons MarcheArret et (-) et (+) vitesse moteur.
    GererBoutonMarcheArret ();
    // Gérer les actions d'une télécommande et d'un capteur infrarouge.
    GererBoutonTeleCommande ();
  }

  // Activer la DEL de l'Arduino.
  pinMode (ARDUINO_DEL, SORTIE);
  analogWrite (ARDUINO_DEL, 128);

  // Affichager dans le Moniteur série de l'éditeur Arduino.
  Serial.println ();
  Serial.print ("Fin de la procédure d'initialisation du système...");
  Serial.println ();
  Serial.print ("*********************************************************");
  Serial.println ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION LOOP = Boucle sans fin = coeur du programme.
//*****************************************************************************
/*
La fonction loop () s'exécute sans fin en boucle aussi longtemps que l'Arduino
est sous tension.
*/


void loop()
{
  // Ici les instructions à exécuter par le programme principal.

  // Gerer les mouvements du moteur pas à pas "Step Motor".
  if (Boucler == OUI)
  {
    // Controler le moteur selon le paramètre de la vitesse.
    if (ControleMoteur1Vitesse == 0)
    {
//      ControleMoteur1.step (0);
    }
    // Controler le sens horaire et antihoraire.
    if (ControleMoteur1Vitesse > 0)
    {
      ControleMoteur1.step (1);
    }
    if (ControleMoteur1Vitesse < 0)
    {
      ControleMoteur1.step (-1);
    }
  }
  // Gerer les paramètres du programme et du moteur par télécommande.
  GererBoutonTeleCommande ();
  // Gerer les paramètres du programme et de la vitesse moteur par 2 boutons.
  GererBoutonMarcheArret ();
}
//*****************************************************************************

//*****************************************************************************
//*****************************************************************************
//***************************** Fin du programme. *****************************
//*****************************************************************************
//*****************************************************************************

//*****************************************************************************
// FONCTION GererBoutonMarcheArret
//*****************************************************************************
/*
Gérer l'utilisation de boutons sur la planche d'expérimentation.
*/

void GererBoutonMarcheArret ()
{
  // Lire de l'état des boutons.
  LectureBoutons ();

  // Les deux boutons son pressés.
  if ((EtatBouton1 == OUI) and (EtatBouton2 == OUI))
  {
    Serial.print ("EtatBouton1 = ");
    Serial.print (EtatBouton1);
    Serial.println ();
    Serial.print ("EtatBouton2 = ");
    Serial.print (EtatBouton2);
    Serial.println ();
    // Si le programme bouclait, on l'arrête.
    if (Boucler == OUI)
    {
      Boucler = NON;
      // Étaindre la DEL de l'Arduino.
      digitalWrite (ARDUINO_DEL, Boucler);
      Serial.print ("En attente d'une action d'humaine");
      Serial.println ();
    }
    else
    {
      Boucler = OUI;
      // Allumer la DEL de l'Arduino.
      digitalWrite (ARDUINO_DEL, Boucler);
      Serial.print ("Poursuite du programme");
      Serial.println ();
    }
    // Gerer les rebonds de bouton.
    while ((EtatBouton1 == OUI) and (EtatBouton2 == OUI))
    {
      // Absorber les microcoupures des rebonds (5 ms).
      delay (5);
      // Lire l'état des boutons.
      LectureBoutons ();
    }
  }

  // Condition pour diminuer la vitesse du moteur.
  // Le bouton 1 (-) est pressé, pas le bouton 2.
  if ((EtatBouton1 == OUI) and (EtatBouton2 == NON) and (Boucler == OUI))
  {
    Serial.print ("EtatBouton1 = ");
    Serial.print (EtatBouton1);
    Serial.println ();
    Serial.print ("EtatBouton2 = ");
    Serial.print (EtatBouton2);
    Serial.println ();
    // Controler la limite inférieure de la vitesse.
    if (ControleMoteur1Vitesse > (MOTEUR_1_VITESSE_MAXIMUM * -1))
    {
      // Diminuer la vitesse de...
      AjusterVitesse (-10);
    }
    while (EtatBouton1 == OUI)
    {
      // Absorber les microcoupures des rebonds (5 ms).
      delay (5);
      EtatBouton1 = digitalRead (BOUTON_1_PORT);
    }
  }

  // Condition pour augmenter la vitesse du moteur.
  // Le bouton 2 (+) est pressé, pas le bouton 1.
  if ((EtatBouton2 == OUI) and (EtatBouton1 == NON) and (Boucler == OUI))
  {
    Serial.print ("EtatBouton1 = ");
    Serial.print (EtatBouton1);
    Serial.println ();
    Serial.print ("EtatBouton2 = ");
    Serial.print (EtatBouton2);
    Serial.println ();
    // Controler la limite supérieure de la vitesse.
    if (ControleMoteur1Vitesse < MOTEUR_1_VITESSE_MAXIMUM)
    {
      // Augmenter la vitesse de...
      AjusterVitesse (10);
    }
    // Attendre la relâche du bouton
    while (EtatBouton2 == OUI)
    {
      // Absorber les microcoupures des rebonds (5 ms).
      delay (5);
      EtatBouton2 = digitalRead (BOUTON_2_PORT);
    }
  }
  ControleMoteur1.setSpeed (abs (ControleMoteur1Vitesse));
}
//*****************************************************************************

//*****************************************************************************
// FONCTION LectureBoutons
//*****************************************************************************
/*
Lecture de l'état des boutons.
*/

void LectureBoutons ()
{
  // Lire l'état des boutons.
  EtatBouton1 = digitalRead (BOUTON_1_PORT);
  EtatBouton2 = digitalRead (BOUTON_2_PORT);
}
//*****************************************************************************

//*****************************************************************************
// FONCTION GererBoutonTeleCommande
//*****************************************************************************
/*
Gérer l'utilisation d'une télécommande type MP3 avec capteur infrarouge.

Ici tous les boutons de la télécommande sont listés et la majorité ont un
effet sur le déroulement de de la boucle principale ou sur les paramètres de
fonctionnement du moteur ou les deux  la fois et la touche « EQ » est
l'actionneur de la broche RESET de la carte Arduino, donc du redémarrage du
Système complet.

En synthèse les boutons font :

Power     : Active/désactive la boucle principale du programme, arrêt moteur.
Mode      : Pas d'action.
Son       : Pas d'action.
PlayPause : Active/désactive la boucle principale du programme, arrêt moteur.
Debut     : Change le sens de rotation du moteur pour antihoraire.
Fin       : Change le sens de rotation du moteur pour horaire.
EQ        : Bouton kamikaze qui utilise la broche RESET de la carte Arduino.
Moins     : Diminue la vitesse de rotation du moteur de 1 unité.
Plus      : Augmente la vitesse de rotation du moteur de 1 unité.
0         : Ajuste la vitesse négative ou positive a 1.
Recycle   : Ajuste la vitesse moteur a sa vitesse par défaut.
U_SD      : Pas d'action.
1         : Ajuste la vitesse négative ou positive a 100.
2         : Ajuste la vitesse négative ou positive a 200.
3         : Ajuste la vitesse négative ou positive a 300.
4         : Ajuste la vitesse négative ou positive a 400.
5         : Ajuste la vitesse négative ou positive a 500.
6         : Ajuste la vitesse négative ou positive a 600.
7         : Ajuste la vitesse négative ou positive a 700.
8         : Ajuste la vitesse négative ou positive a 800.
9         : Ajuste la vitesse négative ou positive a 900.
Rebond     : En cas de résidu de retour de bouton, on ne fait rien.
default   : Une télécommande génère beaucoup d'autres codes qui sont inutiles ici.
*/


void GererBoutonTeleCommande ()
{
  // Si la télécommande émet quelque chose.
  if (Capteur_IR_1.decode (&Capteur_IR_1_Results))
  {
    // Récuperer une valeur du capteur infrarouge.
    Capteur_IR_1.resume ();
    TelecommandeBoutonValeur = Capteur_IR_1_Results.value;
    // Selon les valeurs connues pour une touche de la télécommande fait...
    switch (TelecommandeBoutonValeur)
    {
      case TelecommandeBoutonPower:
        Serial.print ("TelecommandeBoutonPower ");
        Serial.println ();
        Boucler = 1 - Boucler;
        digitalWrite (ARDUINO_DEL, Boucler);
        AfficherLesValeur ();
        break;
      case TelecommandeBoutonMode:
        Serial.print ("TelecommandeBoutonMode ");
        Serial.println ();
        break;
      case TelecommandeBoutonSon:
        Serial.print ("TelecommandeBoutonSon ");
        Serial.println ();
        break;
      case TelecommandeBoutonPlayPause:
        Serial.print ("TelecommandeBoutonPlayPause ");
        Serial.println ();
        Boucler = 1 - Boucler;
        digitalWrite (ARDUINO_DEL, Boucler);
        AfficherLesValeur ();
        break;
      case TelecommandeBoutonDebut:
        Serial.print ("TelecommandeBoutonDebut ");
        Serial.println ();
        ControleMoteur1Vitesse = (abs (ControleMoteur1Vitesse) * -1);
        AjusterVitesse (0);
        break;
      case TelecommandeBoutonFin:
        Serial.print ("TelecommandeBoutonFin ");
        Serial.println ();
        ControleMoteur1Vitesse = (abs (ControleMoteur1Vitesse));
        AjusterVitesse (0);
        break;
      case TelecommandeBoutonEQ:
        Serial.print ("TelecommandeBoutonEQ ");
        Serial.println ();
        Serial.print ("Reinitialisation du systeme par telecommande ! ");
        Serial.println ();
        delay (UneSeconde / 2);
        // Arreter le moteur et réinitialiser le système Arduino.
        pinMode (BROCHE_REINITIALISER, SORTIE);
        digitalWrite (BROCHE_REINITIALISER, HAUT);
        break;
      case TelecommandeBoutonMoins:
        Serial.print ("TelecommandeBoutonMoins ");
        Serial.println ();
        ControleMoteur1Vitesse = ControleMoteur1Vitesse - 1;
        AjusterVitesse (0);
        break;
      case TelecommandeBoutonPlus:
        Serial.print ("TelecommandeBoutonPlus ");
        Serial.println ();
        ControleMoteur1Vitesse = ControleMoteur1Vitesse + 1;
        AjusterVitesse (0);
        break;
      case TelecommandeBouton0:
        Serial.print ("TelecommandeBouton0 ");
        Serial.println ();
        ControleMoteur1Vitesse = 1 * constrain (ControleMoteur1Vitesse, -1, 1);
        AjusterVitesse (0);
        break;
      case TelecommandeBoutonRecycle:
        Serial.print ("TelecommandeBoutonRecycle ");
        Serial.println ();
        ControleMoteur1Vitesse = MOTEUR_1_VITESSE_DEFAUT;
        AjusterVitesse (0);
        break;
      case TelecommandeBoutonU_SD:
        Serial.print ("TelecommandeBoutonU_SD ");
        Serial.println ();
        break;
      case TelecommandeBouton1:
        Serial.print ("TelecommandeBouton1 ");
        Serial.println ();
        ControleMoteur1Vitesse = 100 * constrain (ControleMoteur1Vitesse, -1, 1);
        AjusterVitesse (0);
        break;
      case TelecommandeBouton2:
        Serial.print ("TelecommandeBouton2 ");
        Serial.println ();
        ControleMoteur1Vitesse = 200 * constrain (ControleMoteur1Vitesse, -1, 1);
        AjusterVitesse (0);
        break;
      case TelecommandeBouton3:
        Serial.print ("TelecommandeBouton3 ");
        Serial.println ();
        ControleMoteur1Vitesse = 300 * constrain (ControleMoteur1Vitesse, -1, 1);
        AjusterVitesse (0);
        break;
      case TelecommandeBouton4:
        Serial.print ("TelecommandeBouton4 ");
        Serial.println ();
        ControleMoteur1Vitesse = 400 * constrain (ControleMoteur1Vitesse, -1, 1);
        AjusterVitesse (0);
        break;
      case TelecommandeBouton5:
        Serial.print ("TelecommandeBouton5 ");
        Serial.println ();
        ControleMoteur1Vitesse = 500 * constrain (ControleMoteur1Vitesse, -1, 1);
        AjusterVitesse (0);
        break;
      case TelecommandeBouton6:
        Serial.print ("TelecommandeBouton6 ");
        Serial.println ();
        ControleMoteur1Vitesse = 600 * constrain (ControleMoteur1Vitesse, -1, 1);
        AjusterVitesse (0);
        break;
      case TelecommandeBouton7:
        Serial.print ("TelecommandeBouton7 ");
        Serial.println ();
        ControleMoteur1Vitesse = 700 * constrain (ControleMoteur1Vitesse, -1, 1);
        AjusterVitesse (0);
        break;
      case TelecommandeBouton8:
        Serial.print ("TelecommandeBouton8 ");
        Serial.println ();
        ControleMoteur1Vitesse = 800 * constrain (ControleMoteur1Vitesse, -1, 1);
        AjusterVitesse (0);
        break;
      case TelecommandeBouton9:
        Serial.print ("TelecommandeBouton9 ");
        Serial.println ();
        ControleMoteur1Vitesse = 900 * constrain (ControleMoteur1Vitesse, -1, 1);
        AjusterVitesse (0);
        break;
      case TelecommandeBoutonRebond:
        // En cas de résidu de retour de bouton, ne fait rien.
        Serial.print ("TelecommandeBoutonRebond : ");
        Serial.print (TelecommandeBoutonRebond);
        Serial.println ();
        break;
      default:
        // En cas de valeur inconnue pour une touche, ne fait rien.
        Serial.print ("TelecommandeBoutonValeur : ");
        Serial.print (TelecommandeBoutonValeur);
        Serial.println ();
    }
  }
  // Attendre la relâche de la touche.
  while (Capteur_IR_1.decode (&Capteur_IR_1_Results))
  {
    // Absorber les microcoupures des rebonds (5 ms).
    delay (5);
    // Récuperer la valeur suivante.
    Capteur_IR_1.resume ();
    TelecommandeBoutonValeur = Capteur_IR_1_Results.value;
  }
}
//*****************************************************************************

//*****************************************************************************
// FONCTION AjusterVitesse
//*****************************************************************************
/*
Ajuster la vitesse moteur en gérant le sens horaire et antihoraire.
*/

void AjusterVitesse (int Changement)
{
  // Pas d'incrémentation de la vitesse.
  if (Changement == 0)
  {
    // C'est le cas ou la valeur de la vitesse est absolue et ne doit pas être
    // augmenté n'y diminué, mais simplement appliqué.
  }
  // Gerer le sens horaire et antihoraire et les limites ±V_MAX.
  else
  {
    // Cas d'incrémentation négative.
    if (Changement < 0)
    {
      ControleMoteur1Vitesse = ControleMoteur1Vitesse + Changement;
      if (ControleMoteur1Vitesse < (MOTEUR_1_VITESSE_MAXIMUM * -1))
      {
        ControleMoteur1Vitesse = (MOTEUR_1_VITESSE_MAXIMUM * -1);
      }
    }
    // Cas d'incrémentation positive.
    if (Changement > 0)
    {
      ControleMoteur1Vitesse = ControleMoteur1Vitesse + Changement;
      if (ControleMoteur1Vitesse > MOTEUR_1_VITESSE_MAXIMUM)
      {
        ControleMoteur1Vitesse = MOTEUR_1_VITESSE_MAXIMUM;
      }
    }
  }
  // La vitesse a changée d'une manière ou d'une autre, alors :
  // Ajuster la vitesse moteur.
  ControleMoteur1.setSpeed (abs (ControleMoteur1Vitesse));

  // Afficher les nouvelles valeurs dans le Moniteur d'Arduino.
  AfficherLesValeur ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION AfficherLesValeur
//*****************************************************************************
/*
Afficher le minimum, dans le Moniteur série de l'éditeur Arduino. Il n'y a un
affichage que quand une valeur a changé, autrement c'est le silence...

Pourrait servir pour déboguer.
*/

void AfficherLesValeur ()
{
  // Afficher dans le Moniteur série de l'éditeur Arduino.
  Serial.print ("ControleMoteur1Vitesse = ");
  Serial.print (ControleMoteur1Vitesse);
  Serial.println ();
  Serial.print ("Boucler = ");
  Serial.print (Boucler);
  Serial.println ();
}
//*****************************************************************************
 


En souhaitant que vous y trouviez ce que vous cherchiez !

Bon montage !

L'ami René

Un pour tous, et tous pour un !