programmation arduino -...

12
10/03/2018 Programmation Arduino - PWM analogWrite et applications MLK - ECST

Upload: others

Post on 25-Oct-2019

12 views

Category:

Documents


0 download

TRANSCRIPT

10/03/2018

Programmation Arduino

- PWM analogWrite et applications

MLK - ECST

Programmation Arduino – PWM analogWrite et applications

TP déductif 1

Présentation du matériel .......................................................................................................... 2

Variation d’intensité lumineuse ............................................................................................... 2

Variation d’intensité lumineuse soft (logicielle) ................................................................... 2

1. Rapport cyclique à 100% ........................................................................................................................... 2

2. Rapport cyclique à 0% ............................................................................................................................... 3

3. Rapport cyclique et valeur moyenne, définitions .................................................................................... 3

Variation d’intensité lumineuse hard (matérielle) ............................................................... 4

1. Fonction analogWrite(pin,valeur); ........................................................................................................... 4

Variation de vitesse et de sens de rotation sur un MCC ........................................................... 5

Compatibilité en puissance entre un MCC et un Arduino .................................................... 5

Interface de puissance ........................................................................................................... 5

1. Schéma de principe.................................................................................................................................... 5

2. Inversion de sens, variation de vitesse et freinage : Le Pont en H .......................................................... 5

Application : Interface de puissance Motor Shield .............................................................. 6

Mesure de la vitesse réelle du moteur .................................................................................. 8

Asservissement de la vitesse à une vitesse de consigne ...................................................... 11

Programmation Arduino – PWM analogWrite et applications

2

Programmation Arduino - PWM analogWrite et applications

Centre d’intérêt : CI2 Instrumentation-Acquisition et restitution de grandeurs physiques

Objectif et Compétences : CO7.sin1 : Décoder la notice technique d’un système CO7.sin2 : Faire des mesures et mise en conformité

Compétences spécifiques : Structures fondamentales du langage C pour Arduino

Pré-requis : Cours/TP « Programmation sur Arduino »

Type : TP déductif

Présentation du matériel

L’objectif est de contrôler la vitesse d’un moteur. Nous allons utiliser : une carte Arduino Uno, avec le logiciel

Arduino IDE, une LED sur interface Grove un module analyseur logique USBee SX avec le logiciel USBee

Suite, une interface de puissance Motor Shield et un petit MCC (moteur à courant continu).

Dans un second temps, un capteur optique ou et un afficheur LCD grove I2C pour déterminer et contrôler la

vitesse du MCC.

Arduino UNO

LED et interface grove

USBee SX

Motor Shield (interface de puissance pour moteurs)

MCC Moteur à Courant Continu

Capteur optique, LCD et potentiomètre

grove

Variation d’intensité lumineuse

Connectez la LED sur D3 de carte Arduino. Connectez également cette entrée à D3 de l’analyseur logique.

Variation d’intensité lumineuse soft (logicielle)

1. Rapport cyclique à 100%

Dans le dossier SIN de votre lecteur P, créer et tester le programme PWM_soft.ino.

Vérifiez l’allure de la sortie D3 sur USBee Suite en conservant uniquement l’affichage

Digital 3.

#define pinLed1 3 void setup() // Fonction de configuration { pinMode(pinLed1, OUTPUT); } void loop() // Fonction principale boucle { digitalWrite(pinLed1,HIGH); }

Programmation Arduino – PWM analogWrite et applications

TP déductif 3

Commentez le programme, son influence sur le chronogramme et sur le fonctionnement de la LED.

On dira dans ce cas que le rapport cyclique, proportionnel à l’énergie électrique véhiculé par le signal, est à

100%.

2. Rapport cyclique à 0%

Modifiez le programme en faisant passer D3 à 0. Visualisez le chronogramme sur l’analyseur logique et

commentez ce dernier ainsi que l’état de la LED. On dira dans ce cas que le rapport cyclique est à 0%.

3. Rapport cyclique et valeur moyenne, définitions

En utilisant la fonction delayMicroseconds(us), Modifiez le programme de manière à ce que D3 soit

périodiquement à 0 pendant 500µs puis à 1 pendant 500µs. Visualisez le chronogramme sur l’analyseur

logique et commentez ce dernier ainsi que l’état de la LED.

Modifiez le programme et visualiser sur l’analyseur logique les cas suivants. Mesurez α (en %) dans la zone

measurements (Duty Cycle) de l’analyseur. Calculez UMOY (en Volts), tracez UMOY et entourez l’état de la LED.

