Difference between revisions of "Exercice Arduino FCU"

From beeplane
Jump to navigation Jump to search
 
(63 intermediate revisions by the same user not shown)
Line 1: Line 1:
Vous trouverez sur cette page toutes les informations, exercies, et fichiers nécessaire à la prise en main et à la réalisation d'un prototype de FCU (Flight Control Unit) dans le cadre de travaux dirigés (TD) à faire en classe
+
<i>This page is available in English by following this link: https://wiki.collaborativebee.com//index.php?title=Exercise_Arduino_FCU_English</i>
  
<b><h3>Quelques fonctions Arduino utiles :</h3></b>
+
Vous trouverez sur cette page toutes les informations, exercices, et fichiers nécessaires à la prise en main et à la réalisation d'un prototype de FCU (Flight Control Unit) dans le cadre de travaux dirigés (TD) à faire en classe.
 +
 
 +
<b><h3>Quelques fonctions Arduino utiles</h3></b>
  
 
Void setup() : obligatoire en début de programme, cela correspond à l’initialisation du  
 
Void setup() : obligatoire en début de programme, cela correspond à l’initialisation du  
Line 16: Line 18:
  
 
PinMode() : permet d’initialiser une broche et de la mettre en entrée ou sortie (ex :  
 
PinMode() : permet d’initialiser une broche et de la mettre en entrée ou sortie (ex :  
pinMode(1, OUTPUT) )
+
pinMode(1, OUTPUT))
  
 
Delay() : Fait une pause dans le programme (en ms).
 
Delay() : Fait une pause dans le programme (en ms).
Line 24: Line 26:
  
 
Voici quelques sites permettant de trouver tous les composants nécessaires pour le  
 
Voici quelques sites permettant de trouver tous les composants nécessaires pour le  
montage :
+
montage : <br>
 
https://www.gotronic.fr/rechercher.htm  
 
https://www.gotronic.fr/rechercher.htm  
 +
<br>
 
https://boutique.semageek.com/fr/2-arduino
 
https://boutique.semageek.com/fr/2-arduino
  
Line 55: Line 58:
 
Pour pouvoir allumer cette LED, il faudra utiliser le code Arduino suivant.
 
Pour pouvoir allumer cette LED, il faudra utiliser le code Arduino suivant.
  
void setup() {
+
void setup()
 +
{
 +
  pinMode(1, OUTPUT); //initialise la borne numérique numéro 1 de la carte Arduino en mode sortie
 +
}
 +
void loop()
 +
{
 +
  digitalWrite(1, HIGH); //le courant est envoyé sur la borne 1, la LED s'allume
 +
}
 +
 
 +
<h3><b>Etape 2 : faire clignoter une LED</b></h3>
 +
 
 +
Ce code Arduino permet de faire clignoter une LED à une fréquence déterminée
 +
 
 +
void setup()
 +
{
 +
  pinMode(1, OUTPUT); //Initialisation de la broche 1 en sortie
 +
}
 +
 
 +
void loop()
 +
{
 +
  digitalWrite(1, HIGH); //Mise au niveau Haut (Allumage) de la LED
 +
  delay(1000); //Délai de 1000ms dans cette position (LED allumée)
 +
  digitalWrite(1, LOW); //Mise au niveau bas (Eteint) de la LED
 +
  delay(1000); //Délai de 1000ms dans cette position (LED éteinte)
 +
}
 +
 
 +
Vous pouvez retrouver une vidéo explicative sur ce lien : https://www.youtube.com/watch?v=OOR3dfWH8HE
 +
 
 +
<h3><b>Etape 3 : faire varier l'intensité lumineuse d'une LED</b></h3>
 +
 
 +
Ici le code va faire varier l’intensité lumineuse de la LED, de façon à ce que l’intensité augmente linéairement puis lorsque la LED atteint sa valeur maximale (valeur 255, valeur HIGH) puis arrivé a cette valeur, l’intensité lumineuse rediminue jusqu’à ce que la LED soit éteinte (valeur 0, LOW).
 +
 
 +
int LED = 3; // Définition des broches et variables utilisées
 +
int x; // Rapport cyclique
 +
 +
void setup()
 +
 +
  pinMode(LED, OUTPUT); 
 +
}
 +
 
 +
void loop()
 +
 +
  x = 0; 
 +
  while (x <= 255) // Allumer progressivement la LED (0 --> 255)
 +
  {
 +
  analogWrite(LED, x); 
 +
  delay(10); 
 +
  x = x+1;
 +
  } 
 +
  x = 255;
 +
  while (x >= 0) // Eteindre progressivement la LED (255 --> 0)
 +
  {
 +
  analogWrite(LED, x); 
 +
  delay(10); 
 +
  x = x-1;
 +
  }
 +
}
 +
 
 +
== Exercice 2 : Utiliser un gyroscope ==
 +
 
 +
L’implémentation d’un gyroscope sous Arduino permet de connaître les inclinaisons d’un appareil en mouvement.
 +
 
 +
[[File:arduino_gyroscope.png|400px|thumb|center|Schéma du montage]]
 +
 
 +
<h3><b>Matériel nécessaire</b></h3>
 +
- Carte Arduino <br>
 +
- Un gyroscope <br>
 +
- 4 fils mâle/femelle <br>
 +
 
 +
<h3><b>Montage</b></h3>
 +
• Connecter les bornes GND et VCC respectivement aux bornes GND et +5V de la carte Arduino <br>
 +
• Connecter la borne SCL du gyroscope à la borne analogique numéro A4 <br>
 +
• Connecter la borne SCA du gyroscope à la borne analogique numéro A5 <br>
 +
 
 +
Ici, les bornes SCL et SDA correspondent aux axes x et y du gyroscope.
 +
 
 +
<font color ="blue">REMARQUE : </font>On peut utiliser des LEDs sur une plaquette d’essai comme cela a été fait pour le Joystick afin de pouvoir voir quels sont les effets du gyroscope sur les LEDs.
 +
 
 +
 
 +
<h3><b>Code Arduino</b></h3>
 +
 
 +
#include <Wire.h>
 +
#include "I2Cdev.h"
 +
#include "MPU6050_6Axis_MotionApps20.h"
 +
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
 +
#include "Wire.h"
 +
#endif
 +
MPU6050 mpu;
 +
#define OUTPUT_READABLE_YAWPITCHROLL
 +
#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
 +
bool blinkState = false;
 +
 +
bool dmpReady = false;  // set true if DMP init was successful
 +
uint8_t mpuIntStatus;  // holds actual interrupt status byte from MPU
 +
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
 +
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
 +
uint16_t fifoCount;    // count of all bytes currently in FIFO
 +
uint8_t fifoBuffer[64]; // FIFO storage buffer
 +
 +
// orientation/motion vars
 +
Quaternion q;          // [w, x, y, z]        quaternion container
 +
VectorInt16 aa;        // [x, y, z]            accel sensor measurements
 +
VectorInt16 aaReal;    // [x, y, z]            gravity-free accel sensor measurements
 +
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
 +
VectorFloat gravity;    // [x, y, z]            gravity vector
 +
float euler[3];        // [psi, theta, phi]    Euler angle container
 +
float ypr[3];          // [yaw, pitch, roll]  yaw/pitch/roll container and gravity vector
 +
 +
// packet structure for InvenSense teapot demo
 +
uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };
 +
 +
// ================================================================
 +
// ===              INTERRUPT DETECTION ROUTINE                ===
 +
// ================================================================
 +
 +
volatile bool mpuInterrupt = false;    // indicates whether MPU interrupt pin has gone high
 +
void dmpDataReady() {
 +
    mpuInterrupt = true;
 +
}
 +
// ================================================================
 +
// ===                      LEDS                                ===
 +
// ================================================================
 +
 +
const int led_1 = 13 ;
 +
const int led_2 = 12 ;
 +
const int led_3 = 11 ;
 +
const int led_4 = 10 ;
 +
const int led_5 = 9 ;
 +
const int led_6 = 8 ;
 +
const int led_7 = 7 ;
 +
const int led_8 = 6 ;
 +
const int led_9 = 5 ;
 +
 +
// ================================================================
 +
// ===                      INITIAL SETUP                      ===
 +
// ================================================================
 +
 +
