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

Code source autonome

Code source - Robot - Arduinobot (brouillon 01)

Bonjour,

Ce tutoriel explique comment monter un circuit qui utilise :

 L'éditeur compilateur Arduino 1.5.2.
 1 x Contrôleur Arduino Mega R2
 1 x Planche d'expérimentation Circuit-Test MB-104 « BreadBoard »
 1 x Boîtier a 6 piles AA 1.5V (9V) et connecteur pour Arduino
 1 x Adaptateur secteur pour Arduino, 9V, 1A, câble 100cm)
 2 x Moteur a courant continue(CC 3V~6V) avec engrenage réducteur 1/48 donne 100RPM
 1 x Contrôleur moteur L298N (H-Bridge) pour 2 moteurs CC ou 1 moteur Pas-A-Pas ()
 1 x Support a pivot pour moteur pas a pas et module ultrason
 1 x Carte a écran LCD LCD1602 6 boutons
 1 x Module ultrason émetteur capteur HR-SC04, éventuellement 3 modules ultrason
 1 x Capteur infra-rouge VS1838B (TSOP1838)
 1 x Mini télécommande type MP3
 1 x Buzzer électromagnétique MN-EB-BUZPS Passive
 1 x DEL 1.8 Volts
 1 x Résistance 330 Ohm
 1 x Servo Moteur TowerPro SG90 9G et accessoires

Et des petits câbles électriques et connecteurs appropriés (Réf. : MB-940, MB-910, MB-900, MB-102J, LS-MMPJ-6, LS-FFPJ-6, etc.).

Ce programme contrôle un véhicule robot a deux ou quatre roues motrices et une série de capteurs pour se déplacer intelligemment en évitant les obstacles. Éventuellement, il cartographiera son environnement pour en communiquer les coordonnées et données de ses observations à un ordinateur et cela par communication sans fil (Bluetooth). Il utilise un module à ultrason, des servomoteurs, des moteurs pas à pas ou des moteurs à courant continu, des capteurs infrarouges et des microintérupteur pour détecter son environnement. Une télécommande et un capteur infrarouge permettent de le contrôler à distance et de modifier plusieurs de ses paramètres. Il est aussi activé par un bouton directement sur la planche d'expérimentation ou les 6 boutons du module à écran LCD. Sur l'écran LCD et ou dans le moniteur série, il affiche des informations de base sur un écran LCD intégré sur le véhicule.

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.

Attention, il y a trois fichiers qui compose ce programme à placer dans un même dossier :


//*****************************************************************************
// Programme Arduino : Arduinobot [contraction du mot Ardino et Robot  ;-)]
//*****************************************************************************
/*
Écrit par : René Ross

Date : 2013-09-09

Ce code source est sous licence publique générale GNU (GNU General Public
License "GPL"), désignation « open source », ou « code source ouvert ».
Référence : https://www.fsffrance.org/index.fr.html
Ce programme est un logiciel libre; vous pouvez le redistribuer et / ou le
modifier selon les termes de la licence GNU V2. Ce programme est distribué
dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE, sans même la
garantie implicite de COMMERCIALISATION ou D'ADAPTATION À UN USAGE
PARTICULIER. Voir la GNU General Public License, Version 2 pour plus de
détails.

Ce code source se veux didactique, c'est pourquoi les commentaires y prenne
une très grande place. Mais cela ne doit pas vous effrayez, au contraire, cela
devrait vous rassurez en facilitant la compréhension du code source.
*/

//*****************************************************************************
// Que fait ce programme ?
//*****************************************************************************
/*
Ce programme contrôle un véhicule robot a deux ou quatre roues motrices et une
série de capteurs pour se déplacer intelligemment en évitant les obstacles.
Éventuellement, il cartographiera son environnement pour en communiquer les
coordonnées et données de ses observations à un ordinateur et cela par
communication sans fil (Bluetooth). Il utilise un module à ultrason, des
servomoteurs, des moteurs pas à pas ou des moteurs à courant continu, des
capteurs infrarouges et des microintérupteur pour détecter son environnement.
Une télécommande et un capteur infrarouge permettent de le contrôler à
distance et de modifier plusieurs de ses paramètres. Il est aussi activé par
un bouton directement sur la planche d'expérimentation ou les 6 boutons du
module à écran LCD. Sur l'écran LCD et ou dans le moniteur série, il affiche
des informations de base sur un écran LCD intégré sur le véhicule.
*/

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

//*****************************************************************************
// Matériel requis ?
//*****************************************************************************
/*
Testé avec : l'éditeur compilateur Arduino 1.5.2.

1 x Contrôleur Arduino Mega R2 :
https://dx.com/p/mega-2560-r3-atmega2560-16au-board-usb-cable-for-arduino-black-blue-215579

1 x Planche d'expérimentation Circuit-Test MB-104 « BreadBoard ».
https://dx.com/p/solderless-breadboard-white-large-size-121529

1 x Boîtier a 6 piles AA 1.5V (9V) et connecteur pour Arduino :
https://dx.com/p/6-x-aa-batteries-holder-with-dc2-1-power-jack-for-arduino-126413

1 x Adaptateur secteur pour Arduino, 9V, 1A, câble 100cm) :
https://dx.com/p/arduino-9v-1a-power-adapter-black-2-flat-pin-plug-100cm-cable-126288

2 x Moteur a courant continue(CC 3V~6V) avec engrenage réducteur 1/48 donne 100RPM :
https://dx.com/p/dual-axis-reducer-motor-for-smart-tt-car-yellow-silver-dc-3-6v-185017

1 x Contrôleur moteur L298N (H-Bridge) pour 2 moteurs CC ou 1 moteur Pas-A-Pas () :
https://dx.com/p/l298n-stepper-motor-driver-controller-board-module-blue-149662

1 x Support a pivot pour moteur pas a pas et module ultrason :
https://dx.com/p/2-metal-u-holders-2-round-servo-mount-brackets-w-screws-for-r-c-helicopter-silver-193069

1 x Carte a écran LCD LCD1602 6 boutons
https://www.dfrobot.com/image/data/Common/Arduino%20Shield%20Manual.pdf
https://www.dfrobot.com/image/data/DFR0009/LCD4Bit_mod.zip
https://www.zartronic.fr/doc/E2/E2N1P193/LCD_Keypad_Shield_SCH.pdf
https://www.zartronic.fr/shield-lcd-pour-arduino-p-125.html
https://dx.com/p/lcd-keypad-shield-for-arduino-duemilanove-lcd-1602-118059

3 x Module ultrason émetteur capteur HR-SC04.
https://dx.com/p/hc-sr04-ultrasonic-sensor-distance-measuring-module-133696

1 x Capteur infra-rouge VS1838B (TSOP1838) :
https://dx.com/p/tsop1838-ir-infrared-37-9khz-receiver-18m-range-2-7-5-5v-135045
https://www.dipmicro.com/store/VS1838B
https://dx.com/s/1838
Ou :
https://dx.com/p/hx1838-pc638-diy-universal-electronic-component-infrared-receiver-silver-20-pcs-158341
Avec :
1 x Condensateur 100uF 10V
1 x Condensateur 104
1 x Résistance 100 Ohm
1 x Résistance 20 KOhm

1 x Mini télécommande type MP3 :
https://dx.com/p/ir-remote-control-diy-kit-for-arduino-1-x-cr2025-136284

1 x Buzzer électromagnétique MN-EB-BUZPS Passive.
https://dx.com/p/meeeno-mn-eb-buzps-passive-buzzer-module-orange-black-202512
https://dx.com/p/3v-electromagnetic-buzzers-for-diy-project-black-5pcs-148650

1 x DEL 1.8 Volts
https://dx.com/p/620-625nm-800-1000mcd-5mm-led-red-100-piece-pack-137888
1 x Résistance 330 Ohm
https://dx.com/p/elecfreaks-diy-0-25w-100-ohm-to-2-4k-ohm-resistor-kit-a-for-arduino-test-blue-270-pcs-224974

1 x Servo Moteur TowerPro SG90 9G et accessoires :
https://dx.com/p/towerpro-sg90-9g-mini-servo-with-accessories-12859

Et des petits câbles électriques et connecteurs appropriés (Réf. : MB-940,
MB-910, MB-900, MB-102J, LS-MMPJ-6, LS-FFPJ-6, etc.).

Fils de raccordement pour le bricolage électronique (65 pièces) :
https://dx.com/p/breadboard-jumper-wires-for-electronic-diy-65-cable-pack-118826
Paquet de 40 fils mono brian male femelle de 20cm :
https://dx.com/p/male-to-female-dupont-breadboard-jumper-wires-for-arduino-40-piece-pack-20cm-length-146935
Paquet de 40 fils mono brian femelle femelle de 20cm :
https://dx.com/p/dupont-line-1p-1p-40-pack-20cm-length-121338
Paquet de 70 fils mono brian male male de 12 a 24cm :
https://dx.com/p/breadboard-jumper-wires-for-electronic-diy-70-cable-pack-80208
Breadboard Jumper Cord Kit pour Arduino (140 pièces) :
https://dx.com/p/breadboard-jumper-wire-cord-kit-for-arduino-diy-140-piece-pack-138220
2,54mm 1x40 Pin Breakaway tête droite (10 Pieces) :

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
*/

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

//*****************************************************************************
// Circuit à réaliser.
//*****************************************************************************
/*
Pour identifier les broches d'une planche d'expérimentation « BreanBoard »,
comme dans le jeu de bataille navale "Battle Ship", les lignes sont identifier
pas des numéro (ici, de 1 a 63) et les colonnes sont identifier par lettre des
lettre (ici, de a a j) et des signes (+) et (-). Donc, (i10) indique
l'intersection de la colonne "i" avec la ligne numéro "10".

Ici comme nous utilison deux planche d'expérimentation, nous ajoutons le
préfix "BB1" pour la plache numéro 1, celle de gauche et "BB2" pour la planche
numéro 2, celle de droite. Le "BB" étant le diminutif de « BreanBoard ». Au
final cela nous donne donc, (BB1i10) indique sur la planche 1, l'intersection
de la colonne "i" avec la ligne numéro "10".
*/