La réponse de la LED en intensité lumineuse est elle linéaire ?

Faire vérifier vos résultats par le professeur.

α = __________ UMOY = _______

T = 1000µs 0

5V

t (ms)

U (V) TON = 900µs TOFF = _____

LED

α = __________ UMOY = _______

T = 1000µs 0

5V

t (ms)

U (V) TON = 750µs TOFF = _____

LED

α = __________ UMOY = _______

T = 1000µs 0

5V

t (ms)

U (V) TON = 600µs TOFF = _____

LED

α = __________ UMOY = _______

T = 1000µs 0

5V

t (ms)

U (V) TON = 450µs TOFF = _____

LED

α = __________ UMOY = _______

T = 1000µs 0

5V

t (ms)

U (V) TON = 300µs TOFF = _____

LED

α = __________ UMOY = _______

T = 1000µs 0

5V

t (ms)

U (V) TON = 10µs TOFF = _____

LED

U (V)

t (ms)

UMAX

αT T 0

A UMOY

TON TOFF

La valeur moyenne du signal UMOY est égale à l’air A divisée par la période T de ce même signal :

UMOY = A / T

Or A = UMAX x TON

Donc UMOY = UMAX x TON / T

On appelle le rapport TON / T le rapport cyclique α du signal : la durée au niveau haut par rapport

à la période du signal exprimé en %.

D’où UMOY = UMAX x α

Application : UMAX = 5V TON = 500µs TOFF = 500µs

T = ___________ A = ___________ α = ___________ UMOY = ___________

Programmation Arduino – PWM analogWrite et applications

4

Le fait de faire varier le rapport cyclique ou Duty Cycle pour faire varier la valeur moyenne du signal est appelé

PWM (Pulse Width Modulation) ou en français MLI (Modulation de Largeur d’Impulsion).

Variation d’intensité lumineuse hard (matérielle)

1. Fonction analogWrite(pin,valeur);

Dans le dossier SIN de votre lecteur personnel, créer et tester le programme PWM_hard.ino. Observez

l’allure des sorties D3 puis D5 sur USBee Suite pour les différentes valeurs de pinLed1 et valeur du

tableau. Mesurez TON, TOFF ainsi que le Duty Cycle α.

#define pinLed1 3 // À modifier #define valeur 127 // À modifier void setup() // Fonction de configuration { pinMode(pinLed1, OUTPUT); } void loop() // Fonction principale boucle { analogWrite(pinLed1,valeur); }

pinLed1 valeur 0 64 127 191 255

3

TON

TOFF

α

5

TON

TOFF

α

Quelle est la différence entre les sorties 3 (PWM3) et 5 (PWM5) ?

Seules les sorties marquées d’un tilde ~ sont capables de délivrer de la PWM.

À l’aide de l’analyseur logique, trouvez celles qui

délivrent la même fréquence que D3 ?

Quelles sont celles qui délivrent la même

fréquence que D5 ?

Compléter le code qui a permis d’obtenir les sorties PWM3 et la PWM5. Testez avec l’analyseur.

#define pinLed1 __ // À compléter #define valeur __ // À compléter void setup() // Fonction de configuration { pinMode(pinLed1, OUTPUT); } void loop() // Fonction principale boucle { analogWrite(pinLed1,valeur); }

#define pinLed1 __ // À compléter #define valeur __ // À compléter void setup() // Fonction de configuration { pinMode(pinLed1, OUTPUT); } void loop() // Fonction principale boucle { analogWrite(pinLed1,valeur); }

Programmation Arduino – PWM analogWrite et applications

TP déductif 5

Appliquez sur PWM3 et sur PWM5 le même rapport cyclique α (par exemple 50%) et câblez la LED successivement sur les deux sorties. L’intensité lumineuse est-elle différente malgré la fréquence du signal différente ? Conclure.

Variation de vitesse et de sens de rotation sur un MCC

Compatibilité en puissance entre un MCC et un Arduino Sur Internet, recherchez le courant max d’une sortie digitale d’un Arduino :

Les tous petits MCC (Moteurs à Courant Continu) illustrés en première page et alimentés en 12V ont

généralement une puissance inférieure à 5W.

Calculez le courant électrique nécessaire pour l’alimenter. Rappel : P = U x I avec P en W, U en V et I en A :

La carte Arduino permet d’alimenter directement le moteur MCC ? justifiez votre réponse.

Interface de puissance : Généralités En pratique, on n’applique que très rarement une tension continue sur un MCC (Moteur à courant continu).