void setup() {
 +
    // LEDS
 +
   
 +
  pinMode(led_1, OUTPUT);
 +
  pinMode(led_2, OUTPUT);
 +
  pinMode(led_3, OUTPUT);
 +
  pinMode(led_4, OUTPUT);
 +
  pinMode(led_5, OUTPUT);
 +
  pinMode(led_6, OUTPUT);
 +
  pinMode(led_7, OUTPUT);
 +
  pinMode(led_8, OUTPUT);
 +
  pinMode(led_9, OUTPUT);
 +
   
 +
    // join I2C bus (I2Cdev library doesn't do this automatically)
 +
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
 +
        Wire.begin();
 +
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
 +
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
 +
        Fastwire::setup(400, true);
 +
    #endif
 +
 +
    Serial.begin(115200);
 +
    while (!Serial); // wait for Leonardo enumeration, others continue immediately
 +
 +
    Serial.println(F("Initializing I2C devices..."));
 +
    mpu.initialize();
 +
 +
    Serial.println(F("Testing device connections..."));
 +
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
 +
 +
    Serial.println(F("\nSend any character to begin DMP programming and demo: "));
 +
    while (Serial.available() && Serial.read()); // empty buffer
 +
    while (!Serial.available());                // wait for data
 +
    while (Serial.available() && Serial.read()); // empty buffer again
 +
 +
    Serial.println(F("Initializing DMP..."));
 +
    devStatus = mpu.dmpInitialize();
 +
 +
    // supply your own gyro offsets here, scaled for min sensitivity
 +
    mpu.setXGyroOffset(220);
 +
    mpu.setYGyroOffset(76);
 +
    mpu.setZGyroOffset(-85);
 +
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
 +
 +
    // make sure it worked (returns 0 if so)
 +
    if (devStatus == 0) {
 +
        // turn on the DMP, now that it's ready
 +
        Serial.println(F("Enabling DMP..."));
 +
        mpu.setDMPEnabled(true);
 
   
 
   
pinMode(1, OUTPUT); //initialise la borne numérique numéro 1 de la carte Arduino en mode sortie
+
        // enable Arduino interrupt detection
 +
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
 +
        attachInterrupt(0, dmpDataReady, RISING);
 +
        mpuIntStatus = mpu.getIntStatus();
 +
 +
        // set our DMP Ready flag so the main loop() function knows it's okay to use it
 +
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
 +
        dmpReady = true;
 +
 +
        // get expected DMP packet size for later comparison
 +
        packetSize = mpu.dmpGetFIFOPacketSize();
 +
    } else {
 +
        // ERROR!
 +
        // 1 = initial memory load failed
 +
        // 2 = DMP configuration updates failed
 +
        // (if it's going to break, usually the code will be 1)
 +
        Serial.print(F("DMP Initialization failed (code "));
 +
        Serial.print(devStatus);
 +
        Serial.println(F(")"));
 +
    }
 +
 +
    // configure LED for output
 +
    pinMode(LED_PIN, OUTPUT);
 +
}
 +
// ================================================================
 +
// ===                    MAIN PROGRAM LOOP                    ===
 +
// ================================================================
 +
 +
void loop() {
 +
    // if programming failed, don't try to do anything
 +
    if (!dmpReady) return;
 +
 +
    // wait for MPU interrupt or extra packet(s) available
 +
    while (!mpuInterrupt && fifoCount < packetSize) {
 +
        // other program behavior stuff here
 +
        // if you are really paranoid you can frequently test in between other
 +
        // stuff to see if mpuInterrupt is true, and if so, "break;" from the
 +
        // while() loop to immediately process the MPU data
 +
    }
 +
 +
    // reset interrupt flag and get INT_STATUS byte
 +
    mpuInterrupt = false;
 +
    mpuIntStatus = mpu.getIntStatus();
 +
 +
    // get current FIFO count
 +
    fifoCount = mpu.getFIFOCount();
 +
 +
    // check for overflow (this should never happen unless our code is too inefficient)
 +
    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
 +
        // reset so we can continue cleanly
 +
        mpu.resetFIFO();
 +
        Serial.println(F("FIFO overflow!"));
 +
 +
    // otherwise, check for DMP data ready interrupt (this should happen frequently)
 +
    } else if (mpuIntStatus & 0x02) {
 +
        // wait for correct available data length, should be a VERY short wait
 +
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
 +
 +
        // read a packet from FIFO
 +
        mpu.getFIFOBytes(fifoBuffer, packetSize);
 +
       
 +
        // track FIFO count here in case there is > 1 packet available
 +
        // (this lets us immediately read more without waiting for an interrupt)
 +
        fifoCount -= packetSize;
 +
 +
        mpu.dmpGetQuaternion(&q, fifoBuffer);
 +
        mpu.dmpGetGravity(&gravity, &q);
 +
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
 +
 +
 +
// DEBUT DE NOTRE CODE
 +
 +
// MPU
 +
      int XX ;
 +
      int YY ;
 +
      XX = (ypr[2] * 180/M_PI) * (128/90) ; // entre -128 et 128
 +
      YY = (ypr[1] * 180/M_PI) * (128/90) ;
 +
 +
      // c'est p et r qui nous intéressent
 +
 
 +
      int puiss_led_11 ;
 +
      int puiss_led_22 ;
 +
      int puiss_led_33 ;
 +
      int puiss_led_44 ;
 +
      int puiss_led_55 ;
 +
      int puiss_led_66 ;
 +
      int puiss_led_77 ;
 +
      int puiss_led_88 ;
 +
      int puiss_led_99 ;
 +
     
 +
      puiss_led_11 = 100 + (0 * XX) - (1.5 * YY);
 +
      puiss_led_22 = 100 - (0.75 * XX) - (1 * YY);
 +
      puiss_led_33 = 100 + (0.75 * XX) - (1 * YY);
 +
      puiss_led_44 = 100 - (1 * XX) - (0 * YY);
 +
      puiss_led_55 = 100 + (1 * XX) - (0 * YY);
 +
      puiss_led_66 = 100 - (1.25 * XX) + (1 * YY);
 +
      puiss_led_77 = 100 - (0.75 * XX) + (1 * YY);
 +
      puiss_led_88 = 100 + (0.75 * XX) + (1 * YY);
 +
      puiss_led_99 = 100 + (1.25 * XX) + (1 * YY);
 +
 +
      analogWrite(led_1, puiss_led_11);
 +
      analogWrite(led_2, puiss_led_22);
 +
      analogWrite(led_3, puiss_led_33);
 +
      analogWrite(led_4, puiss_led_44);
 +
      analogWrite(led_5, puiss_led_55);
 +
      analogWrite(led_6, puiss_led_66);
 +
      analogWrite(led_7, puiss_led_77);
 +
      analogWrite(led_8, puiss_led_88);
 +
      analogWrite(led_9, puiss_led_99);
 +
 +
      // montrer dans la console les différentes intensités des LEDs
 +
      Serial.print("XX = ");
 +
      Serial.print(XX);
 +
      Serial.print("YY = ");
 +
      Serial.print(YY);
 +
      Serial.print("\tPuiss 1 = ");
 +
      Serial.print(puiss_led_11);
 +
      Serial.print("\tPuiss 2 = ");
 +
      Serial.print(puiss_led_22);
 +
      Serial.print("\tPuiss 3 = ");
 +
      Serial.print(puiss_led_33);
 +
      Serial.print("\tPuiss 4 = ");
 +
      Serial.print(puiss_led_44);
 +
      Serial.print("\tPuiss 5 = ");
 +
      Serial.print(puiss_led_55);
 +
      Serial.print("\tPuiss 6 = ");
 +
      Serial.print(puiss_led_66);
 +
      Serial.print("\tPuiss 7 = ");
 +
      Serial.print(puiss_led_77);
 +
      Serial.print("\tPuiss 8 = ");
 +
      Serial.print(puiss_led_88);
 +
      Serial.print("\tPuiss 9 = ");
 +
      Serial.println(puiss_led_99);
 +
 +
// FIN DE NOTRE CODE
 +
         
 +
      // blink LED to indicate activity
 +
      blinkState = !blinkState;
 +
      digitalWrite(LED_PIN, blinkState);
 +
    }
 +
}
 +
 
 +
 
 +
== Exercice 3A : Utiliser un joystick ==
 +
 
 +
L’implémentation d’un Joystick sous Arduino permet de récupérer des informations sur la position de celui-ci en temps réel. Ici on utilise des LEDs dans le montage afin d’obtenir un effet visuel. Cependant ces LEDs ne sont pas indispensable dans ce package.
  
}
+
<h3><b>Matériel nécessaire</b></h3>
 +
- Carte Arduino
  
void loop() {
+
- Un Joystick
  
digitalWrite(1, HIGH); //le courant est envoyé sur la borne 1, la LED s'allume
+
- 4 LEDs
  
}
+
- Au minimum 4 résistances de 220 ohms
  
 +
- une plaquette d’essai
  
