Difference between revisions of "Exercice Arduino FCU"
Wiki.admin (talk | contribs) |
Wiki.admin (talk | contribs) |
||
Line 387: | Line 387: | ||
== Exercice 3A : Utiliser un joystick == | == Exercice 3A : Utiliser un joystick == | ||
+ | |||
+ | <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 | ||
+ | |||
+ | - 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 | ||
+ | |||
+ | |||
+ | 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. | ||
+ | |||
+ | <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); | ||
+ | } | ||
+ | } |
Revision as of 12:48, 21 February 2023
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.
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.
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é 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).
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.
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
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
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); } }