On utilise plutôt une commande en MLI (Modulation de largeur d’impulsion) pour faire varier la vitesse qui

présente l’avantage d’avoir un meilleur rendement : les pertes de puissance dans la partie commande du

moteur sont plus faibles (moins d’échauffements).

1. Schéma de principe

Conclure sur la puissance théorique consommée par la partie commande du moteur :

2. Inversion de sens, variation de vitesse et freinage : Le Pont en H

Arbre moteur

libre

Sens 1 Sens 2

Freinage 1 Freinage 2

M MLI

Partie

commande

Deux cas en

fonction de

TON et TOFF :

I = 0A

U>0V

I > 0A

U=0V

P = U x I = _________

P = U x I = _________

Programmation Arduino – PWM analogWrite et applications

6

Complétez l’état des interrupteurs (0 = ouverts ou 1 = fermés) pour les différents mode de fonctionnement du moteur :

Les interrupteurs A, B, C et D seront commandés par les sorties digitales (GPIO) de l’Arduino et détermineront le sens de rotation ou le freinage du MCC. Ajouté à cela, une sortie PWM de l’Arduino sera reliée à une commande En (Enable) de la carte Motor Shield afin de faire varier la vitesse du MCC.

Application : Interface de puissance Motor Shield On utilise une interface de puissance pour amplifier le courant de sortie de l’Arduino. L’alimentation du

moteur peut ne pas être la même que celle de l’Arduino. De plus, cette interface intègre des protection contre

les phénomènes électromagnétiques.

L’interface de puissance Motor Shield est organisée autour d’un composant L298. Ce composant est un double pont en H qui permet donc de commander deux MCC. Dans ce dernier, les interrupteurs A, B, C et D sont réalisés par des transistors bipolaires (fermés lorsque leur commande est à 1)

Indiquez les connexions conformément à l’exemple :

Mode de fonctionnement

A B C D

Arbre moteur libre

Arbre moteur sens 1

Arbre moteur sens 2

Arbre moteur freiné 1

Arbre moteur freiné 2

5

1. Connexions moteur 1 2. Commande interrupteurs A et B moteur 1 3. Commande interrupteurs C et D moteur 1 4. Commande PWM moteur 1 5. Connexions moteur 2 6. Commande interrupteurs A et B moteur 2 7. Commande interrupteurs C et D moteur 2 8. Commande PWM moteur 2

A C

B D

A C

B D 6

7

8

Chaîne d’information

Acquérir (Capteurs)

Traiter (microcontrôleur)

Chaîne d’énergie

Alimenter (Batterie)

Moduler (Interface de puissance

- Pont en H)

Convertir (Moteur électrique)

Transmettre (Réducteur de vitesse)

Action

Restituer (Timer PWM) Matière

d’œuvre entrante

Matière d’œuvre Sortante

Motor Shield

Vitesse réelle

Consignes de vitesse

Énergie d’entrée

(Chargeur - bloc secteur)

Arduino

MCC

Programmation Arduino – PWM analogWrite et applications

TP déductif 7

Quel est l’état des transistors A et B lorsque EnA est à 1 (en fonction de In1) ?

□ Identique □ Complémentairement

Quel est leur état lorsque EnA = 0

□ Ouvert □ Fermé

Conclure sur le rôle de EnA :

Conclure sur le rôle de In1, In2, In3 et In4 :

Faire vérifier vos résultats par le professeur.

Le schéma structurel de la carte électronique Motor Shield est donné ci-dessous ou en suivant ce lien pour une

meilleure définition : http://stiddsin.free.fr/explorer/Cours-TD-TP/Motor_shield_2.0.pdf

On souhaite trouver les connexions entre l’Arduino et la carte Motor Shield pour pouvoir créer le programme qui pilote le moteur.

Motor Shield Arduino

Entrées GPIO Code

IN1 D8 #define IN1 8

IN2

EA

IN3

IN4

EB

Les caractéristiques électriques du composant L298 sont les suivantes. Ce composants permet-il de piloter deux moteurs MCC cités précédemment ? Justifiez votre réponse.

________________________________

________________________________

________________________________

________________________________

________________________________

ARDUINO

Programmation Arduino – PWM analogWrite et applications

8

En observant le schéma de la carte Motor Shield ci-dessus, indiquez le rôle des LED bleues. Justifiez votre réponse.

En observant le schéma de la carte Motor Shield ci-dessus, indiquez le rôle des LED rouges et vertes. Justifiez votre réponse.