<h3><b>Etape 2 : faire clignoter une LED</b></h3>
+
- 5 fils mâle/femelle
 +
 
 +
- 8 fils mâle/mâle
 +
 
 +
<h3><b>Montage</b></h3>
 +
· Connecter les 4 LEDs avec les résistances de la plaquette d’essai sur la carte Arduino sur les broches digital (ex : 10, 11, 12, 13). Disposez-les en forme de losange afin de d’avoir une LED qui correspond à une direction du Joystick (gauche, haut, ...) (voir montage ci-après).
 +
 
 +
· Connecter le Joystick à la carte Arduino :
 +
 
 +
o La broche GND du Joystick doit être relié au GND de la carte Arduino
 +
 
 +
o La broche Vcc du Joystick doit être relié au +5V de la carte Arduino
 +
 
 +
o La broche VRx du Joystick doit être relié à A0 (côté analogique) de la carte Arduino
 +
 
 +
o La broche VRy du Joystick doit être relié à A1 (côté analogique) de la carte Arduino
 +
 
 +
o La broche SW Joystick doit être relié à la borne 2 (côté digital) de la carte Arduino
 +
 
 +
[[File:arduino_joystick.PNG|400px|thumb|center|Schéma du montage]]
 +
 
 +
Sur ce montage, les LEDs permettront de connaître l’orientation du Joystick. En effet si le Joystick sera mis vers l’avant, une des LEDs s’allumera et les autres seront éteintes, alors la LED allumée représentera le côté avant du Joystick. De même pour les autres LEDs avec les autres côtés du Joystick.
 +
 
 +
Pour une analyse plus précise de la position du Joystick, allez dans Outils -> Moniteur série. Vous aurez les positions exactes du Joystick qui vous seront données.
 +
 
 +
<font color = "blue">REMARQUE : </font>On peut ajouter plus de LEDs afin d’augmenter la précision des informations, par exemple si on ajoute 4 LEDs supplémentaires (8 LEDs au total disposé en cercle) alors on pourra déterminer si le Joystick est mis dans les positions diagonales : Nord-Est, Nord-Ouest, Sud-Est, Sud-Ouest.
 +
 
 +
Concernant le Joystick, les broches VRx et VRy correspondent aux positions Avant/Arrière et Gauche/Droite du Joystick. La broche SW représente un appui sur le Joystick car celui-ci se comporte aussi comme un bouton poussoir.
 +
 
 +
<h3><b>Code Arduino</b></h3>
 +
 
 +
// Arduino pin numbers
 +
const int SW_pin = 2; //On connecte la broche SW sur la borne digital 2  
 +
const int X_pin = 0; //On connecte la broche X sur la borne analogique A0
 +
const int Y_pin = 1; //On connecte la broche Y sur la borne analogique A1
 +
 
 +
#define UP_LED 10
 +
#define RIGHT_LED 11 //On définit les bornes des LEDs
 +
#define LEFT_LED 12
 +
#define DOWN_LED 13
 +
 
 +
void setup() {
 +
  pinMode(SW_pin, INPUT);
 +
  digitalWrite(SW_pin, HIGH);
 +
  Serial.begin(115200);
 +
 +
  pinMode(UP_LED, OUTPUT);
 +
  pinMode(RIGHT_LED, OUTPUT); // On définit les 4 LEDs en sorties
 +
  pinMode(LEFT_LED, OUTPUT);
 +
  pinMode(DOWN_LED, OUTPUT);
 +
}
 +
 
 +
void loop() {
 +
  Serial.print("Switch: "); //Affichage dans le moniteur série des valeurs
 +
  Serial.print(digitalRead(SW_pin));
 +
  Serial.print("\n");
 +
  Serial.print("X-axis: ");
 +
  Serial.print(analogRead(X_pin));
 +
  Serial.print("\n");
 +
  Serial.print("Y-axis: ");
 +
  Serial.println(analogRead(Y_pin));
 +
  Serial.print("\n\n");
 +
 
 +
  delay(500);
 +
 +
  if(analogRead(X_pin) == 1023){ //Si le joystick est en avant, alors la 
 +
    digitalWrite(UP_LED, HIGH); // LED UP s’allume
 +
 +
} else if(analogRead(X_pin) == 0){ //Si le joystick est en arrière, alors la
 +
    digitalWrite(DOWN_LED, HIGH); // LED DOWN s’allume
 +
}
 +
else if(analogRead(Y_pin) == 1023){ //Si le joystick est à gauche, alors la
 +
    digitalWrite(RIGHT_LED, HIGH); // LED RIGHT s’allume
 +
}
 +
else if(analogRead(Y_pin) == 0){ //Si le joystick est à droite, alors la
 +
    digitalWrite(LEFT_LED, HIGH);          // LED LEFT s’allume
 +
}
 +
 +
else if(digitalRead(SW_pin) == 0){ //S’il y a un appui sur le Joystick,
 +
  digitalWrite(UP_LED, HIGH);         //alors toutes les LEDs s’allument
 +
  digitalWrite(LEFT_LED, HIGH);
 +
  digitalWrite(RIGHT_LED, HIGH);
 +
  digitalWrite(DOWN_LED, HIGH);
 +
}
 +
 +
else{ //S’il n’y a pas d’appui sur le Joystick,
 +
  digitalWrite(UP_LED, LOW); //alors toutes les LEDs s’éteignent
 +
  digitalWrite(LEFT_LED, LOW);
 +
  digitalWrite(RIGHT_LED, LOW);
 +
  digitalWrite(DOWN_LED, LOW);
 +
}
 +
}
 +
 
 +
== Exercice 3B : Utiliser un joystick pour connaître la position (enfoncée ou non) de celui-ci (version simplifiée) ==
 +
 
 +
L’implémentation d’un Joystick sous Arduino permet de récupérer des informations sur la position de celui-ci en temps réel. Ici on utilise des LEDs dans le montage afin d’obtenir un effet visuel. Cependant ces LEDs ne sont pas indispensable dans ce package.
 +
 
 +
L’objectif est d’utiliser seulement 4 LEDs et ainsi faire varier l’intensité lumineuse de chaque LED en fonction de la position du Joystick. L’intensité lumineuse des LEDs va augmenter proportionnellement à la position du Joystick.
 +
 
 +
<font color ="blue">EXEMPLE : </font>si le Joystick est légèrement incliné vers la droite, alors la LED de droite va scintiller avec une faible intensité et plus le Joystick va s’incliner, plus la LED de droite va avoir une intensité lumineuse élevée jusqu’à son maximale (Joystick enfoncé).
 +
 
 +
<h3><b>Matériel nécessaire</b></h3>
 +
 
 +
- Carte Arduino
 +
 
 +
- Un Joystick
 +
 +
- 4 LEDs
 +
 +
- Au minimum 4 résistances de 220 ohms
 +
 +
- une plaquette d’essai
 +
 +
- 4 fils mâle/femelle
 +
 +
- 12 fils mâle/mâle
 +
 
 +
<h3><b>Montage</b></h3>
 +
 
 +
• Connecter les 4 LEDs avec les résistances de la plaquette d’essai sur la carte Arduino sur les broches digital (ex : 10, 11, 12, 13). Disposez-les en forme de losange afin de d’avoir une LED qui correspond à une direction du Joystick (gauche, haut, ...) (voir montage ci-après).
 +
 +
• Connecter le Joystick à la carte Arduino :
 +
 
 +
o La broche GND du Joystick doit être relié au GND de la carte Arduino
 +
 
 +
o La broche Vcc du Joystick doit être relié au +5V de la carte Arduino
 +
 
 +
o La broche VRx du Joystick doit être relié à A0 (côté analogique) de la carte Arduino
 +
 
 +
o La broche VRy du Joystick doit être relié à A1 (côté analogique) de la carte Arduino
 +
 
 +
o La broche SW Joystick doit être relié à la borne 2 (côté digital) de la carte Arduino
 +
 
 +
 
 +
<font color = "blue">REMARQUE : </font>Pour une analyse plus précise de la position du Joystick, allez dans Outils -> Moniteur série. Vous aurez les positions exactes du Joystick qui vous seront données.
 +
 
 +
 
 +
<h3><b>Code Arduino</h3></b>
 +
 
 +
int axey = A1;  // Entrée de référence pour l'axe Y.
 +
int axex = A0;  // Entrée de référence pour l'axe X.
 +
int ledD = 12;  // Led inférieur. Cette valeur est à adapter à votre montage !
 +
int ledup = 9;    // Led supérieur. Cette valeur est à adapter à votre montage !
 +