/*
Le circuit : (Voir la page Web :...)

Câblage de l'Arduino Mega sur la section 2 de la planche d'expérimentation
Circuit-Test MB-104 :

ARDUIBO_USB         : Par câble USB a un ordinateur
ARDUIBO_PWR12V      : En phase de test Adaptateur 9V, autonome piles 9V
ARDUINO_RESET       : LCD_1_RESET et câble a ARDUIBO_A7 (Kamikaze)
ARDUIBO_3_3V        :
ARDUIBO_5V_1        :
ARDUIBO_GND1        :
ARDUIBO_GND2        : LCD_1_J7_2, (-)
ARDUIBO_VIN         : LCD_1_J7_1, (+5V)

ARDUINO_A0          : LCD_1_SELECT
ARDUINO_A1          : LCD_1_UP
ARDUINO_A2          : LCD_1_RIGHT
ARDUINO_A3          : LCD_1_DOWN
ARDUINO_A4          : LCD_1_LEFT
ARDUIBO_A5          :
ARDUIBO_A6          :
ARDUIBO_A7          : ARDUIBO_RECET (Kamikaze par télécommande)

ARDUIBO_A8          :
ARDUIBO_A9          :
ARDUIBO_A10         :
ARDUIBO_A11         :
ARDUIBO_A12         :
ARDUIBO_A13         :
ARDUIBO_A14         :
ARDUIBO_A15         :

ARDUIBO_AREF        :
ARDUIBO_GND3        :
ARDUIBO_13_PWM_DEL  : DEL_1_PLUS
ARDUIBO_12_PWM      :
ARDUIBO_11_PWM      :
ARDUIBO_10_PWM      : LCD_1_A
ARDUIBO_9_PWM       : LCD_1_E
ARDUIBO_8_PWM       :

ARDUIBO_7_PWM       : LCD_1_D7
ARDUIBO_6_PWM       : LCD_1_D6
ARDUIBO_5_PWM       : LCD_1_D5
ARDUIBO_4_PWM       : LCD_1_D4
ARDUIBO_3_PWM_INT1  : LCD_1_D3
ARDUIBO_2_PWM_INT0  : LCD_1_D2
ARDUIBO_1_TX0       : LCD_1_D1
ARDUIBO_0_RX0       : LCD_1_D0

ARDUIBO_14_TX3      : CAPTEUR_IR_1_1SORTIE
ARDUIBO_15_RX3      : BOUTON_1_SORTIE
ARDUIBO_16_TX2      :
ARDUIBO_17_RX2      :
ARDUIBO_18_TX1_INT5 :
ARDUIBO_19_RX1_INT4 :
ARDUIBO_20_SDA_INT3 :
ARDUIBO_21_SCL_INT2 :

ARDUIBO_5V_2        :
ARDUIBO_5V_3        :
ARDUIBO_22          : Sonar_1_TRIG
ARDUIBO_23          : Sonar_1_ECHO
ARDUIBO_24          : Sonar_2_TRIG
ARDUIBO_25          : Sonar_2_ECHO
ARDUIBO_26          : Sonar_3_TRIG
ARDUIBO_27          : Sonar_3_ECHO
ARDUIBO_28          : CONTROLE_MOTEUR_1_IN4
ARDUIBO_29          :
ARDUIBO_30          : CONTROLE_MOTEUR_1_IN3
ARDUIBO_31          :
ARDUIBO_32          : CONTROLE_MOTEUR_1_IN2
ARDUIBO_33          :
ARDUIBO_34          : CONTROLE_MOTEUR_1_IN1
ARDUIBO_35          :
ARDUIBO_36          :
ARDUIBO_37          :
ARDUIBO_38          :
ARDUIBO_39          :
ARDUIBO_40          :
ARDUIBO_41          :
ARDUIBO_42          :
ARDUIBO_43          :
ARDUIBO_44_PWM      : CONTROLE_MOTEUR_1_ENA
ARDUIBO_45_PWM      : CONTROLE_MOTEUR_1_ENB
ARDUIBO_46_PWM      : SERVO_MOTEUR_SONAR_2
ARDUIBO_47          :
ARDUIBO_48          :
ARDUIBO_49          :
ARDUIBO_40          :
ARDUIBO_41          :
ARDUIBO_42          :
ARDUIBO_43          :
ARDUIBO_44          :
ARDUIBO_45          :
ARDUIBO_46          :
ARDUIBO_47          :
ARDUIBO_48          :
ARDUIBO_49          :
ARDUIBO_50_MISO     :
ARDUIBO_51_MOSI     :
ARDUIBO_52_SCK      : BOZZER_1_PLUS
ARDUIBO_53_SS       :
ARDUIBO_GND4        :
ARDUIBO_GND5        :

Câblage directe de la carte a écran LCD LCD1602-6Boutons sur la carte Arduino :
Diagramme : https://www.zartronic.fr/doc/E2/E2N1P193/LCD_Keypad_Shield_SCH.pdf

LCD_1_VSS    broche 1  : ARDUINO_GND_?
LCD_1_VDO    broche 2  : ARDUINO_5V_1
LCD_1_VO     broche 3  : ARDUINO_5V_1
LCD_1_RS     broche 4  : ARDUINO_8
LCD_1_RW     broche 5  : ARDUINO_GND_?
LCD_1_E      broche 6  : ARDUINO_9_PWM
LCD_1_D0     broche 7  :
LCD_1_D1     broche 8  :
LCD_1_D2     broche 9  :
LCD_1_D3     broche 10 :
LCD_1_D4     broche 11 : ARDUINO_4
LCD_1_D5     broche 12 : ARDUINO_5_PWM
LCD_1_D6     broche 13 : ARDUINO_6_PWM
LCD_1_D7     broche 14 : ARDUINO_7
LCD_1_A      broche 15 : ARDUINO_10_PWM
LCD_1_K      broche 16 : ARDUINO_GND_?

LCD_1_SELECT           : ARDUINO_A0
LCD_1_UP               : ARDUINO_A0
LCD_1_RIGHT            : ARDUINO_A0
LCD_1_DOWN             : ARDUINO_A0
LCD_1_LEFT             : ARDUINO_A0
LCD_1_RESET            : ARDUINO_RESET

LCD_1_J7_6             : ARDUINO_RESET
LCD_1_J7_5             : ARDUINO_3_3V
LCD_1_J7_4             : ARDUINO_5V_1
LCD_1_J7_3             : ARDUINO_GND1
LCD_1_J7_2             : ARDUINO_GND2
LCD_1_J7_1             : ARDUINO_VIN

LCD_1_J6_5             : ARDUINO_A1
LCD_1_J6_4             : ARDUINO_A2
LCD_1_J6_3             : ARDUINO_A3
LCD_1_J6_2             : ARDUINO_A4
LCD_1_J6_1             : ARDUINO_A5

LCD_1_J5_7             : ARDUINO_0
LCD_1_J5_6             : ARDUINO_1
LCD_1_J5_5             : ARDUINO_2
LCD_1_J5_4             : ARDUINO_3
LCD_1_J5_3             : ARDUINO_11
LCD_1_J5_2             : ARDUINO_12
LCD_1_J5_1             : ARDUINO_13

LCD_1_ICSP_1           : ARDUINO_12
LCD_1_ICSP_2           : ARDUINO_5V_1
LCD_1_ICSP_3           : ARDUINO_13
LCD_1_ICSP_4           : ARDUINO_11
LCD_1_ICSP_5           : ARDUINO_RESET
LCD_1_ICSP_5           : ARDUINO_GND_?

Câblage pour le module a ultrason, sur la section 2 de la planche
d'expérimentation et l'arduino :

Sonar_1_VCC  : (+)
Sonar_1_TRIG : ARDUIBO_22
Sonar_1_ECHO : ARDUIBO_23
Sonar_1_GND  : (-)

Câblage pour le module a ultrason, sur la section 2 de la planche
d'expérimentation et l'arduino :

Sonar_2_VCC  : (+)
Sonar_2_TRIG : ARDUIBO_24
Sonar_2_ECHO : ARDUIBO_25
Sonar_2_GND  : (-)

Câblage pour le module a ultrason, sur la section 2 de la planche
d'expérimentation et l'arduino :

Sonar_3_VCC  : (+)
Sonar_3_TRIG : ARDUIBO_26
Sonar_3_ECHO : ARDUIBO_27
Sonar_3_GND  : (-)

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

CAPTEUR_IR_1_1SORTIE : ARDUIBO_14
CAPTEUR_IR_1_2GND    : (-)
CAPTEUR_IR_1_3VIN    : (+)

Câblage pour le Buzzer sur la planche d'expérimentation et l'Arduino :

BOZZER_1_PLUS  : ARDUIBO_52
BOZZER_1_MOINS : ARDUIBO_GND4

Câblage pour la DEL verte sur la planche d'expérimentation et l'Arduino :

DEL_1_PLUS         : (i49) et cable a ARDUIBO_22 (ou la DEL ARDUINO_13)
DEL_1_MOINS        : (i51)
Résistance330_Ohm1 : (j51)
Résistance330_Ohm2 : (-51D)

Câblage pour les deux moteur pas-a-pas sur la section 1 et 2 de la planche
d'expérimentation :

Câblage du controle moteur 1 :

CONTROLE_MOTEUR_1_VIN     : (+57G), du 6V~12V
CONTROLE_MOTEUR_1_NEGATIF : (-57G)
CONTROLE_MOTEUR_1_5V      : (+61D)
CONTROLE_MOTEUR_1_ENA     : ARDUIBO_44
CONTROLE_MOTEUR_1_IN1     : ARDUIBO_34
CONTROLE_MOTEUR_1_IN2     : ARDUIBO_32
CONTROLE_MOTEUR_1_ENB     : ARDUIBO_45
CONTROLE_MOTEUR_1_IN3     : ARDUIBO_30
CONTROLE_MOTEUR_1_IN4     : ARDUIBO_28
CONTROLE_MOTEUR_1_OUT1    : Moteur1_Plus
CONTROLE_MOTEUR_1_OUT2    : Moteur1_Moins
CONTROLE_MOTEUR_1_OUT3    : Moteur2_Moins
CONTROLE_MOTEUR_1_OUT4    : Moteur2_Plus

Câblage pour le servo moteur, sur la section 1 de la planche
d'expérimentation :

SERVO_MOTEUR_SONAR_1 : (-)
SERVO_MOTEUR_SONAR_1 : (+5V)
SERVO_MOTEUR_SONAR_1 : ARDUIBO_46
*/

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