Complétez le programme suivant afin d’être en conformité avec le câblage de la carte Motor Shield.

#define EA _________ // Entrée PWM à compléter #define IN1 _________ // À compléter #define IN2 _________ // À compléter void setup() // Fonction de configuration { pinMode(EA, OUTPUT); // EA en sortie pinMode(IN1, OUTPUT); // IN1 en sortie pinMode(IN2, OUTPUT); // IN2 en sortie } void loop() // Fonction principale boucle { analogWrite(EA,255); // 255 correspond à un rapport cyclique de 100% digitalWrite(IN1,LOW); // Si IN1=0 IN2=1 alors sens horaire digitalWrite(IN2,HIGH); // Si IN1=1 IN2=0 alors sens anti-horaire }

Effectuez le câblage du moteur 1 sur la carte Motor Shield et testez le programme avec plusieurs valeurs de

rapport cyclique pour les deux sens de rotation.

Comment évolue la vitesse du moteur en fonction du rapport cyclique appliqué sur EA ?

Comment évolue le sens de rotation du moteur en fonction des niveaux logiques sur IN1 et IN2 ?

Faire vérifier vos résultats par le professeur.

Mesure de la vitesse réelle du moteur

Le programme ci-dessous permet de commander la vitesse du moteur et d’en afficher sa vitesse sur le LCD.

La fonction analogRead() est utilisée pour lire la vitesse de consigne du moteur à partir d’un potentiomètre connecté sur A0 du CAN (Convertisseur Analogique Numérique).

La fonction map() est utilisée pour appliquer le rapport cyclique de 0 à 100% sur le moteur, soit faire correspondre l’intervalle 0-1023 du convertisseur analogique numérique à 0-255 de la MLI analogWrite() :

La vitesse du moteur est obtenue grâce au capteur optique. Chaque front montant (passage de 0 à 1) généré par le capteur optique fait partir le programme en interruption où est incrémentée la variable nbFrontMontant puis, en fonction du nombre de front montant par tour (qui dépend du nombre de secteurs sur le disque optique) et de l’intervalle de temps entre deux mesures, le programme calcule le nombre de tours par minute effectués par le moteur.

Effectuez une lecture attentive du programme ci-dessous (et des commentaires) afin d’en comprendre le sens.

Programmation Arduino – PWM analogWrite et applications

TP déductif 9

#include <Wire.h> // Pour la communication I2C #include <rgb_lcd.h> // pour piloter le LCD #define colorR 255 // Fond d’écran rouge au maximum #define colorG 255 // Fond d’écran vert au maximum #define colorB 255 // Fond d’écran bleu au maximum #define pinCapteur 2 // Pin 2 (OU 3 seulement) pour les interruptions avec un arduino uno #define EA 9 // Pin 9 pour EA de la PWM du moteur 1 #define IN1 8 // Pin 8 pour IN1 du sens du moteur 1 du moteur #define IN2 11 // Pin 11 pour IN2 du sens du moteur 1 du moteur #define n 10 // Constante pour le rafraichissement de l’affichage tous les n tours #define nbrFrontMontantParTour 4 // Dépend du nombre de secteurs sur le disque optique rgb_lcd lcd; // Renomme rgb_lcd en lcd (plus court) float nbFrontMontant = 0; // Variable globale pour le comptage du nombre de fronts montants unsigned long temps1 = millis(); // Variable globales pour la mesure du temps float trmin = 0; // Variable globale pour le nombre de tour/min du moteur void setup() // Fonction de configuration { pinMode(pinCapteur, INPUT); // Pin de connexion du capteur optique en entrée pinMode(EA, OUTPUT); // Pin de connexion EA de la PWM du moteur 1 en sortie pinMode(IN1, OUTPUT); // Pin de connexion IN1 du sens du moteur 1 en sortie pinMode(IN2, OUTPUT); // Pin de connexion IN2 du sens du moteur 1 en sortie digitalWrite(IN1,LOW); // Si IN1=0 IN2=1 alors sens horaire digitalWrite(IN2,HIGH); // Si IN1=1 IN2=0 alors sens anti-horaire lcd.begin(16, 2); // Configuration lignes colonnes du LCD lcd.setRGB(colorR, colorG, colorB); // Application de la couleur du fond d’écran delay(1000); // pause attachInterrupt(digitalPinToInterrupt(pinCapteur), nouveauTourInterrupt, RISING); // Appelle de la fonction nouveauTourInterrupt() à chaque front montant du signal sur pinCapteur } void loop() { // Commande du moteur : int DutyCycle = analogRead(A0); // Lecture du convertisseur analogique numérique DutyCycle = map(DutyCycle, 0, 1023, 0, 255); // [0,1023] -> [0,255] pour 0% à 100 % de vitesse analogWrite(EA, DutyCycle); // écriture de la PWM vers le moteur lcd.setCursor(0,0); // Sélection de la première ligne de l’afficheur lcd.print("DutyCycle : "); // écriture du texte « DutyCycle : » lcd.print(DutyCycle*100/255); // Affichage de la valeur du rapport cyclique lcd.print("% "); // Affichage du caractère ‘%’ // On ne va rafraichir l’affichage du calcul que tous les n tours de moteur : if(nbFrontMontant >= nbrFrontMontantParTour*n) // ex : 4 * 10 = 40 alors on a fait 10 tours { detachInterrupt(digitalPinToInterrupt(pinCapteur)); // InTerruptions OFF // Mesure de la vitesse : trmin = ((unsigned long)60000*n)/(millis() - temps1); // n tours dans un certain intervalle de temps en millisecondes qu’on convertit en minutes temps1 = millis(); // Nouvelle origine de temps pour la prochaine mesure dans n tours lcd.setCursor(0,1); // Sélection de la deuxième ligne de l’afficheur lcd.print("tr/min : "); lcd.print(trmin); // Affichage du nombre de tour par min sur l’afficheur nbFrontMontant = 0; // Réinitialisation var tour avant réactivation des interruptions attachInterrupt(digitalPinToInterrupt(pinCapteur), nouveauTourInterrupt, RISING); // IT ON } } void nouveauTourInterrupt() // Fonction exécutée lors des interruptions { // A chaque front montant généré par le capteur optique, nbFrontMontant ++; // On incrémente la variable tour }