int ledL = 13;    // Led gauche. Cette valeur est à adapter à votre montage !
 +
int ledR = 7;    // Led droite. Cette valeur est à adapter à votre montage !
 +
int valeurX;
 +
int valeurY;
 +
 
 +
void setup() { 
 +
  Serial.begin(9600); // Définition des leds comme sorties
 +
  pinMode(ledup, OUTPUT);
 +
  pinMode(ledD, OUTPUT);
 +
  pinMode(ledL, OUTPUT);
 +
  pinMode(ledR, OUTPUT); 
 +
}
 +
 
 +
void loop() { 
 +
  valeurX = analogRead(axex);
 +
  if (valeurX > 512){ // droite
 +
  analogWrite(ledR,(valeurX-513)/2); // Cette formule permet l’augmentation progressive de l’intensité lumineuse pour des valeurs comprises entre 513 et 1023
 +
  Serial.print("x = ");
 +
  Serial.println(valeurX);
 +
  }
 +
  else
 +
  {
 +
  digitalWrite(ledR, LOW );
 +
  }
 +
 
 +
  valeurX = analogRead(axex);
 +
  if (valeurX < 511){ // gauche
 +
  analogWrite(ledL,(-valeurX+510)/2); // Cette formule permet l’augmentation progressive de l’intensité lumineuse pour des valeurs comprises entre 0 et 510
 +
  Serial.print("x = ");
 +
  Serial.println(valeurX);
 +
  }
 +
  else
 +
  {
 +
  digitalWrite(ledL, LOW );
 +
  }
 +
 +
  valeurY = analogRead(axey);
 +
  if (valeurY > 512){ // bas
 +
  analogWrite(ledD, (valeurY-513)/2); // Cette formule permet l’augmentation progressive de l’intensité lumineuse pour des valeurs comprises entre 513 et 1023
 +
  Serial.print("y = ");
 +
  Serial.println(valeurY);
 +
  }
 +
  else
 +
  {
 +
  digitalWrite(ledD, LOW );
 +
  }
 +
 +
valeurY = analogRead(axey);
 +
if (valeurY < 511){ // haut
 +
  analogWrite(ledup,(-valeurX+510)/2); // Cette formule permet l’augmentation progressive de l’intensité lumineuse pour des valeurs comprises entre 0 et 510
 +
  Serial.print("y = ");
 +
  Serial.println(valeurY);
 +
  }
 +
  else
 +
  {
 +
  digitalWrite(ledup, LOW );
 +
  }
 +
}
 +
 
 +
<font color = "blue">REMARQUE : </font>Dans ce code, il y a 2 formules importantes (une pour les valeurs 0 à 510 des positions de Joystick et une pour les valeurs 513 à 1023). En effet, pour chaque axe (x et y du Joystick), on a une valeur associée de 0 (gauche ou bas) à 1023 (droite et haut). Ainsi avec les formules rentrées au niveau de la valeur de l’intensité lumineuse de la LED (fonction AnalogWrite), on a pour les valeurs proches de 512 une intensité lumineuse nulle (LED éteinte) car Joystick très faiblement incliné. En revanche pour les valeurs proche de 0 ou 1023, <b>en utilisant la bonne formule associée</b>, on a une intensité lumineuse de la LED maximale (valeur max : 255).
 +
 
 +
== Exercice 3C : Utiliser un joystick pour connaître la position (enfoncée ou non) de celui-ci (version complète) ==
 +
 
 +
L’implémentation d’un Joystick sous Arduino permet de récupérer des informations sur la position de celui-ci en temps réel. Ici on utilise des LEDs dans le montage afin d’obtenir un effet visuel. Cependant ces LEDs ne sont pas indispensable dans ce package.
 +
 
 +
L’objectif est ici que lorsque le Joystick est incliné à 50% dans une direction (ex : gauche) on a une LED qui s’allume à 50% de son intensité maximale. Puis lorsque le Joystick est en position maximale à gauche, une 2ème LED s’allume à intensité maximale.
 +
 
 +
<h3><b>Matériel nécessaire</b></h3>
 +
- Carte Arduino
 +
 
 +
- Un Joystick
 +
 
 +
- 8 LEDs
 +
 
 +
- Au minimum 8 résistances de 220 ohms
 +
 
 +
- une plaquette d’essai
 +
 
 +
- 4 fils mâle/femelle
  
Ce code Arduino permet de faire clignoter une LED à une fréquence déterminée
+
- 12 fils mâle/mâle
  
void setup() {
+
<h3><b>Montage</b></h3>
  pinMode(1, OUTPUT); //Initialisation de la broche 1 en sortie
+
• Connecter les 8 LEDs avec les résistances de la plaquette d’essai sur la carte Arduino sur les broches digital (ex : 10, 11, 12, 13). Disposez-les en forme de losange (2dans chaque direction) afin de d’avoir une LED qui correspond à une direction du Joystick (gauche, haut, ...) (voir montage ci-après).
}
 
 
   
 
   
void loop() {
+
• Connecter le Joystick à la carte Arduino :
  digitalWrite(1, HIGH); //Mise au niveau Haut (Allumage) de la LED
+
 
  delay(1000); //Délai de 1000ms dans cette position (LED allumée)
+
o La broche GND du Joystick doit être relié au GND de la carte Arduino
  digitalWrite(1, LOW); //Mise au niveau bas (Eteint) de la LED
+
 
  delay(1000); //Délai de 1000ms dans cette position (LED éteinte)
+
o La broche Vcc du Joystick doit être relié au +5V de la carte Arduino
}
 
  
Vous pouvez retrouver une vidéo explicative sur ce lien : https://www.youtube.com/watch?v=OOR3dfWH8HE
+
o La broche VRx du Joystick doit être relié à A0 (côté analogique) de la carte Arduino
 +
 
 +
o La broche VRy du Joystick doit être relié à A1 (côté analogique) de la carte Arduino
 +
 
 +
o La broche SW Joystick doit être relié à la borne 2 (côté digital) de la carte Arduino
 +
 
 +
• Rappel : Chaque LED a besoin d'une résistance de 220 ohms en série pour protéger le circuit. Branchez la cathode de chaque LED (le segment le plus court) à la masse et l'anode (le segment le plus long) à un port de sortie numérique digital.
 +
 
 +
• Le Joystick agit comme 2 potentiomètres : Sa position horizontale est donnée par un nombre de 0 (gauche) à 1023 (droite). Même chose en verticale (valeur moyenne 512)
 +
 
 +
• On rajoute des conditions dans le code. (Voir code ci-dessous).
 +
 
 +
<font color = "blue">EXEMPLE : </font>Si la valeur du Joystick est inférieure à une valeur donnée (ex : 300, Joystick légèrement incliné) alors la 1ère LED s'allume (intensité faible voir slide LED), puis si la valeur est minimale (0, Joystick enfoncé) alors la 2nde LED s'allume (intensité max).
 +
 
 +
[[File:arduino_joystick.PNG|400px|thumb|center|Schéma du montage]]
  
<h3><b>Etape 3 : faire varier l'intensité lumineuse d'une LED</b></h3>
+
<font color = "blue">REMARQUE : </font>Le montage correspond au montage ci-dessus avec l’ajout de 4 LEDs, on ajoute une LED à chaque extrémité (haut, bas, gauche, droite).
  
Ici le code va faire varier l’intensité lumineuse de la LED, de façon à ce que l’intensité augment linéairement puis lorsque la LED atteint sa valeur maximale (valeur 255, valeur HIGH) puis arrivé a cette valeur, l’intensité lumineuse rediminue jusqu’à ce que la LED soit éteinte (valeur 0, LOW).
+
<h3><b>Illustration</b></h3>
  
int LED = 3; // Définition des broches et variables utilisées
+
[[File:photos_arduino_joystick.PNG|1190px|thumb|center|Joystick relié à la carte Arduino dans 3 positions différentes]]
int x; // Rapport cyclique
 
  
void setup() { 
+
<h3><b>Code Arduino</b></h3>
pinMode(LED, OUTPUT); 
 
  
}  
+
  int axey = A1;  // Entrée de référence pour l'axe Y.
