{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "| |\n", "| ------------------------------------------------------- | \n", "| ![Tremplin des sciences](images/tremplinColorSmall.png) | \n", "\n", "Cahier d'exercices pour l'enseignement et l'apprentissage de programmation issu de la collection \"Climat et météo tremplin pour l'enseignement des sciences\" (PIA IFÉ ENS de Lyon - Météofrance ENM Toulouse). Le dispositif clef en main repose sur l'utilisation d'une RaspberryPi chargée avec le système d'exploitation Debian enrichi, fourni par le projet. Les sources et les exécutables sont accessibles dans [l'espace collaboratif de la forge github](https://github.com/g-vidal/CahierDeProgrammes); plus d'information sur les [blogs d'accompagnement](http://blog.climatetmeteo.fr/GerardVidal/) systèmes d'exploitation sur [la page des OS de Raspberries Pi](http://mediaserv.climatetmeteo.fr/images/RaspBerry/DebianStretchPi3/). Toutes les ressources issues du projet sont fournies sous licence [Creative Commons](https://creativecommons.org/licenses/by-nc/4.0/) ou sous les licences libres d'origine des outils utilisés. Les ressources du projet peuvent être utilisées dans tout autre environnement compatible.![licence : Creative Commons](images/Licence.jpg) \n", "\n", "Auteurs : G. Vidal, C-H. Eyraud, E. le Jan\n", "\n", "------------------------------------------------------------" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Premiers pas avec les diodes electro-luminescentes (DEL ou LED)\n", "\n", "Une diode électroluminescente est un composé électronique qui émet de la lumière lorsqu'il est parcouru par un courant électrique. L'une des particularités de ce composant est qu'il ne peut être parcouru que *dans un seul sens* si l'on permute le sens du courant il est bloqué (aucune intensité ne parcourt le composant) et la diode (LED) reste éteinte. Nous verrons comment exploiter cette particularité en contrôlant par un programme l'alimentation de LEDs. \n", "Nous allons utiliser des montages regroupées sur une plaque d'expérimentation, il s'agit d'une base de proposition qui peut-être copiée et modifiée et chaque expérience peut-être isolée de ses voisines. La plaque est représentée ci- dessous:\n", "\n", "![plaque de lumière](images/feutricolore.jpg)\n", " ![licence : Gérard Vidal](images/Licence.jpg)\n", "\n", "Nous allons utiliser un certain nombre de programmes écrits par des développeurs pour nous permettre d'interagir avec les broches d'une Raspberry Pi, ces programmes sont regroupés dans des librairies stockées sur le disque de la machine et prêtes à l'emploi, il suffit de solliciter leur utilisation pour accéder aux programmes qu'elles contiennent. On utilise pour cela l'instruction **import** *nom_de_la_bibliothèque* **as** *nom_que_nous_utiliserons_dans_le_programme*. Ces commandes doivent systématiquement figurer en tête de chaque programme que nous allons écrire." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Contrôler l'allumage et l'extinction d'une LED par un programme\n", "\n", "Nous allons utiliser le montage encadré ci-dessous et connecter deux broches de la Raspberry Pi. L'identification des broche est une question de type *\"troll\"* dans la mesure où il y a plusieurs façons d'identifier ces broches dont toutes ont des avantages et des inconvénients. Nous utiliserons ici le **numéro de la broche** en commençant en haut à gauche (les connecteurs USB et RJ45 étant considérés en bas) en descendant et en augmentant de droite à gauche.\n", "\n", "![montage LED-1](images/ledverte.png)\n", " ![licence : Gérard Vidal](images/Licence.jpg)\n", " \n", "Connecter le fil vert à la broche 35 et le fil noir à la broche 6 (GROUND). Pour allumer la LED:\n", "* on importe les programmes de la bibliothèque mraa\n", "* on déclare l'utilisation de la broche 35 (GPIO 19)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import mraa\n", "led = mraa.Gpio(35)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les broches peuvent fonctionner dans le sens *in* pour **recevoir** des données ou dans le sens *out* pour envoyer un signal ou un courant.\n", "* on utilise la broche en mode sortie *out*\n", "* l'état de la broche est fourni (0 correct, 7 erreur) et est recueilli dans la variable status. Pour imprimer l'état décommenter la seconde ligne de ce bloc." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "status = led.dir(mraa.DIR_OUT)\n", "#print ('Return status : {0:1d}'.format(status))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "###### On allume ou on ré-allume la LED en mettant la sortie au niveau 1 avec la commande *write*\n", "* l'état de la broche est fourni (0 correct, 7 erreur) et est recueilli dans la variable status. Pour imprimer l'état décommenter la seconde ligne de ce bloc." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "status = led.write(1)\n", "#print ('Return status : {0:1d}'.format(status))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On éteint ou on ré-éteint la LED en mettant la sortie au niveau 0 avec la commande *write*\n", "* l'état de la broche est fourni (0 correct, 7 erreur) et recueilli dans la variable status. Pour imprimer l'état décommenter la seconde ligne de ce bloc." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "led.write(0)\n", "#print ('Return status : {0:1d}'.format(status))" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "Il est possible de contrôler la durée d'allumage ou d'extinction de la LED ce qui conduit à la logique de clignotement. Pour y parvenir il est nécessaire de disposer de fonctions temporelles fournies par la bibliothèque *time*. On importe time ensuite on choisit la durée d'allumage et d'extinction en secondes:\n", "* allumage 2 s\n", "* extinctioncttion 3 s\n", "* allumage 1 s\n", "* extinctioncttion 1 s\n", "* 4 clignotements de 0.5 s\n", "* 4 clignotements de 0.25 s" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import time\n", "led.write(1)\n", "time.sleep(2)\n", "led.write(0)\n", "time.sleep(3)\n", "led.write(1)\n", "time.sleep(1)\n", "led.write(0)\n", "time.sleep(1)\n", "led.write(1)\n", "time.sleep(0.5)\n", "led.write(0)\n", "time.sleep(0.5)\n", "led.write(1)\n", "time.sleep(0.5)\n", "led.write(0)\n", "time.sleep(0.5)\n", "led.write(1)\n", "time.sleep(0.5)\n", "led.write(0)\n", "time.sleep(0.5)\n", "led.write(1)\n", "time.sleep(0.5)\n", "led.write(0)\n", "time.sleep(0.5)\n", "led.write(1)\n", "time.sleep(0.25)\n", "led.write(0)\n", "time.sleep(0.25)\n", "led.write(1)\n", "time.sleep(0.25)\n", "led.write(0)\n", "time.sleep(0.25)\n", "led.write(1)\n", "time.sleep(0.25)\n", "led.write(0)\n", "time.sleep(0.25)\n", "led.write(1)\n", "time.sleep(0.25)\n", "led.write(0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Faire clignoter la Led en utilisant une instruction de répétition : la boucle\n", "\n", "Comme on l'a vu ci dessus il suffit d'imposer le temps d'allumage et d'extinction pour un obtenir un clignotement, cependant c'est très fastidieux de répéter plusieurs fois la même séquence d'instructions. La programmation fournit un outil qui décrit une répétition de commandes et permet en quelques lignes de répéter un grand nombre d'instructions identiques. Le programme ci-dessous utilise la *variable* **i** qui prend la valeur 0 pour commencer : *la valeur initiale* et se termine à 20 *la valeur finale* en augmentant chaque fois d'une unité : *le pas*. Le clignotement se compose d'une phase d'allumage pendant 0.15 s et une phase d'extinction de 0.25 s." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for i in range(0,20,1) :\n", " led.write(1)\n", " time.sleep(0.15)\n", " led.write(0)\n", " time.sleep(0.25)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercice\n", "\n", "Modifier *la valeur initiale*, *la valeur finale* et *le pas* pour modifier le clignotement." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for i in range(-,-,-) :\n", " led.write(1)\n", " time.sleep(-.-)\n", " led.write(0)\n", " time.sleep(-.-)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut modifier la commande qui est répétée en ajoutant des tests qui permettent de fixer le moment ou le type de clignotement change. Ici on change tous les 10 clignotements." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "for i in range(0,30,1) :\n", " if (i < 10) :\n", " led.write(1)\n", " time.sleep(0.15)\n", " led.write(0)\n", " time.sleep(0.25)\n", " elif (i >= 10 & i < 20) :\n", " led.write(1)\n", " time.sleep(0.2)\n", " led.write(0)\n", " time.sleep(0.2)\n", " else :\n", " led.write(1)\n", " time.sleep(0.05)\n", " led.write(0)\n", " time.sleep(0.05)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercice\n", "\n", "Décrivez un mode de clignotement composé de plusieurs phases sur le modèle ci-dessus et écrivez le programme correspondant dans le bloc ci-dessous." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for i in range(-,-,-) :\n", " if (- < -) :\n", " led.write(1)\n", " time.sleep(-.-)\n", " led.write(0)\n", " time.sleep(-.-)\n", " elif ():\n", " \n", " else :\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Généralisation à plusieurs LEDs : le feu tricolore.\n", "\n", "Tout ce qui a été présenté ci dessus peut se généraliser à plusieurs LED. Pour cela on conserve une seule masse **commune aux 3 LEDs utilisées** dans cette partie et on branche une broche sur chacune des 3 LEDs, ce qui a été vu pour la LED jaune de la partie précédente est appliqué simultanément aux 3 broches connectées aux LEDS Rouge Jaune et Verte.\n", "\n", "![montage LED-2](images/feutricolore.jpg) : ![Gérard Vidal](images/Licence.jpg)\n", " \n", "Dans l'exemple présenté ici on branche :\n", "* la masse (fil noir) sur la broche 6 (GROUND)\n", "* la diode rouge sur la broche 11 (ledr pour led red) GPIO 17\n", "* la diode verte sur la broche 35 (ledg pour led green) GPIO 19\n", "* la diode jaune sur la broche 31 (ledy pour led yellow) GPIO 6" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import mraa, time" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# déclaration des broches utilisées\n", "ledr = mraa.Gpio(11)\n", "ledg = mraa.Gpio(35)\n", "ledy = mraa.Gpio(31)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# sens d'utilisation des broches choisies\n", "ledr.dir(mraa.DIR_OUT)\n", "ledg.dir(mraa.DIR_OUT)\n", "ledy.dir(mraa.DIR_OUT)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Allumage pendant une seconde successivement des 3 LEDs, puis allumage des 3 LEDs ensemble pendant 5 secondes" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Allumage pendant une seconde successivement des 3 LEDs Rouge Jaune Vert\n", "ledr.write(1)\n", "time.sleep(1)\n", "ledr.write(0)\n", "ledy.write(1)\n", "time.sleep(1)\n", "ledy.write(0)\n", "ledg.write(1)\n", "time.sleep(1)\n", "ledg.write(0)\n", "time.sleep(1)\n", "# Allumage simultanné des 3 LEDs\n", "ledr.write(1)\n", "ledg.write(1)\n", "ledy.write(1)\n", "time.sleep(5)\n", "ledr.write(0)\n", "ledg.write(0)\n", "ledy.write(0)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### Exercice\n", "pendant 60 secondes faire clignoter la LED rouge Eclairée 1 s Eteinte 1 s, la LED verte Eclairée 0.5 s Eteinte 0.5 s, la LED jaune Eclairée 0.2 Eteinte 0.2\n", "### Solution :" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for i in range(0,300,1) :\n", " j = 2 \n", " k = 5 \n", " l = 10\n", " if (i % k == 0):\n", " if ((i / k) % 2 == 0):\n", " ledg.write(1)\n", " else :\n", " ledg.write(0)\n", " if (i % l == 0):\n", " if ((i / l) % 2 == 0):\n", " ledr.write(1)\n", " else :\n", " ledr.write(0)\n", " if (i % j == 0):\n", " ledy.write(1)\n", " time.sleep(0.1)\n", " else :\n", " ledy.write(0)\n", " time.sleep(0.1) \n", " time.sleep(0.1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut aussi envisager ici des applications comme les montres binaires ou en base 5 (existent toutes deux dans le commerce)" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.7" } }, "nbformat": 4, "nbformat_minor": 2 }