Imprimer
Catégorie : Programmation avancée
Affichages : 2913


Préambule


Les cartes arduino classiques (comme celle qui équipe les mini voitures qui seront utilisées) n'ont pas de chip wifi. Il faut donc leur adjoindre un "shield" (i.e. une carte additionnelle prévue pour se fixer sur les connecteurs de l'arduino) qui inclut ce chip. Il existe cependant d'autres micro-controleurs qui ont le wifi intégré, par exemple les esp32, ou leur "petit-frère" les esp8266.
Il existe plein de fabriquants de matériel électronique qui proposent de mini cartes basées sur ces deux micro-controleurs. Celle qui va être utilisée dans ce TP est de la firme TTGO, et s'appelle la T8. Ce fabriquant propose plusieurs types de cartes relativement bien pensées, et surtout très peu chères. 
Grâce au kit de développement arduino pour ces cartes (fourni par le concepteur de l'esp32), il est extrêmement facile de créer des programmes plus ou moins complexes, utilisant des bibliothèques tierces afin de gérer des modules externes, tels que des capteurs (température, son, lumière, ...), des afficheurs, des moteurs, etc.

ATTENTION ! les composants de ces cartes sont fragiles donc des erreurs de manipulation peuvent facilement "cramer" la carte

 


Préambule

 

Pour ce TP, la platine d'expérimentation ( = "planche à pain" = breadboard) est déjà complètement câblée. Si vous n'avez jamais utilisé de planche à pain, il faut savoir 2-3 choses à leur sujet :

L'image ci-dessous correspond à un exemple de planche à pain, identique à celle utilisée dans les TPs, à part sa longueur :

La planche à pain utilisée pour le TP comporte :

Le câblage est le suivant  (avec le µC placé à droite de la planche) :

 

NB : le BME280 n'est pas utilisé dans ce TP.

 

Exercice 1 : mise en place logicielle

 

1.1°/ Pour les machines du département

 

##########################
# PATH for arduino
##########################
export PATH=$PATH:/opt/arduino-1.8.19
 
1.2°/ Pour votre machine personnelle.
 
 

 

 

 

Exercice 2 : LED+switch

 
Remarques préliminaires :
  

  • Lancez arduino et créez un nouveau sketch (menu "Fichier" -> "Nouveau") nommé par exemple esp32_ledswitch.
  • Dans setup(), le sketch doit :
    • initialiser la liaison série avec l'ordinateur, à 115200 bauds,
    • initialiser la "direction" des pins du switch et de la LED,
    • envoyer "OK" à l'ordinateur.
  • Dans loop(), le sketch doit :
    • récupérer l'état du switch,
    • si l'état = 1, alors allumer la LED,
    • si l'état = 0, alors éteindre la LED,
    • attendre 500ms.
 
Exercice 3 : LED+switch+interruption
 
Remarque préliminaire :
  • Dans l'exercice 2, si on bouge 2 fois le switch pendant le temps d'attente de 500ms, on manque un changement d'état, ce qui peut être préjudiciable selon les applications.
  • Pour éviter cela, on utilise les interruptions.
  
  • Lancez arduino et créez un nouveau sketch (menu "Fichier" -> "Nouveau") nommé par exemple esp32_ledswitchint.
  • Créer une fonction: void ICACHE_RAM_ATTR handleSwitch(), qui doit :
    • lire l'état du switch,
    • si l'état est haut : allumer la LED
    • sinon éteindre la LED
  • *Dans setup(), le sketch doit :
    • initialiser la liaison série avec l'ordinateur, à 115200 bauds,
    • initialiser la "direction" des pins du switch et de la LED,
    • mettre en place la détection d'interruption sur la pin 27, dès que son état change. Dans ce cas, on appelle la fonction handleSwitch().
    • envoyer "OK" à l'ordinateur.
  • La fonction loop(), est laissée vide

 

Tester le sketch en changeant la position du switch : la LED doit s'allumer et s'éteindre en fonction de la position.

 

Exercice 4 : capteur ultrason
 
Remarques préliminaires :
  • Le principe du capteur ultrason est d'envoyer une onde sonore et de capter son retour. C'est pourquoi il y a une pin intitulée TRIGGER qui émet un ultrason, et la pin ECHO qui capte le retour.
  • Le temps passé entre l'aller et le retour permet de mesurer la distance au plus proche obstacle.
  • Ce n'est pas un capteur très précis et parfois les rebond sur les obstacles peuvent conduire le capteur à calculer une distance bien trop grande par rapport à la réalité.
  
Pour utiliser ce capteur, le plus simple est d'installer une bibliothèque qui simplifie l'acquisition. L'installation se fait soit grâce au gestionnaire de bibliothèques, soit manuellement. Pour cet exercice, l'installation sera manuelle :
 

  • Lancez arduino et créez un nouveau sketch (menu Fichier -> Nouveau) nommé par exemple esp32_ultrasonic.
  • Allez dans Fichier -> Préférences. Dans la fenêtre qui s'ouvre, notez le répertoire où sont placés par défaut vos sketch. Par exemple, sous linux, cela devrait être quelque chose du genre /home/login/sketchbook ou bien /home/login/Arduino.
  • Allez dans ce répertoire. Vérifiez qu'il y a un sous-répertoire libraries. S'il n'existe pas, créez-le.
  • Téléchargez la bibliothèque [ ultrasonic.tgz ] et décompactez-là dans libraries. Cela produit un sous-répertoire HCSR04Ultrasonic. avec les sources de la bibliothèques mais également un répertoire avec un exemple.

L'objectif de l'exercice est de s'inspirer de cet exemple pour créer un sketch qui va éteindre/allumer la LED en fonction  du fait que l'on détecte un obstacle à 20cm du capteur, mais en tenant compte de l'état du switch.

 

  • Dans setup(), le sketch doit :
    • initialiser la liaison série avec l'ordinateur, à 115200 bauds,
    • initialiser la "direction" des pins du switch et de la LED,
    • envoyer "OK" à l'ordinateur.
  • Dans loop(), le sketch doit :
    • récupérer l'état du switch,
    • récupérer la distance actuelle au premier obstacle rencontré,
    • si l'état switch = 1 :
      • si distance obstacle <=20cm alors allumer la LED,
      • sinon éteindre la LED
    • si l'état switch = 0 :
      • si distance obstacle > 20cm, alors allumer la LED,
      • sinon éteindre la LED
    • attendre 500ms.

 

Exercice 5 : capteur ultrason + PWM + interruption
 
L'objectif est de faire clignoter la LED plus ou moins vite selon la distance à l'obstacle, en utilisant le mécanisme de PWM, mais uniquement si le switch est à l'état haut. Sinon, la LED est éteinte. De plus, il ne faut pas modifier la fréquence de clignotement  PWM si la distance n'évolue pas de plus de 1cm.
 
Remarques :
  • L'esp32 n'a pas tout à fait la même façon  d'initialiser le PWM que l'esp8266/arduino, car il y a un circuit interne qui permet de gérer 16 canaux, à savoir signaux PWM différents et donc de les attacher à 16 GPIO différentes. Pour utiliser PWM, il faut :
    • initialiser les paramètres du PWM : ledcSetup(num_canal, frequence, nb_bits). num_canal va de 0 à 15. nb_bits permet de régler le nombre de pas possibles pour le duty-cycle, mais en précisant sur combien de bits et pas une valeur entière. Par exemple, on peut mettre 10 pour avoir 2^10 = 1024 pas.
    • attacher une pin à un canal : ledcAttachPin( num_pin, num_canal)
    • lancer le PWM : ledcWrite(num_canal, duty_cycle). duty_cycle va de 0 à la valeur max fixée par nb_bits. Par exemple, si nb_bits vaut 10, alors duty_cycle peut aller de 0 à 1023, sachant qu'avec 512, on obtient un duty cycle de 50%.
  • Il existe d'autres fonctions, notamment pour changer les paramètres : se reporter à la documentation officielle de l'esp32 sur arduino : https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/ledc.html#
 
  • Lancez arduino et créez un nouveau sketch (menu Fichier -> Nouveau) nommé par exemple esp32_ultrasonicpwm.
  • Créer les variables globales :
    • float dist;
    • volatile byte stateSwitch;
  • Créer une fonction : void ICACHE_RAM_ATTR handleSwitch() :
    • lire l'état du switch et le mettre dans stateSwitch.
  • Créer une fonction : void changeBlink() :
    • si stateSwitch == 1 :
      • si dist <= 10cm, régler la fréquence du PWM à 1Hz,
      • si dist >=100cm, régler la fréquence du PWM à 50Hz,
      • sinon régler la fréquence sur une valeur entre 1 et 50Hz, proportionnelle à la distance entre 10cm et 100cm.
      • démarrer le PWM sur le canal choisi (cf.ci-dessous) un duty cycle de 50%
    • sinon, éteindre la LED
  • Dans setup(), le sketch doit :
    • initialiser la liaison série avec l'ordinateur, à 115200 bauds,
    • initialiser la "direction" des pins du switch et de la LED,
    • initialiser le PWM sur la pin 5, avec 10 comme valeur de nb_bits (pas moins, sinon 1Hz ne sera pas possible).Vous pouvez choisir n'importe quel numéro de canal.
    • mettre en place la détection d'interruption sur la pin 27, dès que son état change. Dans ce cas, on appelle la fonction handleSwitch().
    • dist = 0
    • récupérer l'état du switch et en fonction allumer ou éteindre la LED.
    • envoyer "OK" à l'ordinateur.
  • Dans loop(), le sketch doit :
    • récupérer la distance actuelle au premier obstacle rencontré -> new_dist.
    • si écart en new_dist et dist > 1cm :
      • dist = new_dist
      • appeler changeBlink().
    • attendre 100ms.

 

Exercice 6 : afficheur 7-segments
 
L'objectif est d'afficher la distance à l'obstacle avec l'afficheur 4 digits. L'affichage doit changer uniquement quand la distance évolue de plus de 1cm.
 
 Pour utiliser l'afficheur, il est nécessaire d'installer une bibliothèque. Cette fois-ci vous allez passer par le gestionnaire.
 
  • Dans arduino, allez dans Outils -> Gérer les bibliothèques. Dans la fenêtre qui s'ouvre, taper dans le champ de recherche : tm1637.
  • Plusieurs choix sont possibles, offrant des fonctionnalités plus ou moins avancées. Pour le TP, choisissez Groove 4-digit display puis cliquez sur Installer.

Dans le répertoire d'installation de cette bibliothèque (NB : elle est aussi dans le répertoire libraries où vous avez installé celle de l'exercice 4), vous trouverez des exemples, notamment NumberFLow.ino qui peut vous servir d'inspiration pour cet exercice.