void loop() {  
+
  int axex = A0;   // Entrée de référence pour l'axe X.
x = 0;   
+
int ledup = 12;   // Led inférieur. Cette valeur est à adapter à votre montage !
while (x <= 255) { // Allumer progressivement la LED (0 --> 255)
+
  int ledupup = 10;  // Led inférieur ++. Cette valeur est à adapter à votre montage !
analogWrite(LED, x);   
+
int ledD = 9;   // Led supérieur. “”
delay(10);   
+
int ledDD = 5;   // Led supérieur ++. “”
x = x+1; }  
+
  int ledL = 13;    // Led gauche. “”
x = 255;
+
int ledLL = 11;   // Led gauche ++. “”
while (x >= 0) { // Eteindre progressivement la LED (255 --> 0)  
+
  int ledR = 7;    // Led droite. “”
analogWrite(LED, x);   
+
int ledRR = 8;  // Led droite ++. “”
delay(10);   
+
int valeurX;  
x = x-1;  
+
  int valeurY;
}
+
 
 +
void setup() {  
 +
  Serial.begin(9600); // Définition des leds comme sorties
 +
  pinMode(ledup, OUTPUT);
 +
  pinMode(ledupup, OUTPUT);
 +
  pinMode(ledD, OUTPUT);
 +
  pinMode(ledDD, OUTPUT);
 +
  pinMode(ledL, OUTPUT);
 +
  pinMode(ledLL, OUTPUT);   
 +
  pinMode(ledR, OUTPUT);   
 +
  pinMode(ledRR, OUTPUT);
 
  }
 
  }
 +
 
 +
void loop() { 
 +
  valeurX = analogRead(axex);
 +
  if (valeurX > 700){ // droite
 +
  analogWrite(ledR,50); // La Led s’allume à une intensité de 50 sur 255 -> faible intensité
 +
  Serial.print("x = ");
 +
  Serial.println(valeurX);
 +
  }
 +
  else{
 +
    digitalWrite(ledR, LOW );
 +
  }
 +
 
 +
  valeurX = analogRead(axex);
 +
  if (valeurX > 1022){ // droite ++, elle s’allume lorsque Joystick en position max
 +
  digitalWrite(ledRR, HIGH); // La Led à l’extrême droite  s’allume à l’intensité maximale
 +
  Serial.print("x = ");
 +
  Serial.println(valeurX);
 +
  else{
 +
  digitalWrite(ledRR, LOW );
 +
  }
 +
 
 +
  valeurX = analogRead(axex);
 +
  if (valeurX < 400){ // gauche
 +
  analogWrite(ledL,50);
 +
  Serial.print("x = ");
 +
  Serial.println(valeurX);
 +
  }
 +
  else
 +
  {
 +
  digitalWrite(ledL, LOW );
 +
  }
 +
 +
  valeurX = analogRead(axex);
 +
  if (valeurX < 1){  // gauche ++
 +
  digitalWrite(ledLL, HIGH);
 +
  Serial.print("x = ");
 +
  Serial.println(valeurX);
 +
  }else
 +
  {
 +
  digitalWrite(ledLL, LOW );
 +
  }
 +
 
 +
  valeurY = analogRead(axey);
 +
  if (valeurY > 700){ // haut
 +
  analogWrite(ledup,50);
 +
  Serial.print("y = ");
 +
  Serial.println(valeurY);
 +
  }else
 +
  {
 +
  digitalWrite(ledup, LOW );
 +
  }
 +
  valeurY = analogRead(axey);
 +
  if (valeurY > 1022){  // en haut ++
 +
  digitalWrite(ledupup, HIGH);
 +
  Serial.print("y = ");
 +
  Serial.println(valeurY);
 +
  }else
 +
  {
 +
  digitalWrite(ledupup, LOW );
 +
  }
 +
 +
valeurY = analogRead(axey);
 +
  if (valeurY < 400){ // bas
 +
  analogWrite(ledD,50);
 +
  Serial.print("y = ");
 +
  Serial.println(valeurY);
 +
  }else
 +
  {
 +
  digitalWrite(ledD, LOW );
 +
  }
 +
 
 +
  valeurY = analogRead(axey);
 +
  if (valeurY < 2){ // en bas ++
 +
  digitalWrite(ledDD, HIGH);
 +
  Serial.print("y = ");
 +
  Serial.println(valeurY);
 +
  }else
 +
  {
 +
  digitalWrite(ledDD, LOW );
 +
  }
 +
}
 +
 +
<font color = "blue">REMARQUE : </font>Pour obtenir la position précise du Joystick selon l’axe x et y, il faut aller dans le menu Outils -> Moniteur série, les valeurs défileront en temps réel.
 +
 +
 +
 +
Mots clés / Keywords: exercise, Arduino, joystick, LEDs, position, intensity, code, tutorial, lesson, analogRead, digitalWrite, analogWrite, GND, Vcc, A0, A1, SW Joystick, value, setup, loop, tutorial, example.
 +
 +
 +
[[Category:FCU]]

Latest revision as of 15:53, 29 September 2023

This page is available in English by following this link: https://wiki.collaborativebee.com//index.php?title=Exercise_Arduino_FCU_English

Vous trouverez sur cette page toutes les informations, exercices, et fichiers nécessaires à la prise en main et à la réalisation d'un prototype de FCU (Flight Control Unit) dans le cadre de travaux dirigés (TD) à faire en classe.

Quelques fonctions Arduino utiles

Void setup() : obligatoire en début de programme, cela correspond à l’initialisation du programme (indiquer les broches, les sorties, les entrées)

Void loop() : obligatoire dans un programme, cela correspond à la partie du programme qui va se répéter en boucle.

DigitalRead() / AnalogRead() : permet de lire l’état (HIGH ou LOW) d’un port digital/analogique de la carte Arduino.

DigitalWrite() / AnalogWrite() : permet d’écrire et donc de donner un état (HIGH ou LOW) à un port digital/analogique de la carte Arduino.

PinMode() : permet d’initialiser une broche et de la mettre en entrée ou sortie (ex : pinMode(1, OUTPUT))

Delay() : Fait une pause dans le programme (en ms).

Utiliser ce lien pour tout autre information ou autres fonctions Arduino : https://www.arduino.cc/reference/fr/

Voici quelques sites permettant de trouver tous les composants nécessaires pour le montage :
https://www.gotronic.fr/rechercher.htm
https://boutique.semageek.com/fr/2-arduino

Exercice 1 : Prise en main - Commander l'éclairage d'une LED

Cet exercice se décompose en 3 objectifs : allumer une LED, la faire clignoter et enfin commander son intensité lumineuse.

Le montage utilisé pour tout l'exercice se présente ainsi.

Schéma du montage

Matériel nécessaire

- Carte Arduino
- une LED
- Une résistance de 220 ohms
- une plaquette d’essai
- 2 fils mâle/mâle

Réalisation du montage

• Connecter la borne numérique (côté digital) numéro 1 de la carte Arduino à la patte de la résistance.
• Connecter la deuxième patte de la résistance à l’anode de la LED (borne +, tige la plus longue de la LED).
• Brancher la cathode (borne -, tige la plus courte) de la LED au GND de l’Arduino.


Etape 1 : allumage d'une LED

Pour pouvoir allumer cette LED, il faudra utiliser le code Arduino suivant.

void setup()
{
 pinMode(1, OUTPUT); 	//initialise la borne numérique numéro 1 de la carte Arduino en mode sortie 
} 
void loop() 
{ 
 digitalWrite(1, HIGH); 	//le courant est envoyé sur la borne 1, la LED s'allume 
}

Etape 2 : faire clignoter une LED

Ce code Arduino permet de faire clignoter une LED à une fréquence déterminée

void setup() 
{ 
 pinMode(1, OUTPUT); //Initialisation de la broche 1 en sortie 
} 
 
void loop() 
{ 
 digitalWrite(1, HIGH); //Mise au niveau Haut (Allumage) de la LED 
 delay(1000);		//Délai de 1000ms dans cette position (LED allumée) 
 digitalWrite(1, LOW);	//Mise au niveau bas (Eteint) de la LED 
 delay(1000);	//Délai de 1000ms dans cette position (LED éteinte) 
}

Vous pouvez retrouver une vidéo explicative sur ce lien : https://www.youtube.com/watch?v=OOR3dfWH8HE

Etape 3 : faire varier l'intensité lumineuse d'une LED

Ici le code va faire varier l’intensité lumineuse de la LED, de façon à ce que l’intensité augmente linéairement puis lorsque la LED atteint sa valeur maximale (valeur 255, valeur HIGH) puis arrivé a cette valeur, l’intensité lumineuse rediminue jusqu’à ce que la LED soit éteinte (valeur 0, LOW).

int LED = 3;	 // Définition des broches et variables utilisées
int x;		 // Rapport cyclique

void setup() 
{  
 pinMode(LED, OUTPUT);  
} 
 
void loop() 
{  
 x = 0;  
 while (x <= 255) // Allumer progressivement la LED (0 --> 255)
 {
  analogWrite(LED, x);  
  delay(10);  
  x = x+1; 
 }  
 x = 255; 
 while (x >= 0) // Eteindre progressivement la LED (255 --> 0)
 {
  analogWrite(LED, x);  
  delay(10);  
  x = x-1; 
 } 
}

Exercice 2 : Utiliser un gyroscope

L’implémentation d’un gyroscope sous Arduino permet de connaître les inclinaisons d’un appareil en mouvement.

Schéma du montage

Matériel nécessaire

- Carte Arduino
- Un gyroscope
- 4 fils mâle/femelle

Montage

• Connecter les bornes GND et VCC respectivement aux bornes GND et +5V de la carte Arduino
• Connecter la borne SCL du gyroscope à la borne analogique numéro A4
• Connecter la borne SCA du gyroscope à la borne analogique numéro A5

Ici, les bornes SCL et SDA correspondent aux axes x et y du gyroscope.

REMARQUE : On peut utiliser des LEDs sur une plaquette d’essai comme cela a été fait pour le Joystick afin de pouvoir voir quels sont les effets du gyroscope sur les LEDs.


Code Arduino

#include <Wire.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
MPU6050 mpu;
#define OUTPUT_READABLE_YAWPITCHROLL
#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;

bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };

// ================================================================
// ===               INTERRUPT DETECTION ROUTINE                ===
// ================================================================ 

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
   mpuInterrupt = true;
}
// ================================================================
// ===                      LEDS                                ===
// ================================================================

const int led_1 = 13 ;
const int led_2 = 12 ;
const int led_3 = 11 ;
const int led_4 = 10 ;
const int led_5 = 9 ;
const int led_6 = 8 ;
const int led_7 = 7 ;
const int led_8 = 6 ;
const int led_9 = 5 ;

// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================

void setup() {
    // LEDS
   
 pinMode(led_1, OUTPUT);
 pinMode(led_2, OUTPUT);
 pinMode(led_3, OUTPUT);
 pinMode(led_4, OUTPUT);
 pinMode(led_5, OUTPUT);
 pinMode(led_6, OUTPUT);
 pinMode(led_7, OUTPUT);
 pinMode(led_8, OUTPUT);
 pinMode(led_9, OUTPUT);
   
   // join I2C bus (I2Cdev library doesn't do this automatically)
   #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
       Wire.begin();
       TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
   #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
       Fastwire::setup(400, true);
   #endif

   Serial.begin(115200);
   while (!Serial); // wait for Leonardo enumeration, others continue immediately

   Serial.println(F("Initializing I2C devices..."));
   mpu.initialize();

   Serial.println(F("Testing device connections..."));
   Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

   Serial.println(F("\nSend any character to begin DMP programming and demo: "));
   while (Serial.available() && Serial.read()); // empty buffer
   while (!Serial.available());                 // wait for data
   while (Serial.available() && Serial.read()); // empty buffer again

   Serial.println(F("Initializing DMP..."));
   devStatus = mpu.dmpInitialize();

   // supply your own gyro offsets here, scaled for min sensitivity
   mpu.setXGyroOffset(220);
   mpu.setYGyroOffset(76);
   mpu.setZGyroOffset(-85);
   mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

   // make sure it worked (returns 0 if so)
   if (devStatus == 0) {
       // turn on the DMP, now that it's ready
       Serial.println(F("Enabling DMP..."));
       mpu.setDMPEnabled(true);

       // enable Arduino interrupt detection
       Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
       attachInterrupt(0, dmpDataReady, RISING);
       mpuIntStatus = mpu.getIntStatus();

       // set our DMP Ready flag so the main loop() function knows it's okay to use it
       Serial.println(F("DMP ready! Waiting for first interrupt..."));
       dmpReady = true;

       // get expected DMP packet size for later comparison
       packetSize = mpu.dmpGetFIFOPacketSize();
   } else {
       // ERROR!
       // 1 = initial memory load failed
       // 2 = DMP configuration updates failed
       // (if it's going to break, usually the code will be 1)
       Serial.print(F("DMP Initialization failed (code "));
       Serial.print(devStatus);
       Serial.println(F(")"));
   }

   // configure LED for output
   pinMode(LED_PIN, OUTPUT);
}
// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() {
   // if programming failed, don't try to do anything
   if (!dmpReady) return;

   // wait for MPU interrupt or extra packet(s) available
   while (!mpuInterrupt && fifoCount < packetSize) {
       // other program behavior stuff here
       // if you are really paranoid you can frequently test in between other
       // stuff to see if mpuInterrupt is true, and if so, "break;" from the
       // while() loop to immediately process the MPU data
   }

   // reset interrupt flag and get INT_STATUS byte
   mpuInterrupt = false;
   mpuIntStatus = mpu.getIntStatus();

   // get current FIFO count
   fifoCount = mpu.getFIFOCount();

   // check for overflow (this should never happen unless our code is too inefficient)
   if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
       // reset so we can continue cleanly
       mpu.resetFIFO();
       Serial.println(F("FIFO overflow!"));

   // otherwise, check for DMP data ready interrupt (this should happen frequently)
   } else if (mpuIntStatus & 0x02) {
       // wait for correct available data length, should be a VERY short wait
       while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

       // read a packet from FIFO
       mpu.getFIFOBytes(fifoBuffer, packetSize);
       
       // track FIFO count here in case there is > 1 packet available
       // (this lets us immediately read more without waiting for an interrupt)
       fifoCount -= packetSize;

       mpu.dmpGetQuaternion(&q, fifoBuffer);
       mpu.dmpGetGravity(&gravity, &q);
       mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);


// DEBUT DE NOTRE CODE 

// MPU
      int XX ; 
      int YY ;
      XX = (ypr[2] * 180/M_PI) * (128/90) ; // entre -128 et 128
      YY = (ypr[1] * 180/M_PI) * (128/90) ;

      // c'est p et r qui nous intéressent
 
      int puiss_led_11 ;
      int puiss_led_22 ;
      int puiss_led_33 ;
      int puiss_led_44 ;
      int puiss_led_55 ;
      int puiss_led_66 ;
      int puiss_led_77 ;
      int puiss_led_88 ;
      int puiss_led_99 ;
      
      puiss_led_11 = 100 + (0 * XX) - (1.5 * YY);
      puiss_led_22 = 100 - (0.75 * XX) - (1 * YY);
      puiss_led_33 = 100 + (0.75 * XX) - (1 * YY);
      puiss_led_44 = 100 - (1 * XX) - (0 * YY);
      puiss_led_55 = 100 + (1 * XX) - (0 * YY);
      puiss_led_66 = 100 - (1.25 * XX) + (1 * YY);
      puiss_led_77 = 100 - (0.75 * XX) + (1 * YY);
      puiss_led_88 = 100 + (0.75 * XX) + (1 * YY);
      puiss_led_99 = 100 + (1.25 * XX) + (1 * YY);

      analogWrite(led_1, puiss_led_11);
      analogWrite(led_2, puiss_led_22);
      analogWrite(led_3, puiss_led_33);
      analogWrite(led_4, puiss_led_44);
      analogWrite(led_5, puiss_led_55);
      analogWrite(led_6, puiss_led_66);
      analogWrite(led_7, puiss_led_77);
      analogWrite(led_8, puiss_led_88);
      analogWrite(led_9, puiss_led_99);

      // montrer dans la console les différentes intensités des LEDs
      Serial.print("XX = ");
      Serial.print(XX);
      Serial.print("YY = ");
      Serial.print(YY);
      Serial.print("\tPuiss 1 = ");
      Serial.print(puiss_led_11);
      Serial.print("\tPuiss 2 = ");
      Serial.print(puiss_led_22);
      Serial.print("\tPuiss 3 = ");
      Serial.print(puiss_led_33);
      Serial.print("\tPuiss 4 = ");
      Serial.print(puiss_led_44);
      Serial.print("\tPuiss 5 = ");
      Serial.print(puiss_led_55);
      Serial.print("\tPuiss 6 = ");
      Serial.print(puiss_led_66);
      Serial.print("\tPuiss 7 = ");
      Serial.print(puiss_led_77);
      Serial.print("\tPuiss 8 = ");
      Serial.print(puiss_led_88);
      Serial.print("\tPuiss 9 = ");
      Serial.println(puiss_led_99);

// FIN DE NOTRE CODE
         
     // blink LED to indicate activity
     blinkState = !blinkState;
     digitalWrite(LED_PIN, blinkState);
   }
}


Exercice 3A : Utiliser un joystick

L’implémentation d’un Joystick sous Arduino permet de récupérer des informations sur la position de celui-ci en temps réel. Ici on utilise des LEDs dans le montage afin d’obtenir un effet visuel. Cependant ces LEDs ne sont pas indispensable dans ce package.