Programmation Arduino – PWM analogWrite et applications

10

D’après le programme, sur quelle broche est connecté le capteur optique ?

___________________________________________________________________________

Combien de fronts montants sont générés pour un tour de moteur d’après la constante nbrFrontMontantParTour ?

___________________________________________________________________________

Noircissez les secteurs sur le disque optique afin de correspondre à la valeur de nbrFrontMontantParTour et le complétez le chronogramme correspondant sachant qu’un secteur blanc correspond à un niveau bas sur D2.

Tester le programme et relever la vitesse de ce dernier en fonction du rapport cyclique.

Vitesse (tr/min)

Rapport cyclique

(%)

20 30 40 50 60 70 80 90 100 0 10 0

10 000

5 000

1

2

3

4

5

6

7

8

3 4 5 6 7 8 1 2 3 1 2

pinCapteur D2

0

1

Fronts

Capteur

optique

Vers D2

Arduino

Programmation Arduino – PWM analogWrite et applications

TP déductif 11

Asservissement de la vitesse à une vitesse de consigne

Maintenant que nous pouvons commander et mesurer la vitesse du moteur, nous allons l’asservir à une valeur

de consigne. L’objectif est d’avoir une vitesse constante et égale à la vitesse de consigne quelque soit le couple

mécanique résistant sur l’arbre moteur (dans la limite des performances du moteur).

Principe :

Changer ces lignes de codes :

// Commande du moteur : int DutyCycle = analogRead(A0); // Lecture du convertisseur analogique numérique DutyCycle = map(DutyCycle, 0, 1023, 0, 255); // [0,1023] -> [0,255] pour 0% à 100 % de vitesse analogWrite(EA, DutyCycle); // écriture de la PWM vers le moteur

par celles-ci après les avoir complétées : // Commande du moteur : int DutyCycle; int consigne = analogRead(A0); // Lecture du convertisseur analogique numérique consigne = map(consigne, 0, 1023, 0, ____); // [0,1023]->[0,vitesse max] mesurée précédemment if(trmin < consigne) { if(DutyCycle<255) { DutyCycle= DutyCycle+1; // } } else { if(DutyCycle>0) { DutyCycle= DutyCycle-1; // } } analogWrite(EA, DutyCycle); // écriture de la PWM vers le moteur

Tester le programme en agissant sur la valeur de la constante n qui va déterminer la rapidité de l’asservissement donc influencer sa stabilité. Commentez le résultat

___________________________________________________________________________

Faire vérifier vos résultats par le professeur.

Mesure vitesse de

consigne

Mesure vitesse

réelle

Si vitesse réelle <

vitesse consigne

Vitesse -- Vitesse ++

oui

non