ATTENTION : dans cet exemple, les pins CLK et DIO utilisées sont 2 et 3. Il faut bien entendu changer ces valeurs pour utiliser les pins prévues sur la planche (cf. préambule)

 

  • Créez un nouveau sketch (menu Fichier -> Nouveau) nommé par exemple esp32_tm1637.
  • Copier/coller le code de l'exercice 5.
  • Modifier le sketch pour qu'après l'appel à changeBlink(), la nouvelle distance en cm (tronquer les décimales) soit affichée sur les 3 premiers digits de l'afficheur si la distance est >= 100cm, et sur les digits 2 & 3 si la distance est <=99cm.

 

Exercice 7 : hacking de bibliothèque

La bibliothèque de l'afficheur est relativement simple à utiliser mais elle ne permet d'afficher que les chiffres de 0 à 9 et les lettres de A à F. En effet, si on regarde un peu dans le fichier TM1637.cpp, on voit au tout début un tableau nommé TubeTab contenant 16 valeurs et un commentaire indiquant quelle valeurs correspond à quel caractère. De plus, on voit que la fonction display() prend en paramètre un numéro de digit et de façon indirecte, un indice dans TubeTab du caractère à afficher. Par exemple, si on appelle display(4,15), un F apparaîtra sur le 4ème digit. Si on veut afficher d'autres caractères, il faudrait donc ajouter des valeurs à ce tableau TubeTab.

  • Modifiez TubeTab pour ajouter les caractères + (NB : il manque forcément une des barres horizontale de la croix)  et -
  • Modifiez le sketch de l'exercice 6 pour que le 4ème digit de l'afficheur affiche un + si la distance a grandi depuis la dernière mise à jour de l'affichage, ou bien un - si elle a diminuée.

Indice : faîtes une recherche sur wikipedia de "afficheur 7 segments". En lisant jusqu'au bout, vous devriez trouver sans peine comment sont codés les caractères qui s'affichent.

 

Exercice 8 (bonus pour les rapides) : gérer des événements temporaires

L'objectif de cet exercice est de compléter l'exercice 7 pour que :

  • l'afficheur puisse afficher les lettres H, L, un "crochet droit" formé par un L et le segment droite-bas allumé, ainsi que son symétrique par la verticale (c.a.d L inversé et segment gauche-bas allumé)
  • si le switch change d'état, au lieu d'afficher la distance, on affiche pendant deux secondes l'état du switch. Après ces 2 secondes, on revient à l'affichage de la distance.

ATTENTION : pendant les 2 secondes, le script ne doit pas être bloqué et la mesure de la distance, le PWM doivent continuer à se faire.

Les caractères pour afficher l'état sont :

  • haut => H, 1, 9, H
  • bas => L, 0, crochet droit, crochet gauche (l'assemblage des 2 crochets forme une sorte de W)

Indice : cherchez du côté de la fonction millis() pour mesurer le temps qui passe.