Matériel nécessaire

- Carte Arduino

- Un Joystick

- 4 LEDs

- Au minimum 4 résistances de 220 ohms

- une plaquette d’essai

- 5 fils mâle/femelle

- 8 fils mâle/mâle

Montage

· Connecter les 4 LEDs avec les résistances de la plaquette d’essai sur la carte Arduino sur les broches digital (ex : 10, 11, 12, 13). Disposez-les en forme de losange afin de d’avoir une LED qui correspond à une direction du Joystick (gauche, haut, ...) (voir montage ci-après).

· Connecter le Joystick à la carte Arduino :

o La broche GND du Joystick doit être relié au GND de la carte Arduino

o La broche Vcc du Joystick doit être relié au +5V de la carte Arduino

o La broche VRx du Joystick doit être relié à A0 (côté analogique) de la carte Arduino

o La broche VRy du Joystick doit être relié à A1 (côté analogique) de la carte Arduino

o La broche SW Joystick doit être relié à la borne 2 (côté digital) de la carte Arduino

Schéma du montage

Sur ce montage, les LEDs permettront de connaître l’orientation du Joystick. En effet si le Joystick sera mis vers l’avant, une des LEDs s’allumera et les autres seront éteintes, alors la LED allumée représentera le côté avant du Joystick. De même pour les autres LEDs avec les autres côtés du Joystick.

Pour une analyse plus précise de la position du Joystick, allez dans Outils -> Moniteur série. Vous aurez les positions exactes du Joystick qui vous seront données.

REMARQUE : On peut ajouter plus de LEDs afin d’augmenter la précision des informations, par exemple si on ajoute 4 LEDs supplémentaires (8 LEDs au total disposé en cercle) alors on pourra déterminer si le Joystick est mis dans les positions diagonales : Nord-Est, Nord-Ouest, Sud-Est, Sud-Ouest.

Concernant le Joystick, les broches VRx et VRy correspondent aux positions Avant/Arrière et Gauche/Droite du Joystick. La broche SW représente un appui sur le Joystick car celui-ci se comporte aussi comme un bouton poussoir.

Code Arduino

// Arduino pin numbers 
const int SW_pin = 2; //On connecte la broche SW sur la borne digital 2 
const int X_pin = 0; //On connecte la broche X sur la borne analogique A0 
const int Y_pin = 1; //On connecte la broche Y sur la borne analogique A1 
 
#define UP_LED 10 
#define RIGHT_LED 11	//On définit les bornes des LEDs 
#define LEFT_LED 12 
#define DOWN_LED 13 
 
void setup() { 
 pinMode(SW_pin, INPUT); 
 digitalWrite(SW_pin, HIGH); 
 Serial.begin(115200); 

 pinMode(UP_LED, OUTPUT); 
 pinMode(RIGHT_LED, OUTPUT); // On définit les 4 LEDs en sorties 
 pinMode(LEFT_LED, OUTPUT); 
 pinMode(DOWN_LED, OUTPUT); 
}
 
void loop() { 
 Serial.print("Switch:  "); //Affichage dans le moniteur série des valeurs 
 Serial.print(digitalRead(SW_pin)); 
 Serial.print("\n"); 
 Serial.print("X-axis: "); 
 Serial.print(analogRead(X_pin)); 
 Serial.print("\n"); 
 Serial.print("Y-axis: "); 
 Serial.println(analogRead(Y_pin)); 
 Serial.print("\n\n"); 
  
 delay(500); 

 if(analogRead(X_pin) == 1023){ 	//Si le joystick est en avant, alors la   
   digitalWrite(UP_LED, HIGH); 	// LED UP s’allume 

} else if(analogRead(X_pin) == 0){ 		//Si le joystick est en arrière, alors la 
   digitalWrite(DOWN_LED, HIGH); 		// LED DOWN s’allume 
} 
else if(analogRead(Y_pin) == 1023){	 //Si le joystick est à gauche, alors la 
   digitalWrite(RIGHT_LED, HIGH); 		// LED RIGHT s’allume 
} 
else if(analogRead(Y_pin) == 0){ 		//Si le joystick est à droite, alors la	 
   digitalWrite(LEFT_LED, HIGH);  	        // LED LEFT s’allume 
} 

else if(digitalRead(SW_pin) == 0){ 		//S’il y a un appui sur le Joystick, 
 digitalWrite(UP_LED, HIGH); 		        //alors toutes les LEDs s’allument 
 digitalWrite(LEFT_LED, HIGH); 
 digitalWrite(RIGHT_LED, HIGH); 
 digitalWrite(DOWN_LED, HIGH); 
} 

else{				//S’il n’y a pas d’appui sur le Joystick, 
 digitalWrite(UP_LED, LOW); 	//alors toutes les LEDs s’éteignent 
 digitalWrite(LEFT_LED, LOW); 
 digitalWrite(RIGHT_LED, LOW); 
 digitalWrite(DOWN_LED, LOW); 
} 
}

Exercice 3B : Utiliser un joystick pour connaître la position (enfoncée ou non) de celui-ci (version simplifiée)

L’implémentation d’un Joystick sous Arduino permet de récupérer des informations sur la position de celui-ci en temps réel. Ici on utilise des LEDs dans le montage afin d’obtenir un effet visuel. Cependant ces LEDs ne sont pas indispensable dans ce package.

L’objectif est d’utiliser seulement 4 LEDs et ainsi faire varier l’intensité lumineuse de chaque LED en fonction de la position du Joystick. L’intensité lumineuse des LEDs va augmenter proportionnellement à la position du Joystick.

EXEMPLE : si le Joystick est légèrement incliné vers la droite, alors la LED de droite va scintiller avec une faible intensité et plus le Joystick va s’incliner, plus la LED de droite va avoir une intensité lumineuse élevée jusqu’à son maximale (Joystick enfoncé).

Matériel nécessaire

- Carte Arduino

- Un Joystick

- 4 LEDs

- Au minimum 4 résistances de 220 ohms

- une plaquette d’essai

- 4 fils mâle/femelle

- 12 fils mâle/mâle

Montage

• Connecter les 4 LEDs avec les résistances de la plaquette d’essai sur la carte Arduino sur les broches digital (ex : 10, 11, 12, 13). Disposez-les en forme de losange afin de d’avoir une LED qui correspond à une direction du Joystick (gauche, haut, ...) (voir montage ci-après).

• Connecter le Joystick à la carte Arduino :

o La broche GND du Joystick doit être relié au GND de la carte Arduino

o La broche Vcc du Joystick doit être relié au +5V de la carte Arduino

o La broche VRx du Joystick doit être relié à A0 (côté analogique) de la carte Arduino

o La broche VRy du Joystick doit être relié à A1 (côté analogique) de la carte Arduino

o La broche SW Joystick doit être relié à la borne 2 (côté digital) de la carte Arduino


REMARQUE : Pour une analyse plus précise de la position du Joystick, allez dans Outils -> Moniteur série. Vous aurez les positions exactes du Joystick qui vous seront données.


Code Arduino

int axey = A1;   // Entrée de référence pour l'axe Y. 
int axex = A0;   // Entrée de référence pour l'axe X. 
int ledD = 12;   // Led inférieur. Cette valeur est à adapter à votre montage ! 
int ledup = 9;    // Led supérieur. Cette valeur est à adapter à votre montage ! 
int ledL = 13;    // Led gauche. Cette valeur est à adapter à votre montage ! 
int ledR = 7;    // Led droite. Cette valeur est à adapter à votre montage ! 
int valeurX; 
int valeurY; 
 
void setup() {   
 Serial.begin(9600);	// Définition des leds comme sorties 
 pinMode(ledup, OUTPUT); 
 pinMode(ledD, OUTPUT); 
 pinMode(ledL, OUTPUT); 
 pinMode(ledR, OUTPUT);  
}
 