//*****************************************************************************
// Inclusion des librairies utilisées.
//*****************************************************************************
#include <LiquidCrystal.h>
/*
« Cette librairie permet à une carte Arduino de contrôler un afficheur LCD
alphanumérique standard à cristaux liquides basé sur le circuit intégré Hitachi
HD44780 (ou compatible), ce qui est le cas de la plupart des afficheurs
alphanumériques LCD disponibles. La librairie fonctionne aussi bien en mode 4
bits qu'en mode 8 bits (càd utilisant 4 ou 8 broches numériques en plus des
broches de contrôle RS, Enable et RW (optionnel)). Ainsi, en mode 4 bits,
6 broches numériques de la carte Arduino suffisent pour contrôler un afficheur
LCD alphanumérique.

Référence : https://arduino.cc/fr/Main/LibrairieLCD
*/


#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èque Arduino « ~/Arduino/libraries/IRremote ». Pour avoir accès à la
nouvelle bibliothèque, vous devez redémarrer l'éditeur Arduino. 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

Merci à cette personne pour sa contribution !
*/


#include <Servo.h>
/*
Cette librairie permet à une carte Arduino de contrôler les servomoteurs de
modélisme. Les servomoteurs intègrent un mécanisme et un axe qui peut-être
contrôlé précisément. Les servomoteurs standards permettent de positionner
l'axe à différents angles, habituellement entre 0 et 180 degrès (ces
servomoteurs permettent de maintenir l'axe à une position précise). Les
servomoteurs à rotation continue permettent des rotations de l'axe à
différentes vitesses.

A partir d'Arduino 0017, la librairie Servo supporte jusqu'à 12 servomoteurs
sur la plupart des cartes Arduino (la Duemilanove par exemple) et 48 sur
l'Arduino Mega. Sur les cartes autres que la Mega, l'utilisation de la
librairie Servo désactive l'instruction analogWrite() sur les broches 9 et
10, qu'il y ait ou non un servomoteur sur ces broches. Sur la Mega, jusqu'à 12
servomoteurs peuvent être utilisés sans interférer avec la fonction PWM (càd
avec l'instruction analogWrite); utiliser de 12 à 23 servomoteurs désactivera
les impulsions PWM sur les broches 11 et 12. (Note : PWM pour Pulse Width
Modulation ou Modulation de Largeur d'Impulsion).

Avec Arduino 0016 et précédent, la librairie Servo utilise la fonction
fournie par le matériel (càd l'ATmega de la carte), et fonctionne uniquement
sur les broches 9 et 10 (et ne fonctionne pas sur l'Arduino Mega). Dans ce
cas, si seulement un servomoteur est utilisé, l'autre broche ne peut pas être
utilisée pour générer une sortie PWM normale avec l'instruction analogWrite().
Par exemple, avec Arduino 0016 et précédent, vous ne pouvez avoir un
servomoteur sur la broche 9 et une sortie PWM sur la broche 10.

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

/*
La librairie Stepper pour le contrôle des moteurs pas à pas :
https://arduino.cc/fr/Main/LibrairieStepper
*/


//#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
*/


#include "TelecommandeValeurBoutons.h"
/*
Fichier contenant la valeur envoyée pour chaque boutons de la télécommande.
*/


#include "NotesDeMusique.h"
/*
Fichier contenant les définitions de notes de musique.
*/

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

//*****************************************************************************
// Déclaration des constantes de base pour franciser le code source.
//*****************************************************************************
/*
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 « 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;
//*****************************************************************************

//*****************************************************************************
// Déclaration des constantes des connecteurs Arduino.
//*****************************************************************************
// En prévision d'un ARDUINO_RESET par télécommande.
const byte ARDUINO_RESET = A7;

// Broche d'Arduino pour le controleur moteur 1 (double Pont en H).
const byte CONTROLE_MOTEUR_1_ENA = 44;
const byte CONTROLE_MOTEUR_1_ENB = 45;
const byte CONTROLE_MOTEUR_1_IN1 = 34;
const byte CONTROLE_MOTEUR_1_IN2 = 32;
const byte CONTROLE_MOTEUR_1_IN3 = 30;
const byte CONTROLE_MOTEUR_1_IN4 = 28;

// Pour gérer l'action d'humains le bouton de la planche d'expérimentation.
const byte BOUTON_1_SORTIE = 15;

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

// Câblage pour la DEL verte sur la planche d'expérimentation et l'Arduino
const byte DEL_1_PLUS = 13;

// Broche d'Arduino pour le capteur a ultrason 1, le sonar.
const byte Sonar_1_TRIG = 22;
const byte Sonar_1_ECHO = 23;

// Broche d'Arduino pour le capteur a ultrason 2, le sonar.
const byte Sonar_2_TRIG = 24;
const byte Sonar_2_ECHO = 25;

// Broche d'Arduino pour le capteur a ultrason 3, le sonar.
const byte Sonar_3_TRIG = 26;
const byte Sonar_3_ECHO = 27;

// Constantes des broches sur l'Arduino pour une carte LCD1602.
const byte LCD_1_RS      = 8;// Écran LCD.
const byte LCD_1_E       = 9;// Écran LCD.
const byte LCD_1_D4      = 4;// Écran LCD.
const byte LCD_1_D5      = 5;// Écran LCD.
const byte LCD_1_D6      = 6;// Écran LCD.
const byte LCD_1_D7      = 7;// Écran LCD.
const byte LCD_1_A       = 10;// Écran LCD controle la liminosité arriere.
const byte LCD_1_SELECT  = A0;// Carte écran LCD 1 boutons
const byte LCD_1_UP      = A0;// Carte écran LCD 2 boutons
const byte LCD_1_RIGHT   = A0;// Carte écran LCD 3 boutons
const byte LCD_1_DOWN    = A0;// Carte écran LCD 4 boutons
const byte LCD_1_LEFT    = A0;// Carte écran LCD 5 boutons
const byte LCD_1_BOUTONS = A0;// Pour la gestion des boutons

// Constantes des parametres de l'objet ECRAN_LCD.
// Nombre de lignes et de colonnes.
const byte LCD_1_NOMBRE_DE_COLONNES = 16;
const byte LCD_1_NOMBRE_DE_LIGNES   = 2;
// Par le passage d'une résistance, la valeur indiquant le bon bouton pressé.
const int LCD_1_VALEUR_SELECT = 800;
const int LCD_1_VALEUR_UP     = 200;
const int LCD_1_VALEUR_RIGHT  = 100;
const int LCD_1_VALEUR_DOWN   = 400;
const int LCD_1_VALEUR_LEFT   = 600;
// Aucun bouton n'est pressé.
const int LCD_1_VALEUR_AUCUN  = 1023;

// Câblage pour le Buzzer sur la planche d'expérimentation et l'Arduino :
const byte BOZZER_1_PLUS = 52;

// Attribution du port Arduino controlent le servo moteur.
const byte SERVO_MOTEUR_SONAR_1 = 46;// DigitalPWM
//*****************************************************************************

//*****************************************************************************
// Déclaration des autres constantes de travail.
//*****************************************************************************
const long MOTEUR_1_VITESSE_MAXIMUM = 255;
const long MOTEUR_2_VITESSE_MAXIMUM = MOTEUR_1_VITESSE_MAXIMUM;
const long MOTEUR_1_VITESSE_MINIMUM = 255;// C'est le plus bas possible.
const long MOTEUR_2_VITESSE_MINIMUM = MOTEUR_1_VITESSE_MINIMUM;
//*****************************************************************************

//*****************************************************************************
// Déclaration des variables globales.
//*****************************************************************************
/*
Par convention, pour nommer une variable, nous utiliserons des noms écrits
avec un 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 controlera 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'exeption d'initialiser ses périphériques.
*/

boolean Boucler = NON;

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

// Variable recevant la valeur du bouton pressé, entre 0 et 1023.
int LCD_1Bouton = 0;

int LCD_1FondEcranValeur = 255;// Ne fontionne pas avec 254 et moins.

// Pour contenir la valeur du dernier bouton pressé sur la télécommande.
unsigned long TelecommandeBoutonValeur = 0;

// Afficher les données dans le moniteur série d'Arduino (débogage).
boolean AffichageMoniteurSerie = NON;
boolean AffichageEcranLCD = OUI;

// Déclaration des variables pour le servo moteur.
// largeur impulsion pour position 0° servomoteur TowerPro SG90.
int ServoMoteurSonar_1PositionMinimum = 500;
// largeur impulsion pour position 180° servomoteur TowerPro SG90.
int ServoMoteurSonar_1PositionMaximum = 2400;
// Variable recevant la valeur de l'angle du servo moteur.
float ServoMoteurSonar_1AngleMinimum = 0;// Selon les datasheet.
float ServoMoteurSonar_1AngleMaximum = 180;// Selon les datasheet.
float ServoMoteurSonar_1AngleCentre =
((ServoMoteurSonar_1AngleMaximum - ServoMoteurSonar_1AngleMinimum) / 2);
float ServoMoteurSonar_1Angle = ServoMoteurSonar_1AngleCentre;

