[[microc:accueilmc|{{ :iconemaison.jpg?nolink&30|Sommaire Microcontrôleurs}}]]
===== Microcontrôleurs - Entrées, sorties (GPIO) =====
{{ :microc:microcontroleur.png?nolink|}}
[Mise à jour le : 19/2/2025] En cours de rédaction
* **Source**
* Arduino
* Raspberry Pi pico
* esp32Les exemples de code de cette page ont été testés sur une [[microc:uc:uno|Arduino Uno]], une [[microc:uc:mkr|Arduino MKR Wifi 1010]], une [[microc:uc:esp32|ESP32 Feather Huzzah]] et sur une [[microc:uc:rp2|Raspberry Pi Pico]].
==== 1. Généralités ====
* Vidéo : Microcontrôleur : Comment ça marche ? - SILIS Electronique \\
« //D'un point de vue fonctionnel, dans un système à base de **microcontrôleur((Un microcontrôleur est un circuit intégré qui rassemble les éléments essentiels d'un ordinateur : processeur, mémoires, unités périphériques et interfaces d'entrées-sorties.))**, on appelle **entrées-sorties** les échanges d'informations entre le processeur et les périphériques qui lui sont associés. De la sorte, le système peut réagir à des modifications de son environnement, voire le contrôler. Les entrées, sorties sont parfois désignées par l'acronyme **I**/**O**, issu de l'anglais **I**nput/**O**utput ou encore **E**/**S** pour **E**ntrées/**S**orties.// » Wikipédia
{{ :microc:systememicroproc.png?nolink |}}
«// D'un point de vue matériel, un **microcontrôleur** dispose de **broches((Une broche de microcontrôleur est un élément physique situé sur le boîtier du microcontrôleur, qui permet de connecter ce dernier à d'autres composants électroniques, tels que des capteurs, des actionneurs ou d'autres circuits.))** pouvant être contrôlées par un logiciel. Elles peuvent se comporter comme des entrées ou des sorties, d'où le nom "Entrée / Sortie à usage général", ou **GPIO** (**G**eneral **P**urpose **I**nput **O**utput. Le nombre de broches d’un microcontrôleur étant limité, il est fréquent d’avoir **plusieurs fonctionnalités sur une même broche**.// » Wikipédia
=== 1.1 Exemples de microcontrôleurs ===
\\
=== 1.2 Cartes de prototypage ===
\\
==== 2. Entrées, sorties numériques ====
=== 2.1 Généralités ===
Pour éviter de faire référence à des valeurs électriques (tension ou intensité), on définit souvent l’état d’un signal numérique en utilisant la logique booléenne. \\
- **true** (« **1** » logique ou **HIGH**) \\
- **false** (« **0** » logique ou **LOW**) . \\ \\
\\
=== 2.2 Sortie numérique ===
== 2.2.1 Généralités ==
Lorsqu'une broche est configurée en **sortie numérique**, le microcontrôleur délivre des **signaux logiques** “**0**”(LOW) ou “**1**"(HIGH).
Une sortie numériqque est fragile. Ne **JAMAIS** la relier à un générateur \\ Une sortie numérique délivre **très peu de puissance** (quelques centaines de mW). Il n’est donc pas possible de la relier directement à un actionneur (moteur). Il est nécessaire de placer une interface de puissance (hacheur, relais) entre elle et l’actionneur à commander.
{{ :tinyclros:gpio:sortienum.png?nolink |}}
{{ :materiels:capteurs:environnement:code.png?nolink|}}
== 2.2.2 Programmation ==
Les programmes suivants sont codés :
* En langage **C** sur Arduino Uno ou compatible
* En langage **MicroPython** sur Raspberry Pi Pico et ESP32
\\
=== 2.3 Sortie numérique (PWM) ===
== 2.3.1 Généralités ==
La **M**odulation de **L**argeur d'**I**mpulsions (**MLI** ; en anglais **PWM** pour **P**ulse **W**idth **M**odulation), est une technique couramment utilisée pour synthétiser des signaux **pseudo** analogiques à l'aide de circuits numériques ("**1**" ou "**0**"). \\
Le PWM est utilisé par exemple pour contrôler la luminosité d'une LED, changer la couleur d'une LED RGB ou encore piloter la vitesse d'un moteur. \\ \\
Le principe est de créer un signal prenant les valeurs "**1**" ou "**0**", à fréquence fixe mais dont le rapport cyclique est contrôlé numériquement, la **valeur moyenne** de ce signal étant une grandeur analogique, égale au produit du rapport cyclique par l'amplitude maximale du signal. Wikipédia
{{ :microc:signalpwm.png?nolink |}}
{{ :materiels:capteurs:environnement:code.png?nolink|}}
== 2.3.2 Programmation ==
Les programmes suivant sont codés :
* En langage **C** sur Arduino Uno ou compatible
* En langage **MicroPython** sur Raspberry Pi Pico et ESP32
\\
=== 2.4 Entrée numérique ===
== 2.4.1 Généralités ==
Lorsqu'une broche est configurée en **entrée numérique**, le microcontrôleur est capable de traiter des signaux prenant la valeur logique "**0**" ou "**1**".
Les microcontrôleurs disposent de **résistances de rappel** internes pouvant être connectées par le logiciel. \\ Une entrée numérique utilisée dans un programme **ne doit pas être laissée "en l’air"** (non connectée) car elle prendra alors un état logique aléatoirement et le comportement du programme deviendra imprévisible.
__Exemple__ : détermination de l'état ouvert ou fermé d'un bouton-poussoir.
{{ :tinyclros:gpio:resistancerappel.jpg?nolink&600 |}}
Les entrées numériques sont **fragiles**. Elles ne supportent ni les **décharges électrostatiques** ni les **surtensions**. Il ne faut ni les toucher ni leur appliquer une tension supérieure à 5V ou inférieure à 0V.
{{ :materiels:capteurs:environnement:code.png?nolink|}}
== 2.4.2 Programmation ==
Les programmes suivant sont codés :
* En langage **C** sur Arduino Uno ou compatible
* En langage **MicroPython** sur Raspberry Pi Pico et ESP32
\\
{{ :python:micropython:deroulement_interruption.gif?nolink&280|}}
=== 2.5 Entrée d'interruption ===
== 2.5.1 Généralités ==
Une **interruption** est un **arrêt temporaire** de l'exécution normale d'un programme par le processeur afin d'exécuter un autre programme (appelé **service d'interruption**). \\
L’interruption est provoquée par une cause externe (action sur un bouton-poussoir, mesure réalisée par un capteur, horloge temps réel, etc.). \\
On utilise les interruptions afin de permettre des **communications non bloquantes** avec des périphériques externes. \\
Une interruption tient compte de l’état logique présent sur une broche. Couramment, on la déclenchera sur **le front montant, le front descendant, ou chacun des fronts** d’un signal logique.
Une interruption sera reconnue si le signal présente des fronts "propres". Il faudra donc s’assurer de la qualité du signal.
Les figures ci-dessous représentent un signal transmis à la fermeture du contact d’un anémomètre. Le signal de gauche n’est pas utilisable à cause du rebondissement du contact. En effet, il contient quatre fronts montants au lieu d’un seul comme dans le cas du signal de droite.
{{ :tinyclros:gpio:antirebong.png?nolink |}}
{{ :materiels:capteurs:environnement:code.png?nolink|}}
== 2.5.2 Programmation ==
Les programmes suivant sont codés :
* En langage **C** sur Arduino Uno ou compatible
* En langage **MicroPython** sur Raspberry Pi Pico et ESP32
* [[#tab-uno_4|Arduino Uno]]
* [[#tab-pico_4|RPi Pico]]
* [[#tab-esp32_4|ESP32]]
* **Ressource** :
//a. Présentation// \\
//b. Configuration d'une broche en entrée d'interruption// \\
//c. Evènement et gestionnaire d'interruption// \\
//d. Synthèse: ?//
* **Ressource** :
//a. Présentation// \\
//b. Configuration d'une broche en entrée d'interruption// \\
//c. Evènement et gestionnaire d'interruption// \\
//d. Synthèse: ?//
{{ :python:micropython:pmod_btn_25707.png?nolink&90|Digilent Pmod BTN: 4 User Pushbuttons}}
* **Ressource** : Quick reference for ESP32, GPIO Pins, External interrupts sur Micropython.org.
//a. Présentation// \\
* Ressource provisoireMicroPython: Interrupts with ESP32 and ESP8266
//b. Configuration d'une broche en entrée d'interruption// \\
//c. Evènement et gestionnaire d'interruption// \\
//d. Synthèse: HORLOGE NUMERIQUE// \\
* **Matériel** : [[microc:uc:esp32|ESP32 Feather Huzzah]], Digilent Pmod BTN: 4 User Pushbuttons[Schéma]
{{ :python:micropython:youtube.png?nolink&50|}}
* **Description** : l'extrait du programme HORLOGE ci-dessous illustre l'utilisation d'interruptions assurant le réglage de l'heure à l'aide de trois boutons-poussoir. Une vidéo de présentation est accessible ici.
# -----------------------------------------------
# Code partiel du programme HORLOGE
# -----------------------------------------------
# Réglage de l'heure à la mise sous tension
time_offset=12*3600+0*60+0 # hh+mm+ss
# Routines de service d'interruption (ISR)
def handle_interrupt_min(pin):
global time_offset
time_offset+=60
time.sleep(.2)
def handle_interrupt_hr(pin):
global time_offset
time_offset+=3600
time.sleep(.2)
# Réglage des minutes
# Ajout de 60s à l'heure initiale
button_min = Pin(25, Pin.IN)
# Gestionnaire d'interruption
button_min.irq(trigger=Pin.IRQ_RISING,handler=handle_interrupt_min)
# Réglage des heures
# Ajout de 3600s à l'heure initiale
button_hr = Pin(26, Pin.IN)
# Gestionnaire d'interruption
button_hr.irq(trigger=Pin.IRQ_RISING,handler=handle_interrupt_hr)
{{ :python:micropython:materiel:thonny.png?nolink&70|}}
Le projet MICROPYTHON_ESP32_HORLOGE pour l'IDE Thonny.
\\
==== 3. Entrées analogiques ====
* **Ressource** : site Arduino
=== 3.1 Généralités ===
{{ :materiels:capteurs:environnement:code.png?nolink|}}
=== 3.2 Programmation ===
* [[#tab-uno_5|Arduino Uno]]
* [[#tab-pico_5|RPi Pico]]
* [[#tab-esp32_5|ESP32]]
//a. Présentation// \\
//b. Configuration d'une broche en entrée analogique// \\
//c. Lecture d'une entrée analogique// \\
//d. Synthèse: ?//
//a. Présentation// \\
//b. Configuration d'une broche en entrée analogique// \\
//c. Lecture d'une entrée analogique// \\
{{ :materiels:capteurs:potentiometre.png?nolink&80|Potentiomètre}}
//d. Synthèse: ?//
* **Ressource**
* ADC (analog to digital conversion) | class Pin – control I/O pins sur Micropython.org.
//Exemple de code pour un **Raspberry Pi Pico**//
# -------------------------------------------------------------------------------
# Lecture et affichage dans la console de la tension issue d'un potentiomètre
# Date : 22/5/2023
# Matériels : Raspberry Pi Pico, Shield Grove, pot. 10k
# ADC accessibles sur le shield Grove pour RP2 :
# Connecteur: ADC : GPIO
# A0 : ADC0 : 26
# A1 : ADC0,ADC1: 26,27
# A2 : ADC1,ADC2: 27,28
# IDE : Thonny
# -------------------------------------------------------------------------------
from machine import ADC, Pin
import time
# Le potentiomètre 10kOhm est connecté à l'entrée analogique A0 du shield.
# Attention : La tension doit être comprise entre 0 - 3,3V (3,6V max !)
# sur une entrée analogique.
# Configuration
pot = ADC(Pin(26))
while (True):
val=pot.read_u16() # lecture de l'ADC
U = val*3.3/65535 # Calcul de la tension
print("%.2f" % U) # Affichage dans la console (formaté à 2 décimales)
time.sleep(1)
//a. Présentation// \\
Ressource provisoire : ESP32/ESP8266 Analog Readings with MicroPython \\
//b. Configuration d'une broche en entrée analogique// \\
//c. Lecture d'une entrée analogique// \\
{{ :materiels:capteurs:potentiometre.png?nolink&80|Potentiomètre}}
//d. Synthèse: ?//
* **Ressource**
* ADC (analog to digital conversion) sur Micropython.org.
//Exemple de code pour un **ESP32 Feather Huzzah**//
# ADC accessibles en Python sur la carte ESP32 Feather Huzzah :
# ADC:GPIO
# A2 : 34
# A3 : 39
# A4 : 36
# A7 : 32
# A9 : 33
from machine import ADC, Pin
# Le potentiomètre 10kOhm est connecté à l'entrée analogique A2 de l'ESP32.
# Configuration
adc = ADC(Pin(34))
# Sur une entrée analogique, la tension doit
# être comprise entre 0 - 3,3V (3,6V max !)
adc.atten(ADC.ATTN_11DB) # voir doc
# Mesure
value = adc.read()
print(value) # affichage dans la console
\\
==== pour aller plus loin ====
**SISEL SA** - Entrées-sorties d’un microcontrôleur