void loop() {   
 valeurX = analogRead(axex); 
 if (valeurX > 512){ // droite 
  analogWrite(ledR,(valeurX-513)/2); 		// Cette formule permet l’augmentation progressive de l’intensité lumineuse pour des valeurs comprises entre 513 et 1023 
  Serial.print("x = "); 
  Serial.println(valeurX); 
 }
 else 
 { 
  digitalWrite(ledR, LOW ); 
 }
 
 valeurX = analogRead(axex); 
 if (valeurX < 511){ // gauche 
  analogWrite(ledL,(-valeurX+510)/2);		// Cette formule permet l’augmentation progressive de l’intensité lumineuse pour des valeurs comprises entre 0 et 510 
  Serial.print("x = "); 
  Serial.println(valeurX); 
 }
 else 
 { 
  digitalWrite(ledL, LOW ); 
 } 

 valeurY = analogRead(axey); 
 if (valeurY > 512){ // bas 
  analogWrite(ledD, (valeurY-513)/2); 		// Cette formule permet l’augmentation progressive de l’intensité lumineuse pour des valeurs comprises entre 513 et 1023 
  Serial.print("y = "); 
  Serial.println(valeurY); 
 }
 else
 { 
  digitalWrite(ledD, LOW ); 
 } 

valeurY = analogRead(axey); 
if (valeurY < 511){ // haut 
 analogWrite(ledup,(-valeurX+510)/2);	// Cette formule permet l’augmentation progressive de l’intensité lumineuse pour des valeurs comprises entre 0 et 510 
 Serial.print("y = "); 
 Serial.println(valeurY); 
 }
 else
 { 
  digitalWrite(ledup, LOW ); 
 } 
} 

REMARQUE : Dans ce code, il y a 2 formules importantes (une pour les valeurs 0 à 510 des positions de Joystick et une pour les valeurs 513 à 1023). En effet, pour chaque axe (x et y du Joystick), on a une valeur associée de 0 (gauche ou bas) à 1023 (droite et haut). Ainsi avec les formules rentrées au niveau de la valeur de l’intensité lumineuse de la LED (fonction AnalogWrite), on a pour les valeurs proches de 512 une intensité lumineuse nulle (LED éteinte) car Joystick très faiblement incliné. En revanche pour les valeurs proche de 0 ou 1023, en utilisant la bonne formule associée, on a une intensité lumineuse de la LED maximale (valeur max : 255).

Exercice 3C : Utiliser un joystick pour connaître la position (enfoncée ou non) de celui-ci (version complète)

L’implémentation d’un Joystick sous Arduino permet de récupérer des informations sur la position de celui-ci en temps réel. Ici on utilise des LEDs dans le montage afin d’obtenir un effet visuel. Cependant ces LEDs ne sont pas indispensable dans ce package.

L’objectif est ici que lorsque le Joystick est incliné à 50% dans une direction (ex : gauche) on a une LED qui s’allume à 50% de son intensité maximale. Puis lorsque le Joystick est en position maximale à gauche, une 2ème LED s’allume à intensité maximale.

Matériel nécessaire

- Carte Arduino

- Un Joystick

- 8 LEDs

- Au minimum 8 résistances de 220 ohms

- une plaquette d’essai

- 4 fils mâle/femelle

- 12 fils mâle/mâle

Montage

• Connecter les 8 LEDs avec les résistances de la plaquette d’essai sur la carte Arduino sur les broches digital (ex : 10, 11, 12, 13). Disposez-les en forme de losange (2dans chaque direction) afin de d’avoir une LED qui correspond à une direction du Joystick (gauche, haut, ...) (voir montage ci-après).

• Connecter le Joystick à la carte Arduino :

o La broche GND du Joystick doit être relié au GND de la carte Arduino

o La broche Vcc du Joystick doit être relié au +5V de la carte Arduino

o La broche VRx du Joystick doit être relié à A0 (côté analogique) de la carte Arduino

o La broche VRy du Joystick doit être relié à A1 (côté analogique) de la carte Arduino

o La broche SW Joystick doit être relié à la borne 2 (côté digital) de la carte Arduino

• Rappel : Chaque LED a besoin d'une résistance de 220 ohms en série pour protéger le circuit. Branchez la cathode de chaque LED (le segment le plus court) à la masse et l'anode (le segment le plus long) à un port de sortie numérique digital.

• Le Joystick agit comme 2 potentiomètres : Sa position horizontale est donnée par un nombre de 0 (gauche) à 1023 (droite). Même chose en verticale (valeur moyenne 512)

• On rajoute des conditions dans le code. (Voir code ci-dessous).

EXEMPLE : Si la valeur du Joystick est inférieure à une valeur donnée (ex : 300, Joystick légèrement incliné) alors la 1ère LED s'allume (intensité faible voir slide LED), puis si la valeur est minimale (0, Joystick enfoncé) alors la 2nde LED s'allume (intensité max).

Schéma du montage

REMARQUE : Le montage correspond au montage ci-dessus avec l’ajout de 4 LEDs, on ajoute une LED à chaque extrémité (haut, bas, gauche, droite).

Illustration

Joystick relié à la carte Arduino dans 3 positions différentes

Code Arduino

int axey = A1;   	// Entrée de référence pour l'axe Y. 
int axex = A0;	   // Entrée de référence pour l'axe X. 
int ledup = 12; 	  // Led inférieur. Cette valeur est à adapter à votre montage ! 
int ledupup = 10;  // Led inférieur ++. Cette valeur est à adapter à votre montage ! 
int ledD = 9; 	   // Led supérieur.			“” 
int ledDD = 5;   	// Led supérieur ++.			“” 
int ledL = 13;  	  // Led gauche.				“” 
int ledLL = 11;  	  // Led gauche ++.			“” 
int ledR = 7;    	// Led droite.				“” 
int ledRR = 8;   	// Led droite ++.			“” 
int valeurX; 
int valeurY; 
  
void setup() {   
 Serial.begin(9600);	// Définition des leds comme sorties 
 pinMode(ledup, OUTPUT); 
 pinMode(ledupup, OUTPUT); 
 pinMode(ledD, OUTPUT); 
 pinMode(ledDD, OUTPUT); 
 pinMode(ledL, OUTPUT); 
 pinMode(ledLL, OUTPUT);  
 pinMode(ledR, OUTPUT);  
 pinMode(ledRR, OUTPUT);  
}
 
void loop() {   
 valeurX = analogRead(axex); 
 if (valeurX > 700){ 		// droite 
  analogWrite(ledR,50);	// La Led s’allume à une intensité de 50 sur 255 -> faible intensité 
  Serial.print("x = "); 
  Serial.println(valeurX); 
 }
 else{ 
   digitalWrite(ledR, LOW ); 
 }
 
 valeurX = analogRead(axex); 
 if (valeurX > 1022){ 		// droite ++, elle s’allume lorsque Joystick en position max 
  digitalWrite(ledRR, HIGH);	// La Led à l’extrême droite  s’allume à l’intensité maximale 
  Serial.print("x = "); 
  Serial.println(valeurX); 
 else{ 
  digitalWrite(ledRR, LOW ); 
 }
 
 valeurX = analogRead(axex); 
 if (valeurX < 400){ 		// gauche 
  analogWrite(ledL,50); 
  Serial.print("x = "); 
  Serial.println(valeurX); 
 }
 else
 { 
  digitalWrite(ledL, LOW ); 
 } 

 valeurX = analogRead(axex); 
 if (valeurX < 1){  		// gauche ++ 
  digitalWrite(ledLL, HIGH); 
  Serial.print("x = "); 
  Serial.println(valeurX); 
 }else
 { 
  digitalWrite(ledLL, LOW ); 
 } 
  
 valeurY = analogRead(axey); 
 if (valeurY > 700){ 		// haut 
  analogWrite(ledup,50); 
  Serial.print("y = "); 
  Serial.println(valeurY); 
 }else
 { 
  digitalWrite(ledup, LOW ); 
 } 
 valeurY = analogRead(axey); 
 if (valeurY > 1022){  		// en haut ++ 
  digitalWrite(ledupup, HIGH); 
  Serial.print("y = "); 
  Serial.println(valeurY); 
 }else
 { 
  digitalWrite(ledupup, LOW ); 
 }

valeurY = analogRead(axey); 
 if (valeurY < 400){		 // bas 
  analogWrite(ledD,50); 
  Serial.print("y = "); 
  Serial.println(valeurY); 
 }else
 { 
  digitalWrite(ledD, LOW ); 
 }
 
 valeurY = analogRead(axey); 
 if (valeurY < 2){ 		// en bas ++ 
  digitalWrite(ledDD, HIGH); 
  Serial.print("y = "); 
  Serial.println(valeurY); 
 }else
 { 
  digitalWrite(ledDD, LOW ); 
 } 
} 

REMARQUE : Pour obtenir la position précise du Joystick selon l’axe x et y, il faut aller dans le menu Outils -> Moniteur série, les valeurs défileront en temps réel.


Mots clés / Keywords: exercise, Arduino, joystick, LEDs, position, intensity, code, tutorial, lesson, analogRead, digitalWrite, analogWrite, GND, Vcc, A0, A1, SW Joystick, value, setup, loop, tutorial, example.