float LargeureChampDeBalayage = ServoMoteurSonar_1AngleMaximum;
int DelaiEntreMesuresUltrason = 0;// En milliseconde.
// Les valeurs des changements d'un angle a un autre, le Pas.
float ServoMoteurSonar_1AnglePasDefaut = 2;
float ServoMoteurSonar_1AnglePas = ServoMoteurSonar_1AnglePasDefaut;
// La vitesse a la quelle l'angle changera.
int ServoMoteurSonar_1VitesseDefaut = 10;
int ServoMoteurSonar_1Vitesse = ServoMoteurSonar_1VitesseDefaut;

// Distance limite pour la fiabilité des mesure du sonar.
float Sonar_1DistanceValideMaximum = 400.0;
float Sonar_2DistanceValideMaximum = 400.0;
float Sonar_3DistanceValideMaximum = 400.0;

// Pour contrer l'imprécission des echos sonars, deux lecture et la moyene.
int NombreDeLecture = 5;
// Dernire valeur fournit par le sonar.
float Sonar_1DistanceActuele = 0.0;
float Sonar_2DistanceActuele = 0.0;
float Sonar_3DistanceActuele = 0.0;
float DistanceMaximumTrouve = 0;
float DistanceMaximumTrouveAngle = 0;
// Variables pour établir la durée de la commande ping,
// Et le résultat de la distance en pouces et en centimètres:
float Sonar_1DureeEchoSonar = 0.0;
float Sonar_2DureeEchoSonar = 0.0;
float Sonar_3DureeEchoSonar = 0.0;

// Délai pour réduire la vitesse de réaction entre les lectues des boutons.
int TempsRebonBouton = 9;

// Contiend la vitesse moteur a applique et donc aussi la vitesse courante.
int ControleMoteur1Vitesse = 0;
int ControleMoteur2Vitesse = 0;
//*****************************************************************************

//*****************************************************************************
// Création en mémoire des objet pour les interfaces des périphériques.
//*****************************************************************************
// Créer et initialisation LCD en mode 4 bits.
LiquidCrystal LCD_1 (LCD_1_RS, LCD_1_E, LCD_1_D4, LCD_1_D5, LCD_1_D6, LCD_1_D7);

// Pour le capteur infrarouge crée un objet sur la broche voulue.
IRrecv         Capteur_IR_1 (CAPTEUR_IR_1_1SORTIE);
decode_results Capteur_IR_1_Results;

// Pour le contrôle du servomoteur 1 du capteur a ultrason.
Servo ServoMoteurSonar_1;
//*****************************************************************************

//*****************************************************************************
// 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 utilisant une boucle « while »,
tant qu'une première action n'est pas accompli 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);
  Serial.println ();
  Serial.println ();
  Serial.print ("***********************************************************");
  Serial.println ();
  Serial.print ("*   Debut de la procedure d'initialisation du systeme...  *");
  Serial.println ();
  Serial.print ("***********************************************************");
  Serial.println ();

  // Le minimum de connecteurs en entrées et sorties d'activé par sécurité
  // en cas de changement des port de connexion.

  // Pour le bouton Marche/Arrêt sur la planche d'expérimentation.
  // Configurer le port Arduino en entrée pour le bouton.
  pinMode (BOUTON_1_SORTIE, ENTREE);
  // Activer la résistance au plus PULLUP.
  digitalWrite (BOUTON_1_SORTIE, HAUT);

  // Pour l'intencité du rétro-éclairage de l'écran LCD.
  pinMode (LCD_1_A, SORTIE);
  analogWrite (LCD_1_A, LCD_1FondEcranValeur);

  // Pour affichage dans l'écran LCD.
  LCD_1.begin (LCD_1_NOMBRE_DE_COLONNES, LCD_1_NOMBRE_DE_LIGNES);
  LCD_1.clear ();
  LCD_1.noCursor ();
  LCD_1.setCursor (0,0);
  LCD_1.print ("Bouton (SELECT)!");

  // Configurer le port Arduino en entrée pour le capteur infrarouge.
  pinMode (CAPTEUR_IR_1_1SORTIE, ENTREE);
  // Initialisation et début de la réception du capteur infrarouge.
  Capteur_IR_1.enableIRIn ();
  Serial.print ("* Activation du capteur infrarouge pour la telecommande   *");
  Serial.println ();
  Serial.print ("***********************************************************");
  Serial.println ();
  Serial.print ("* Attante : Telecommande (Power) ou Bouton MarcheArret... *");
  Serial.println ();
  Serial.print ("***********************************************************");
  Serial.println ();

  // Boucle pour éviter qu'un ancien programme 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.
  while (Boucler != OUI)
  {
    GererBoutons ();
  }

  // Active la DEL de l'Arduino.
  pinMode (DEL_1_PLUS, SORTIE);
  digitalWrite (DEL_1_PLUS, Boucler);
  Serial.print ("* Activation de la DEL d'ArduiRobot                       *");
  Serial.println ();

  // Fixer le BOZZER_1_PLUS en sortie.
  pinMode (BOZZER_1_PLUS, OUTPUT);
  Serial.print ("* Activation de la broche pour le Buzzer d'ArduiRobot     *");
  Serial.println ();

  // Pour les moteurs de déplacement du véhicule sur les port de l'Arduino.
  // Ajustement initial de la vitesse moteur 1 et 2, a l'arret.
  // Moteur a l'arret, au cas ou.
  pinMode (CONTROLE_MOTEUR_1_ENA, OUTPUT);
  pinMode (CONTROLE_MOTEUR_1_IN1, OUTPUT);
  pinMode (CONTROLE_MOTEUR_1_IN2, OUTPUT);
  pinMode (CONTROLE_MOTEUR_1_ENB, OUTPUT);
  pinMode (CONTROLE_MOTEUR_1_IN3, OUTPUT);
  pinMode (CONTROLE_MOTEUR_1_IN4, OUTPUT);
  LCD_1.clear ();

  // Test des vitesses variable, décommentez la ligne ci-dessous.
  // InitialiserMoteursCC ();

  Serial.print ("* Moteurs des roues d'ArduiRobot a l'arret                *");
  Serial.println ();
  DeplacementArreter ();

  // Initialisation du servo moteur.
  // C'EST ICI QUE LE BOGUE COMMANCE ###########################################
  ServoMoteurSonar_1.attach (SERVO_MOTEUR_SONAR_1,
                             ServoMoteurSonar_1PositionMinimum,
                             ServoMoteurSonar_1PositionMaximum);

  Serial.print ("* Activation du servomoteur du sonar d'ArduiRobot         *");
  Serial.println ();

  ServoMoteurSonar_1.write (ServoMoteurSonar_1Angle);
  delay (UneSeconde);
  Serial.print ("* Centrage du servomoteur du sonar d'ArduiRobot           *");
  Serial.println ();
  Serial.print ("* ServoMoteurSonar_1Angle : ");
  Serial.print (ServoMoteurSonar_1Angle);
  Serial.print ("                         *");
  Serial.println ();
  Serial.print ("* Delai                   : ");
  Serial.print (DelaiEntreMesuresUltrason);
  Serial.print ("                             *");
  Serial.println ();
  Serial.print ("* DistanceMaximum         : ");
  Serial.print (Sonar_1DistanceValideMaximum);
  Serial.print ("                        *");
  Serial.println ();

  // Pour le sonar, activation des port de l'Arduino.
  pinMode (Sonar_1_TRIG, SORTIE);
  pinMode (Sonar_1_ECHO, ENTREE);
  Serial.print ("* Activation du sonar 1 d'ArduiRobot                      *");
  Serial.println ();
  pinMode (Sonar_2_TRIG, SORTIE);
  pinMode (Sonar_2_ECHO, ENTREE);
  Serial.print ("* Activation du sonar 2 d'ArduiRobot                      *");
  Serial.println ();
  pinMode (Sonar_3_TRIG, SORTIE);
  pinMode (Sonar_3_ECHO, ENTREE);
  Serial.print ("* Activation du sonar 3 d'ArduiRobot                      *");
  Serial.println ();

  Serial.print ("* Moteurs des roues d'ArduiRobot a l'arret                *");
  Serial.println ();

  // Message de la fin du processus d'initialisation du systme.
  Serial.print ("***********************************************************");
  Serial.println ();
  Serial.print ("*    Fin de la procedure d'initialisation du systeme...   *");
  Serial.println ();
  Serial.print ("***********************************************************");
  Serial.println ();
  Serial.println ();

  // Pour affichage dans l'écran LCD.
  LCD_1.clear ();
  LCD_1.setCursor (0,0);
  LCD_1.print (">>>>>> OK <<<<<<");
  LCD_1.setCursor (0,1);
  LCD_1.print (">>>>>> GO <<<<<<");
}
//*****************************************************************************

//*****************************************************************************
// 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.
  GererBoutons ();
  if (Boucler == OUI)
  {
    GererDeplacements ();
  }
}
//*****************************************************************************

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

//*****************************************************************************
// FONCTION GererBoutonMarcheArret
//*****************************************************************************
/*
Gestion de l'utilisation d'un bouton sur la planche d'expérimentation.
*/

void GererBoutonMarcheArret ()
{
  int EtatBouton = digitalRead (BOUTON_1_SORTIE);
  if (EtatBouton == HAUT)
  {
    Serial.print ("Le bouton Marche Arret enclenche");
    Serial.println ();
    if (Boucler == OUI)
    {
      Boucler = NON;
      // Éteindre la DEL de l'Arduino.
      digitalWrite (DEL_1_PLUS, Boucler);
      Serial.print ("En attente d'une action d'humaine");
      Serial.println ();
      DeplacementArreter ();
    }
    else
    {
      Boucler = OUI;
      // Allumer la DEL de l'Arduino.
      digitalWrite (DEL_1_PLUS, Boucler);
      Serial.print ("Poursuite du programme");
      Serial.println ();
    }
    while (EtatBouton == HAUT)
    {
      delay (5);// Pour absorber les micro-coupures des rebonds (5 ms).
      EtatBouton = digitalRead (BOUTON_1_SORTIE);
    }
  }
}
//*****************************************************************************

//*****************************************************************************
// FONCTION GererBoutonEcranLCD
//*****************************************************************************
void GererBoutonEcranLCD ()
/*
Gérer l'utilisation de 5 des 6 bouton de la carte LCD1602Sheild.

Le bouton RESET de l'écran LCD est directement relié a la broche ARDUINO_RESET,
donc du redémarrage du Système complet. Tous les autres boutons (5) sont
listés et ont un effet sur le déroulement de la boucle principale ou sur les
paramètres de fonctionnement de l'écran ou les deux la fois.

En synthèse les boutons font :

_SELECT : Gere l'exécution de la boucle principale du programme.
_UP     : Augmente la luminosité du fond d'écran.
_DOWN   : Diminue la luminosité du fond d'écran.
_LEFT   : Active/désactive le parametre blink/noBlink.
_RIGHT  : Active/désactive le parametre display/noDisplay.
*/

{
  LCD_1Bouton = analogRead (LCD_1_BOUTONS);
  if (LCD_1Bouton == LCD_1_VALEUR_AUCUN)
  {
    // On ne fait rien pour le moment.
  }
  else if (LCD_1Bouton < LCD_1_VALEUR_RIGHT)
  {
    LCD_1.blink ();// Fait clignoter le curseur
    Serial.println (LCD_1Bouton);
  }
  else if (LCD_1Bouton < LCD_1_VALEUR_UP)
  {
    LCD_1FondEcranValeur = constrain ((LCD_1FondEcranValeur+5),0,255);
    analogWrite (LCD_1_A, LCD_1FondEcranValeur);
    Serial.println (LCD_1Bouton);
    Serial.print ("LCD_1FondEcranValeur = ");
    Serial.print (LCD_1FondEcranValeur);
    Serial.println ();
  }
  else if (LCD_1Bouton < LCD_1_VALEUR_DOWN)
  {
    LCD_1FondEcranValeur = constrain ((LCD_1FondEcranValeur-5),0,255);
    analogWrite (LCD_1_A, LCD_1FondEcranValeur);
    Serial.println (LCD_1Bouton);
    Serial.print ("LCD_1FondEcranValeur = ");
    Serial.print (LCD_1FondEcranValeur);
    Serial.println ();
  }
  else if (LCD_1Bouton < LCD_1_VALEUR_LEFT)
  {
    LCD_1.noBlink ();// Arrete le clignotement du curseur
    Serial.println (LCD_1Bouton);
  }
  else if (LCD_1Bouton < LCD_1_VALEUR_SELECT)
  {
    Boucler = 1 - Boucler;
    Serial.println (LCD_1Bouton);
  }
  // Attendre la relâche de la touche.
  while (LCD_1Bouton != LCD_1_VALEUR_AUCUN)
  {
    // Absorber les microcoupures des rebonds (5 ms).
    delay (5);
    // Récuperer la valeur suivante.
    LCD_1Bouton = analogRead (LCD_1_BOUTONS);
  }
}
//*****************************************************************************

//*****************************************************************************
// 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 « Mode » 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      : Bouton kamikaze qui utilise la broche RESET de la carte Arduino.
Son       :
PlayPause :
Debut     :  
Fin       :  
EQ        :
Moins     :
Plus      :
0         :
Recycle   :
U_SD      :
1         :
2         :
3         :
4         :
5         :
6         :
7         :
8         :
9         :
default   : Une télécommande génère beaucoup d'autres codes qui sont inutiles ici.
*/

void GererBoutonTeleCommande ()
{
  if (Capteur_IR_1.decode (&Capteur_IR_1_Results))
  {
    Capteur_IR_1.resume (); // Récupérer la valeur suivante.
    TelecommandeBoutonValeur = Capteur_IR_1_Results.value;
    switch (TelecommandeBoutonValeur)
    {
    case TelecommandeBoutonPower:
      Serial.print (" TelecommandeBoutonPower : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      if (Boucler == OUI)
      {
        Boucler = NON;
        digitalWrite (DEL_1_PLUS, Boucler);
        Serial.print ("En attente d'une action d'humaine");
        Serial.println ();
        DeplacementArreter ();
      }
      else
      {
        Boucler = OUI;
        digitalWrite (DEL_1_PLUS, Boucler);
        Serial.print ("Poursuite du programme");
        Serial.println ();
      }
      break;
    case TelecommandeBoutonMode:
      Serial.print (" TelecommandeBoutonMode : ");
      Serial.print (TelecommandeBoutonValeur);
      // Configurer le port Arduino pour un RESET par télécommande.
      pinMode (ARDUINO_RESET, SORTIE);
      // Activer la broche ARDUINO_RESET.
      digitalWrite (ARDUINO_RESET, BAS);
      delay (UneSeconde);
      Serial.println ();
      break;
    case TelecommandeBoutonSon:
      Serial.print (" TelecommandeBoutonSon : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBoutonPlayPause:
      Serial.print (" TelecommandeBoutonPlayPause : ");
      Serial.print (TelecommandeBoutonValeur);
      if (Boucler == OUI)
      {
        Boucler = NON;
        digitalWrite (DEL_1_PLUS, Boucler);
        Serial.print ("En attente d'une action d'humaine");
        Serial.println ();
        DeplacementArreter ();
      }
      else
      {
        Boucler = OUI;
        digitalWrite (DEL_1_PLUS, Boucler);
        Serial.print ("Poursuite du programme");
        Serial.println ();
      }
      Serial.println ();
      break;
    case TelecommandeBoutonDebut:
      Serial.print (" TelecommandeBoutonDebut : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBoutonFin:
      Serial.print (" TelecommandeBoutonFin : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBoutonEQ:
      Serial.print (" TelecommandeBoutonEQ : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBoutonMoins:
      Serial.print (" TelecommandeBoutonMoins : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBoutonPlus:
      Serial.print (" TelecommandeBoutonPlus : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBouton0:
      Serial.print (" TelecommandeBouton0 : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBoutonRecycle:
      Serial.print (" TelecommandeBoutonRecycle : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBoutonU_SD:
      Serial.print (" TelecommandeBoutonU_SD : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBouton1:
      Serial.print (" TelecommandeBouton1 : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBouton2:
      Serial.print (" TelecommandeBouton2 : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBouton3:
      Serial.print (" TelecommandeBouton3 : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBouton4:
      Serial.print (" TelecommandeBouton4 : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBouton5:
      Serial.print (" TelecommandeBouton5 : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBouton6:
      Serial.print (" TelecommandeBouton6 : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBouton7:
      Serial.print (" TelecommandeBouton7 : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBouton8:
      Serial.print (" TelecommandeBouton8 : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    case TelecommandeBouton9:
      Serial.print (" TelecommandeBouton9 : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      break;
    default:
      Serial.print (" Code inconnu : ");
      Serial.print (TelecommandeBoutonValeur);
      Serial.println ();
      ;
    }
  }
  while (Capteur_IR_1.decode (&Capteur_IR_1_Results))
  {
    delay (5);// Pour absorber les micro-coupures des rebonds (5 ms).
    Capteur_IR_1.resume (); // Récupéré la valeur suivante.
    TelecommandeBoutonValeur = Capteur_IR_1_Results.value;
  }
}
//*****************************************************************************

//*****************************************************************************
// FONCTION GererBoutons
//*****************************************************************************
void GererBoutons ()
{
  GererBoutonMarcheArret (); // Un bouton sur planche d'expérimentation.
  GererBoutonEcranLCD ();    // 6 boutons sur module d'écran LCD.
  GererBoutonTeleCommande ();// 21 boutons d'une télécommande type MP3.
}
//*****************************************************************************

//*****************************************************************************
// FONCTION GererDeplacements
//*****************************************************************************
void GererDeplacements ()
{
  float Distance1 = 12.0;
  float Distance2 = 20.0;
  float Distance3 = 100.0;

  CapteurUltrasonLecture ();
  //Serial.print ("GererDeplacements");
  //Serial.println ();

  if (Sonar_2DistanceActuele <= Distance1)
  {
    DeplacementArreter ();
    while (Sonar_2DistanceActuele < Distance1)
    {
      DeplacementReculer ();
      CapteurUltrasonLecture ();
      GererBoutons ();
    }
    DeplacementArreter ();
  }

  if ((Sonar_2DistanceActuele > Distance1) and (Sonar_2DistanceActuele <= Distance2))
  {
    DeplacementArreter ();
    TrouverPlusGrandDegagement ();
    CapAuPlusGrandDegagement ();
  }

  if ((Sonar_2DistanceActuele > Distance2) and (Sonar_2DistanceActuele <= Distance3))
  {
    DeplacementAvancer ();
  }

  if (Sonar_2DistanceActuele > Distance3)
  {
    SortieTrouve ();
  }
}
//*****************************************************************************

//*****************************************************************************
// FONCTION CapteurUltrasonLecture
//*****************************************************************************
void CapteurUltrasonLecture ()
{
  // Pour contrer l'imprécission des echos sonars, deux lecture et la moyene.
  float EchosSonar1 [NombreDeLecture];
  float EchosSonar2 [NombreDeLecture];
  float EchosSonar3 [NombreDeLecture];
  float TotalDistanceEcho1 = 0.0;
  float TotalDistanceEcho2 = 0.0;
  float TotalDistanceEcho3 = 0.0;
  float MoyenneDistanceEcho1 = 0.0;
  float MoyenneDistanceEcho2 = 0.0;
  float MoyenneDistanceEcho3 = 0.0;
  for (int i = 0; i < NombreDeLecture; i = i + 1)
  {
    CapteurUltrasonUneLecture ();
    EchosSonar1 [i] = Sonar_1DistanceActuele;
    EchosSonar2 [i] = Sonar_2DistanceActuele;
    EchosSonar3 [i] = Sonar_3DistanceActuele;
  }

  for (int i = 0; i < NombreDeLecture; i = i + 1)
  {
    TotalDistanceEcho1 = TotalDistanceEcho1 + EchosSonar1 [i];
    TotalDistanceEcho2 = TotalDistanceEcho2 + EchosSonar2 [i];
    TotalDistanceEcho3 = TotalDistanceEcho3 + EchosSonar3 [i];
  }

  MoyenneDistanceEcho1 = TotalDistanceEcho1 / (NombreDeLecture + 1);
  MoyenneDistanceEcho2 = TotalDistanceEcho2 / (NombreDeLecture + 1);
  MoyenneDistanceEcho3 = TotalDistanceEcho3 / (NombreDeLecture + 1);
  Sonar_1DistanceActuele = MoyenneDistanceEcho1;
  Sonar_2DistanceActuele = MoyenneDistanceEcho2;
  Sonar_3DistanceActuele = MoyenneDistanceEcho3;

  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION CapteurUltrasonUneLecture
//*****************************************************************************
void CapteurUltrasonUneLecture ()
{
  /* Le capteur est déclenché par une impulsion haute d'au moins
  10 microsecondes. Donne une courte impulsion basse à l'avance pour assurer
  une impulsion HIGH propre:
  */

  // Lecture echo sonar 1
  delayMicroseconds (2);
  digitalWrite (Sonar_1_TRIG, HIGH);
  delayMicroseconds (10);
  digitalWrite (Sonar_1_TRIG, LOW);
  Sonar_1DureeEchoSonar = pulseIn (Sonar_1_ECHO, HIGH);
  // convertir le temps en une distance
  Sonar_1DistanceActuele = ConvertionMicrosecondsEnCentimetres
                           (Sonar_1DureeEchoSonar);
  // Limiter la distance mesurée a la valeur de Sonar_1DistanceValideMaximum.
  // Limiter la distance mesurée a la valeur de Sonar_1DistanceValideMaximum.
  if (Sonar_1DistanceActuele > Sonar_1DistanceValideMaximum)
  {
    Sonar_1DistanceActuele = Sonar_1DistanceValideMaximum;
  }

  // Lecture echo sonar 2
  delayMicroseconds (2);
  digitalWrite (Sonar_2_TRIG, HIGH);
  delayMicroseconds (10);
  digitalWrite (Sonar_2_TRIG, LOW);
  Sonar_2DureeEchoSonar = pulseIn (Sonar_2_ECHO, HIGH);
  // convertir le temps en une distance
  Sonar_2DistanceActuele = ConvertionMicrosecondsEnCentimetres
                           (Sonar_2DureeEchoSonar);
  // Limiter la distance mesurée a la valeur de Sonar_1DistanceValideMaximum.
  // Limiter la distance mesurée a la valeur de Sonar_1DistanceValideMaximum.
  if (Sonar_2DistanceActuele > Sonar_2DistanceValideMaximum)
  {
    Sonar_2DistanceActuele = Sonar_2DistanceValideMaximum;
  }

  // Lecture echo sonar 3
  delayMicroseconds (2);
  digitalWrite (Sonar_3_TRIG, HIGH);
  delayMicroseconds (10);
  digitalWrite (Sonar_3_TRIG, LOW);
  Sonar_3DureeEchoSonar = pulseIn (Sonar_3_ECHO, HIGH);
  // convertir le temps en une distance
  Sonar_3DistanceActuele = ConvertionMicrosecondsEnCentimetres
                           (Sonar_3DureeEchoSonar);
  // Limiter la distance mesurée a la valeur de Sonar_1DistanceValideMaximum.
  // Limiter la distance mesurée a la valeur de Sonar_1DistanceValideMaximum.
  if (Sonar_3DistanceActuele > Sonar_3DistanceValideMaximum)
  {
    Sonar_3DistanceActuele = Sonar_3DistanceValideMaximum;
  }
  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION TrouverPlusGrandDegagement
//*****************************************************************************
void TrouverPlusGrandDegagement ()
{
  Serial.print ("TrouverPlusGrandDegagement");
  Serial.println ();
  DistanceMaximumTrouve = 0;
  DistanceMaximumTrouveAngle = 0;
  // Un baleillage de tout le champs de rotation du servo moteur du sonar.
  ServoMoteurSonar_1Angle = ServoMoteurSonar_1AngleMinimum;
  ServoMoteurSonar_1.write (ServoMoteurSonar_1Angle);
  while (ServoMoteurSonar_1Angle < ServoMoteurSonar_1AngleMaximum)
  {
    Serial.print ("ServoMoteurSonar_1Angle : ");
    Serial.print (ServoMoteurSonar_1Angle);
    Serial.println ();
    ServoMoteurSonar_1.write (ServoMoteurSonar_1Angle);
    delay (DelaiEntreMesuresUltrason);
    CapteurUltrasonLecture ();
    if (DistanceMaximumTrouve <= Sonar_2DistanceActuele)
    {
      DistanceMaximumTrouve = Sonar_2DistanceActuele;
      DistanceMaximumTrouveAngle = ServoMoteurSonar_1Angle;
      Serial.println ();
    }
    Serial.print ("Sonar_2DistanceActuele : ");
    Serial.print (Sonar_2DistanceActuele);
    Serial.print (" DistanceMaximumTrouve : ");
    Serial.print (DistanceMaximumTrouve);
    Serial.println ();
    ServoMoteurSonar_1Angle = ServoMoteurSonar_1Angle + ServoMoteurSonar_1AnglePas;
    GererBoutons ();
  }
  ServoMoteurSonar_1Angle = DistanceMaximumTrouveAngle;
  ServoMoteurSonar_1.write (ServoMoteurSonar_1Angle);
  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION CapAuPlusGrandDegagement
//*****************************************************************************
void CapAuPlusGrandDegagement ()
{
  Serial.print ("CapAuPlusGrandDegagement");
  Serial.println ();
  while (int (ServoMoteurSonar_1Angle) != int (ServoMoteurSonar_1AngleCentre))
  {
    if (ServoMoteurSonar_1Angle < ServoMoteurSonar_1AngleCentre)
    {
      DeplacementReculerGauche ();
      ServoMoteurSonar_1Angle = ServoMoteurSonar_1Angle +
                                ServoMoteurSonar_1AnglePasDefaut;
    }
    if (ServoMoteurSonar_1Angle > ServoMoteurSonar_1AngleCentre)
    {
      DeplacementReculerDroite ();
      ServoMoteurSonar_1Angle = ServoMoteurSonar_1Angle -
                                ServoMoteurSonar_1AnglePasDefaut;
    }
    ServoMoteurSonar_1.write (ServoMoteurSonar_1Angle);
    Serial.print ("ServoMoteurSonar_1Angle = ");
    Serial.print (ServoMoteurSonar_1Angle);
    Serial.println ();
    GererBoutons ();
  }
}
//*****************************************************************************

//*****************************************************************************
// FONCTION InitialiserMoteursCC
//*****************************************************************************
void InitialiserMoteursCC ()
{

  // Test pour les moteurs a cause du bogue de la bibliotheque Servo.
  // Moteur 1.
  digitalWrite (CONTROLE_MOTEUR_1_IN1, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, LOW);
  analogWrite (CONTROLE_MOTEUR_1_ENA, MOTEUR_1_VITESSE_MAXIMUM);
  delay (2000);//2 secondes.

  analogWrite (CONTROLE_MOTEUR_1_ENA, MOTEUR_1_VITESSE_MINIMUM);
  delay (2000);//2 secondes.

  digitalWrite (CONTROLE_MOTEUR_1_IN1, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, HIGH);
  analogWrite (CONTROLE_MOTEUR_1_ENA, MOTEUR_1_VITESSE_MAXIMUM);
  delay (2000);//2 secondes.

  analogWrite (CONTROLE_MOTEUR_1_ENA, MOTEUR_1_VITESSE_MINIMUM);
  delay (2000);//2 secondes.

  digitalWrite (CONTROLE_MOTEUR_1_IN1, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, LOW);
  analogWrite (CONTROLE_MOTEUR_1_ENA, 0);

  // Moteur 2.
  digitalWrite (CONTROLE_MOTEUR_1_IN3, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, LOW);
  analogWrite (CONTROLE_MOTEUR_1_ENB, MOTEUR_2_VITESSE_MAXIMUM);
  delay (2000);//2 secondes.

  digitalWrite (CONTROLE_MOTEUR_1_IN3, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, LOW);
  analogWrite (CONTROLE_MOTEUR_1_ENB, MOTEUR_2_VITESSE_MINIMUM);
  delay (2000);//2 secondes.

  digitalWrite (CONTROLE_MOTEUR_1_IN3, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, HIGH);
  analogWrite (CONTROLE_MOTEUR_1_ENB, MOTEUR_2_VITESSE_MAXIMUM);
  delay (2000);//2 secondes.

  analogWrite (CONTROLE_MOTEUR_1_ENB, MOTEUR_2_VITESSE_MINIMUM);
  delay (2000);//2 secondes.

  digitalWrite (CONTROLE_MOTEUR_1_IN3, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, LOW);
  analogWrite (CONTROLE_MOTEUR_1_ENB, 0);

}
//*****************************************************************************

//*****************************************************************************
// FONCTION DeplacementArret
//*****************************************************************************
void DeplacementArreter ()
{
  ControleMoteur1Vitesse = 0;
  ControleMoteur2Vitesse = 0;
  // Pour le moteur 1.
  digitalWrite (CONTROLE_MOTEUR_1_ENA, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN1, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENA, ControleMoteur1Vitesse);
  // Pour le moteur 2.
  digitalWrite (CONTROLE_MOTEUR_1_ENB, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN3, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENB, ControleMoteur1Vitesse);
  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION DeplacementAvancer
//*****************************************************************************
void DeplacementAvancer ()
{
  ControleMoteur1Vitesse = MOTEUR_1_VITESSE_MINIMUM;
  ControleMoteur2Vitesse = MOTEUR_2_VITESSE_MINIMUM;
  // Pour le moteur 1.
  digitalWrite (CONTROLE_MOTEUR_1_ENA, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN1, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENA, ControleMoteur1Vitesse);
  // Pour le moteur 2.
  digitalWrite (CONTROLE_MOTEUR_1_ENB, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN3, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENB, ControleMoteur1Vitesse);
  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION DeplacementReculer
//*****************************************************************************
void DeplacementReculer ()
{
  ControleMoteur1Vitesse = MOTEUR_1_VITESSE_MINIMUM;
  ControleMoteur2Vitesse = MOTEUR_2_VITESSE_MINIMUM;
  // Pour le moteur 1.
  digitalWrite (CONTROLE_MOTEUR_1_ENA, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN1, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, HIGH);
  analogWrite  (CONTROLE_MOTEUR_1_ENA, ControleMoteur1Vitesse);
  // Pour le moteur 2.
  digitalWrite (CONTROLE_MOTEUR_1_ENB, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN3, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, HIGH);
  analogWrite  (CONTROLE_MOTEUR_1_ENB, ControleMoteur1Vitesse);
  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION DeplacementAvancerDroite
//*****************************************************************************
void DeplacementAvancerDroite ()
{
  ControleMoteur1Vitesse = MOTEUR_1_VITESSE_MAXIMUM;
  ControleMoteur2Vitesse = MOTEUR_2_VITESSE_MINIMUM;
  // Pour le moteur 1.
  digitalWrite (CONTROLE_MOTEUR_1_ENA, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN1, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENA, ControleMoteur1Vitesse);
  // Pour le moteur 2.
  digitalWrite (CONTROLE_MOTEUR_1_ENB, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN3, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENB, ControleMoteur1Vitesse);
  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION DeplacementAvancerGauche
//*****************************************************************************
void DeplacementAvancerGauche ()
{
  ControleMoteur1Vitesse = MOTEUR_1_VITESSE_MINIMUM;
  ControleMoteur2Vitesse = MOTEUR_2_VITESSE_MAXIMUM;
  // Pour le moteur 1.
  digitalWrite (CONTROLE_MOTEUR_1_ENA, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN1, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENA, ControleMoteur1Vitesse);
  // Pour le moteur 2.
  digitalWrite (CONTROLE_MOTEUR_1_ENB, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN3, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENB, ControleMoteur1Vitesse);
  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION DeplacementReculerDroite
//*****************************************************************************
void DeplacementReculerDroite ()
{
  ControleMoteur1Vitesse = MOTEUR_1_VITESSE_MINIMUM;
  ControleMoteur2Vitesse = MOTEUR_2_VITESSE_MAXIMUM;
  // Pour le moteur 1.
  digitalWrite (CONTROLE_MOTEUR_1_ENA, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN1, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENA, ControleMoteur1Vitesse);
  // Pour le moteur 2.
  digitalWrite (CONTROLE_MOTEUR_1_ENB, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN3, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, HIGH);
  analogWrite  (CONTROLE_MOTEUR_1_ENB, ControleMoteur1Vitesse);
  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION DeplacementReculerGauche
//*****************************************************************************
void DeplacementReculerGauche ()
{
  ControleMoteur1Vitesse = MOTEUR_1_VITESSE_MAXIMUM;
  ControleMoteur2Vitesse = MOTEUR_2_VITESSE_MINIMUM;
  // Pour le moteur 1.
  digitalWrite (CONTROLE_MOTEUR_1_ENA, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN1, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, HIGH);
  analogWrite  (CONTROLE_MOTEUR_1_ENA, ControleMoteur1Vitesse);
  // Pour le moteur 2.
  digitalWrite (CONTROLE_MOTEUR_1_ENB, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN3, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENB, ControleMoteur1Vitesse);
  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION DeplacementPivoterGauche
//*****************************************************************************
void DeplacementPivoterGauche ()
{
  ControleMoteur1Vitesse = MOTEUR_1_VITESSE_MINIMUM;
  ControleMoteur2Vitesse = MOTEUR_2_VITESSE_MINIMUM;
  // Pour le moteur 1.
  digitalWrite (CONTROLE_MOTEUR_1_ENA, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN1, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENA, ControleMoteur1Vitesse);
  // Pour le moteur 2.
  digitalWrite (CONTROLE_MOTEUR_1_ENB, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN3, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, HIGH);
  analogWrite  (CONTROLE_MOTEUR_1_ENB, ControleMoteur1Vitesse);
  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION DeplacementPivoterDroite
//*****************************************************************************
void DeplacementPivoterDroite ()
{
  ControleMoteur1Vitesse = MOTEUR_1_VITESSE_MINIMUM;
  ControleMoteur2Vitesse = MOTEUR_2_VITESSE_MINIMUM;
  // Pour le moteur 1.
  digitalWrite (CONTROLE_MOTEUR_1_ENA, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN1, LOW);
  digitalWrite (CONTROLE_MOTEUR_1_IN2, HIGH);
  analogWrite  (CONTROLE_MOTEUR_1_ENA, ControleMoteur1Vitesse);
  // Pour le moteur 2.
  digitalWrite (CONTROLE_MOTEUR_1_ENB, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN3, HIGH);
  digitalWrite (CONTROLE_MOTEUR_1_IN4, LOW);
  analogWrite  (CONTROLE_MOTEUR_1_ENB, ControleMoteur1Vitesse);
  GererAffichages ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION GererAffichages
//*****************************************************************************
void GererAffichages ()
{
  if (AffichageMoniteurSerie)
  {
    GererAffichageMoniteurSerie ();
  }
  if (AffichageEcranLCD)
  {
    GererAffichageEcranLCD ();
  }
}
//*****************************************************************************

//*****************************************************************************
// FONCTION GererAffichageMoniteurSerie
//*****************************************************************************
void GererAffichageMoniteurSerie ()
{
  // Écriture dans le moniteur série de l'IDE d'Arduino des valeurs lues.
  Serial.print (" AnglePas:");
  Serial.print (ServoMoteurSonar_1AnglePasDefaut);

  Serial.print (" DistanceActuele:");
  Serial.print (Sonar_1DistanceActuele);
  Serial.print (" AngleActuel:");
  Serial.print (ServoMoteurSonar_1Angle);
  Serial.print (" AngleTrouve:");
  Serial.print (DistanceMaximumTrouveAngle);
  Serial.print (" Moteur1:");
  Serial.print (ControleMoteur1Vitesse);
  Serial.print (" Moteur2:");
  Serial.print (ControleMoteur2Vitesse);
  Serial.println ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION GererAffichageEcranLCD
//*****************************************************************************
void GererAffichageEcranLCD ()
{
  // Écriture dans l'écran LCD des valeurs lues.
  LCD_1.clear ();
  LCD_1.setCursor (0,0);
  LCD_1.print ("");
  LCD_1.print (int (Sonar_1DistanceActuele));
  LCD_1.setCursor (5,0);
  LCD_1.print ("");
  LCD_1.print (int (Sonar_2DistanceActuele));
  LCD_1.setCursor (11,0);
  LCD_1.print ("");
  LCD_1.print (int (Sonar_3DistanceActuele));
  LCD_1.setCursor (0,1);
  LCD_1.print ("");
  LCD_1.print (ControleMoteur1Vitesse);
  LCD_1.setCursor (5,1);
  LCD_1.print ("");
  LCD_1.print (ControleMoteur2Vitesse);
  LCD_1.setCursor (11,1);
  LCD_1.print ("");
  LCD_1.print (int (ServoMoteurSonar_1Angle));
  LCD_1.print ("     ");
  LCD_1.println ();
}
//*****************************************************************************

//*****************************************************************************
// FONCTION AjusterVitesseDesMoteurs
//*****************************************************************************
void AjusterVitesseDesMoteurs ()
{
/*
  ControleMoteur1Vitesse = map (Sonar_1DistanceActuele, 0,
  Sonar_1DistanceValideMaximum, 0,
  MOTEUR_1_VITESSE_MAXIMUM);
  ControleMoteur2Vitesse = map (Sonar_1DistanceActuele, 0,
  Sonar_1DistanceValideMaximum, 0,
  MOTEUR_1_VITESSE_MAXIMUM);
  ControleMoteur1.setSpeed (abs (ControleMoteur1Vitesse));
  ControleMoteur2.setSpeed (abs (ControleMoteur2Vitesse));
  GererAffichages ();
  Rouler ();
*/

}
//*****************************************************************************

//*****************************************************************************
// FONCTION ConvertionMicrosecondsEnCentimetres
//*****************************************************************************
float ConvertionMicrosecondsEnCentimetres (float microseconds)
{
/*
La vitesse du son est de 340 metres par seconde ou 29 microsecondes par
centimètre. Le ping voyage aller et retour, de sorte à trouver la distance de
l'objet, nous prenons la moitié de la distance parcourue. Voir:
https://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
*/

  return microseconds / 29 / 2;
}
//*****************************************************************************

//*****************************************************************************
// FONCTION R2D2_1
//*****************************************************************************
void UneNoteDeMusique (int BOZZER_1_PLUS, float noteFrequency, long noteDuration)
{
  int x;
  // Convertir la fréquence en microsecondes.
  float microsecondsPerWave = 1000000 / noteFrequency;
  // Calculez combien de cycles HIGH / LOW il ya par milliseconde.
  float millisecondsPerCycle = 1000 / (microsecondsPerWave * 2);
  // Multipliez noteDuration en nombre de cycles * par milliseconde.
  float loopTime = noteDuration * millisecondsPerCycle;
  // Jouez la note pour la boucle calculé.
  for (x = 0; x < loopTime ; x = x + 1)
  {
    digitalWrite (BOZZER_1_PLUS, HIGH);
    delayMicroseconds (microsecondsPerWave);
    digitalWrite (BOZZER_1_PLUS, LOW);
    delayMicroseconds (microsecondsPerWave);
  }
}
//*****************************************************************************

//*****************************************************************************
// FONCTION R2D2_1
//*****************************************************************************
void R2D2_1 ()
{
  UneNoteDeMusique (BOZZER_1_PLUS, Note_A7, 100);// Note de musique A
  UneNoteDeMusique (BOZZER_1_PLUS, Note_E7, 100);// Note de musique E
  UneNoteDeMusique (BOZZER_1_PLUS, Note_C7, 100);// Note de musique C
  UneNoteDeMusique (BOZZER_1_PLUS, Note_D7, 100);// Note de musique D
  UneNoteDeMusique (BOZZER_1_PLUS, Note_B7, 100);// Note de musique B
  UneNoteDeMusique (BOZZER_1_PLUS, Note_F7, 100);// Note de musique F
}
//*****************************************************************************

//*****************************************************************************
// FONCTION SortieTrouve
//*****************************************************************************
void SortieTrouve ()
{
  ServoMoteurSonar_1.detach ();
  DeplacementArreter ();
  R2D2_1 ();
  Boucler = NON;
  // Configurer le port Arduino pour un RESET par télécommande.
  pinMode (ARDUINO_RESET, SORTIE);
  // Activer la broche ARDUINO_RESET.
  digitalWrite (ARDUINO_RESET, BAS);
  delay (UneSeconde);
}
//*****************************************************************************

//*****************************************************************************
// Mémo instructions
//*****************************************************************************
// Mémo LCD
//*****************************************************************************
/*
LiquidCrystal LCD_1 (rs, enable, d4, d5, d6, d7);// Initialisation 4 bits
LCD_1.begin (cols, rows);// Initialisation nombre colonne/ligne

LCD_1.clear ();// Efface écran et met le curseur en haut à gauche
LCD_1.home ();// Repositionne le curseur en haut et à gauche SANS effacer écran

LCD_1.setCursor (col, row);// Positionne le curseur à l'endroit voulu (colonne, ligne) (1ère=0 !)
LCD_1.print ("texte");// Affiche la chaîne texte

LCD_1.cursor ();// Affiche la ligne de base du curseur
LCD_1.noCursor ();// Cache le curseur
LCD_1.blink ();// Fait clignoter le curseur
LCD_1.noBlink ();// Arrete le clignotement du curseur
LCD_1.noDisplay ();// Éteint le LCD sans modifier affichage
LCD_1.display ();// Rallume le LCD sans modif affichage

LCD_1.scrollDisplayLeft ();// Décale l'affichage d'une colonne vers la gauche
LCD_1.scrollDisplayRight ();// Décale l'affichage d'une colonne vers la droite
LCD_1.autoscroll ();// Les nouveaux caractères poussent les caractères déjà affichés
LCD_1.noAutoscroll ();// Stoppe le mode autoscroll
*/

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


Fichier « TelecommandeValeurBoutons.h » :


//Définition de la valeur retourné par les boutons de la télécommande type MP3.
// Écrit par : René Ross
// Date : 2013-09-09
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;


Fichier « NotesDeMusique.h » :


// Référence : Cette liste a été adaptée à partir de la table situé ici :
// https://www.phy.mtu.edu/~suits/notefreqs.html
// Écrit par : René Ross
// Date : 2013-09-09
const float Note_C0  = 16.35;  //C0
const float Note_Db0 = 17.32;  //C#0 Db0
const float Note_D0  = 18.35;  //D0
const float Note_Eb0 = 19.45;  //D#0 Eb0
const float Note_E0  = 20.6;   //E0
const float Note_F0  = 21.83;  //F0
const float Note_Gb0 = 23.12;  //F#0 Gb0
const float Note_G0  = 24.5;   //G0
const float Note_Ab0 = 25.96;  //G#0 Ab0
const float Note_A0  = 27.5;   //A0
const float Note_Bb0 = 29.14;  //A#0 Bb0
const float Note_B0  = 30.87;  //B0
const float Note_C1  = 32.7;   //C1
const float Note_Db1 = 34.65;  //C#1 Db1
const float Note_D1  = 36.71;  //D1
const float Note_Eb1 = 38.89;  //D#1 Eb1
const float Note_E1  = 41.2;   //E1
const float Note_F1  = 43.65;  //F1
const float Note_Gb1 = 46.25;  //F#1 Gb1
const float Note_G1  = 49;     //G1
const float Note_Ab1 = 51.91;  //G#1 Ab1
const float Note_A1  = 55;     //A1
const float Note_Bb1 = 58.27;  //A#1 Bb1
const float Note_B1  = 61.74;  //B1
const float Note_C2  = 65.41;  //C2 (Middle C)
const float Note_Db2 = 69.3;   //C#2 Db2
const float Note_D2  = 73.42;  //D2
const float Note_Eb2 = 77.78;  //D#2 Eb2
const float Note_E2  = 82.41;  //E2
const float Note_F2  = 87.31;  //F2
const float Note_Gb2 = 92.5;   //F#2 Gb2
const float Note_G2  = 98;     //G2
const float Note_Ab2 = 103.83; //G#2 Ab2
const float Note_A2  = 110;    //A2
const float Note_Bb2 = 116.54; //A#2 Bb2
const float Note_B2  = 123.47; //B2
const float Note_C3  = 130.81; //C3
const float Note_Db3 = 138.59; //C#3 Db3
const float Note_D3  = 146.83; //D3
const float Note_Eb3 = 155.56; //D#3 Eb3
const float Note_E3  = 164.81; //E3
const float Note_F3  = 174.61; //F3
const float Note_Gb3 = 185;    //F#3 Gb3
const float Note_G3  = 196;    //G3
const float Note_Ab3 = 207.65; //G#3 Ab3
const float Note_A3  = 220;    //A3
const float Note_Bb3 = 233.08; //A#3 Bb3
const float Note_B3  = 246.94; //B3
const float Note_C4  = 261.63; //C4
const float Note_Db4 = 277.18; //C#4 Db4
const float Note_D4  = 293.66; //D4
const float Note_Eb4 = 311.13; //D#4 Eb4
const float Note_E4  = 329.63; //E4
const float Note_F4  = 349.23; //F4
const float Note_Gb4 = 369.99; //F#4 Gb4
const float Note_G4  = 392;    //G4
const float Note_Ab4 = 415.3;  //G#4 Ab4
const float Note_A4  = 440;    //A4
const float Note_Bb4 = 466.16; //A#4 Bb4
const float Note_B4  = 493.88; //B4
const float Note_C5  = 523.25; //C5
const float Note_Db5 = 554.37; //C#5 Db5
const float Note_D5  = 587.33; //D5
const float Note_Eb5 = 622.25; //D#5 Eb5
const float Note_E5  = 659.26; //E5
const float Note_F5  = 698.46; //F5
const float Note_Gb5 = 739.99; //F#5 Gb5
const float Note_G5  = 783.99; //G5
const float Note_Ab5 = 830.61; //G#5 Ab5
const float Note_A5  = 880;    //A5
const float Note_Bb5 = 932.33; //A#5 Bb5
const float Note_B5  = 987.77; //B5
const float Note_C6  = 1046.5; //C6
const float Note_Db6 = 1108.73;//C#6 Db6
const float Note_D6  = 1174.66;//D6
const float Note_Eb6 = 1244.51;//D#6 Eb6
const float Note_E6  = 1318.51;//E6
const float Note_F6  = 1396.91;//F6
const float Note_Gb6 = 1479.98;//F#6 Gb6
const float Note_G6  = 1567.98;//G6
const float Note_Ab6 = 1661.22;//G#6 Ab6
const float Note_A6  = 1760;   //A6
const float Note_Bb6 = 1864.66;//A#6 Bb6
const float Note_B6  = 1975.53;//B6
const float Note_C7  = 2093;   //C7
const float Note_Db7 = 2217.46;//C#7 Db7
const float Note_D7  = 2349.32;//D7
const float Note_Eb7 = 2489.02;//D#7 Eb7
const float Note_E7  = 2637.02;//E7
const float Note_F7  = 2793.83;//F7
const float Note_Gb7 = 2959.96;//F#7 Gb7
const float Note_G7  = 3135.96;//G7
const float Note_Ab7 = 3322.44;//G#7 Ab7
const float Note_A7  = 3520;   //A7
const float Note_Bb7 = 3729.31;//A#7 Bb7
const float Note_B7  = 3951.07;//B7
const float Note_C8  = 4186.01;//C8
const float Note_Db8 = 4434.92;//C#8 Db8
const float Note_D8  = 4698.64;//D8
const float Note_Eb8 = 4978.03;//D#8 Eb8

En souhaitant que vous y trouviez ce que vous cherchiez !

Bon montage !

L'ami René

Un pour tous, et tous pour un !