{"id":4878,"date":"2017-04-10T08:00:51","date_gmt":"2017-04-10T07:00:51","guid":{"rendered":"https:\/\/www.blaess.fr\/christophe\/?p=4878"},"modified":"2017-04-26T05:05:03","modified_gmt":"2017-04-26T04:05:03","slug":"msp-omodoro","status":"publish","type":"post","link":"https:\/\/www.blaess.fr\/christophe\/2017\/04\/10\/msp-omodoro\/","title":{"rendered":"MSP-omodoro"},"content":{"rendered":"<p><a href=\"https:\/\/www.blaess.fr\/christophe\/2017\/04\/06\/msp-omodoro\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright wp-image-4907 size-full\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/MSP-omodoro-1.png\" alt=\"MSP-omodoro\" width=\"250\" height=\"200\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Le modeste programme pr\u00e9sent\u00e9 dans cet article est extrait d&rsquo;un exercice de travaux pratiques que je propose aux participants de la formation \u00ab\u00a0<a href=\"https:\/\/www.logilin.fr\/formations\/formation-langage-c-embarque-sur-micro-controleurs\/\" target=\"_blank\" rel=\"noopener noreferrer\">Programmation en C sur microcontr\u00f4leurs<\/a>\u00a0\u00bb que j&rsquo;anime r\u00e9guli\u00e8rement. Cet exercice permet de r\u00e9fl\u00e9chir en profondeur sur le d\u00e9veloppement d&rsquo;un petit projet sur microcontr\u00f4leur.<\/p>\n<p style=\"text-align: justify;\">Comme l&rsquo;objet m\u00eame de la r\u00e9alisation peut \u00eatre utile au quotidien (je l&#8217;emploie personnellement), j&rsquo;ai trouv\u00e9 int\u00e9ressant de le partager ici.<\/p>\n<p>\n<!--more-->\n<\/p>\n<p style=\"text-align: justify;\">Le projet <a href=\"https:\/\/github.com\/cpb-\/MSP-omodoro\" target=\"_blank\" rel=\"noopener noreferrer\">MSP-omodoro<\/a> est un <em>timer<\/em> con\u00e7u pour rythmer l&rsquo;activit\u00e9 d&rsquo;un d\u00e9veloppeur. Comme expliqu\u00e9 dans <a href=\"https:\/\/fr.wikipedia.org\/wiki\/Technique_Pomodoro\" target=\"_blank\" rel=\"noopener noreferrer\">cet article de Wikip\u00e9dia<\/a>, la m\u00e9thode de travail par Pomodoro consiste \u00e0 encha\u00eener des p\u00e9riodes de 25 minutes de concentration s\u00e9par\u00e9es par des pauses de 5 minutes. Toutes les 2 heures, on allonge la pause \u00e0 15 minutes.<\/p>\n<p style=\"text-align: justify;\">Cela permet de conserver une bonne efficacit\u00e9 de travail, en \u00e9vitant les p\u00e9riodes trop longues au cours desquelles on s&rsquo;\u00e9puise intellectuellement avec une productivit\u00e9 diminu\u00e9e. Chacun est libre d&rsquo;ajuster la dur\u00e9e des p\u00e9riodes de travail et de pause \u00e0 sa guise\u00a0; personnellement les dur\u00e9es originales me conviennent bien.<\/p>\n<p style=\"text-align: justify;\">Pour rester concentr\u00e9 sur le projet en cours, la pause de 5 minutes ne doit pas \u00eatre l&rsquo;occasion d&rsquo;entamer un nouveau sujet de r\u00e9flexion. C&rsquo;est un moment pour se lever, s&rsquo;\u00e9tirer, faire quelques pas, ranger un peu son bureau, etc. La pause de 15 minutes, en revanche doit permettre d&rsquo;\u00e9vacuer la tension accumul\u00e9e pendant les phases de concentration. On peut boire un caf\u00e9, discuter avec des coll\u00e8gues, consulter Twitter, etc.<\/p>\n<p style=\"text-align: justify;\">Il existe de nombreuses applications d&rsquo;organisation en Pomodoro, tant sur smartphone que sur poste de travail et m\u00eame en ligne. L&rsquo;id\u00e9e de ce projet \u00e9tait de montrer aux participants de mes sessions de formation comment impl\u00e9menter un outil de ce type en utilisant un simple microcontr\u00f4leur.<\/p>\n<h1>Architecture mat\u00e9rielle<\/h1>\n<h2>Microcontr\u00f4leur<\/h2>\n<p style=\"text-align: justify;\">J&rsquo;ai choisi d&rsquo;utiliser un classique <a href=\"http:\/\/www.ti.com\/tool\/msp-exp430g2\" target=\"_blank\" rel=\"noopener noreferrer\">Launchpad MSP-430<\/a> de Texas Instruments, bon march\u00e9, robuste et simple \u00e0 utiliser. Les outils de programmation sont directement disponibles dans les d\u00e9p\u00f4ts Debian\/Ubuntu.<\/p>\n<div id=\"attachment_4894\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/launchpad-msp-430.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4894\" class=\"size-medium wp-image-4894\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/launchpad-msp-430-300x243.png\" alt=\"Launchpad MSP 430\" width=\"300\" height=\"243\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/launchpad-msp-430-300x243.png 300w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/launchpad-msp-430.png 600w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-4894\" class=\"wp-caption-text\">Launchpad MSP 430<\/p><\/div>\n<p style=\"text-align: justify;\">Ce kit contient d\u00e9j\u00e0 deux leds programmables (une rouge et une verte), un bouton-poussoir pour le <em>reset<\/em> du microcontr\u00f4leur et un bouton-poussoir accessible par GPIO. La led verte que l&rsquo;on voit sur la photo est simplement l&rsquo;indicateur d&rsquo;alimentation, il y en a une seconde \u00e0 c\u00f4t\u00e9 de la led rouge, c&rsquo;est celle qui nous int\u00e9ressera ici. Deux leds, un bouton, c&rsquo;est parfaitement adapt\u00e9 pour notre application.<\/p>\n<p style=\"text-align: justify;\">Notons qu&rsquo;une fois le programme flash\u00e9 dans la m\u00e9moire du microcontr\u00f4leur MSP430G253, ce dernier peut-\u00eatre extrait et mont\u00e9 sur une carte ind\u00e9pendante comme j&rsquo;en parlerai plus bas.<\/p>\n<h2>Outils de programmation<\/h2>\n<p style=\"text-align: justify;\">Pour programmer un MSP 430 de la mani\u00e8re la plus simple possible, il suffit d&rsquo;utiliser le compilateur <code>msp430-gcc<\/code> fourni librement sur la plupart des distributions Linux et d&#8217;employer l&rsquo;outil <code>mspdebug<\/code> pour flasher le code sur le microcontr\u00f4leur.<\/p>\n<p style=\"text-align: justify;\">Chacun peut utiliser l&rsquo;\u00e9diteur de texte de son choix pour \u00e9crire son code (<code>nano<\/code>, <code>vim<\/code>, <code>gedit<\/code>, <code>geany<\/code>, etc.). La pr\u00e9sence d&rsquo;un fichier <code>Makefile<\/code> nous permettra de lancer la compilation et le flashage directement depuis la ligne de commande.<\/p>\n<p style=\"text-align: justify;\">Pour ceux qui pr\u00e9f\u00e8rent travailler dans un IDE (<em>Integrated Development Environment<\/em>), sachez qu&rsquo;il existe des <em>plugins<\/em> pour Eclipse (voir <a href=\"http:\/\/eclipse.xpg.dk\" target=\"_blank\" rel=\"noopener noreferrer\">http:\/\/eclipse.xpg.dk<\/a>) pour compiler et t\u00e9l\u00e9charger le code dans le microcontr\u00f4leur depuis le <em>workbench<\/em> Eclipse.<\/p>\n<p style=\"text-align: justify;\">Enfin, il est toujours possible d&rsquo;utiliser <code>msp-gcc<\/code> sur Windows avec l&rsquo;environnement Mingw, mais je ne l&rsquo;ai pas test\u00e9 (je n&rsquo;ai pas de machines Windows dans mon bureau).<\/p>\n<p style=\"text-align: justify;\">Installation sous Ubuntu\u00a0:<\/p>\n<pre>$ <strong>sudo apt install gcc-msp430 mspdebug<\/strong><\/pre>\n<h1>Logiciel<\/h1>\n<h2>Fonctionnement<\/h2>\n<p style=\"text-align: justify;\">La premi\u00e8re partie du projet consiste \u00e0 d\u00e9crire le fonctionnement attendu. Voici quelques id\u00e9es de description\u00a0:<\/p>\n<ol>\n<li style=\"text-align: justify;\">Notre projet n&rsquo;utilisera que les <strong>deux leds<\/strong> (rouge et verte) et <strong>un bouton-poussoir<\/strong>.<\/li>\n<li style=\"text-align: justify;\">Pendant les phases de <strong>travail<\/strong>, la <strong>led rouge<\/strong> sera allum\u00e9e, pendant les <strong>pauses<\/strong> c&rsquo;est la <strong>led verte<\/strong> qui sera active.<\/li>\n<li style=\"text-align: justify;\">Le syst\u00e8me doit pr\u00e9venir l&rsquo;utilisateur de la proximit\u00e9 d&rsquo;une pause et d&rsquo;une reprise environ <strong>deux minutes<\/strong> auparavant.<\/li>\n<li style=\"text-align: justify;\">Lorsque le moment de pause ou de travail arrive, une led clignote pour avertir l&rsquo;utilisateur qui doit <strong>acquitter<\/strong> en pressant le bouton.<\/li>\n<li style=\"text-align: justify;\">Si l&rsquo;utilisateur ne presse pas le bouton pour acquitter la pause ou la reprise, le syst\u00e8me doit <strong>s&rsquo;\u00e9teindre automatiquement<\/strong> au bout d&rsquo;un moment.<\/li>\n<li style=\"text-align: justify;\">L&rsquo;utilisateur peut choisir de faire une <strong>longue pause<\/strong> en pressant deux fois le bouton.<\/li>\n<li style=\"text-align: justify;\">Vu la simplicit\u00e9 du syst\u00e8me, <strong>les dur\u00e9es seront fix\u00e9es<\/strong> \u00e0 la compilation du code et non pas modifiables par l&rsquo;utilisateur.<\/li>\n<li style=\"text-align: justify;\">Le syst\u00e8me final est pr\u00e9vu pour \u00eatre aliment\u00e9 par piles et doit limiter sa <strong>consommation \u00e9lectrique<\/strong>.<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">Naturellement, pour un projet plus ambitieux il faudrait r\u00e9diger un cahier des charges complet avec une description et des sp\u00e9cifications beaucoup plus d\u00e9taill\u00e9es.<\/p>\n<h2>Automate \u00e0 nombre fini d&rsquo;\u00e9tats<\/h2>\n<p style=\"text-align: justify;\">La programmation d&rsquo;un syst\u00e8me pour microcontr\u00f4leur s&rsquo;appuie souvent sur le concept d&rsquo;<a href=\"https:\/\/fr.wikipedia.org\/wiki\/Automate_fini\" target=\"_blank\" rel=\"noopener noreferrer\">automate \u00e0 nombre fini d&rsquo;\u00e9tats<\/a>, souvent abr\u00e9g\u00e9 FSM pour <em>Finite State Machine<\/em>. Ceci peut en effet s&rsquo;organiser sous forme d&rsquo;un graphe que l&rsquo;on peut transposer assez facilement en code s\u00e9quenc\u00e9 par une grande boucle \u00e9v\u00e9nementielle typique de la programmation sur microcontr\u00f4leur.<\/p>\n<p style=\"text-align: justify;\">Nous devons tout d&rsquo;abord commencer par lister les \u00e9tats possibles pour le syst\u00e8me\u00a0:<\/p>\n<ul>\n<li style=\"text-align: justify;\"><strong>Off<\/strong>\u00a0: le microcontr\u00f4leur est \u00e9teint ou en <strong>sommeil tr\u00e8s profond<\/strong> (CPU et horloges d\u00e9sactiv\u00e9s). La consommation est tr\u00e8s r\u00e9duite. On sort de ce mode en pressant <em>Reset<\/em>. On y entre apr\u00e8s quelques minutes sans r\u00e9ponse de l&rsquo;utilisateur lors d&rsquo;une attente d&rsquo;acquittement.<\/li>\n<li style=\"text-align: justify;\"><strong>Time to work<\/strong>\u00a0: la <strong>led rouge clignote<\/strong> avec insistance et attend que l&rsquo;utilisateur presse le bouton pour d\u00e9marrer une s\u00e9quence de travail.<\/li>\n<li style=\"text-align: justify;\"><strong>Work<\/strong>\u00a0: la <strong>led rouge est allum\u00e9e<\/strong> en permanence pendant une dur\u00e9e pr\u00e9d\u00e9termin\u00e9e (par exemple 23 minutes).<\/li>\n<li style=\"text-align: justify;\"><strong>Prepare to take a pause<\/strong>\u00a0: pendant les deux derni\u00e8res minutes de travail, la <strong>led rouge s&rsquo;\u00e9teint r\u00e9guli\u00e8rement<\/strong> pour pr\u00e9venir de l&rsquo;approche de la pause. Le programmeur sait qu&rsquo;il ne doit pas entamer de nouvelle t\u00e2che.<\/li>\n<li style=\"text-align: justify;\"><strong>Time to take a break<\/strong>\u00a0: la <strong>led verte clignote<\/strong> avec insistance en attente d&rsquo;un acquittement par le bouton.<\/li>\n<li style=\"text-align: justify;\"><strong>Short break<\/strong>\u00a0: la <strong>led verte est allum\u00e9e<\/strong> pendant trois minutes. En cas de seconde pression sur le bouton on passe \u00e0 l&rsquo;\u00e9tat suivant.<\/li>\n<li style=\"text-align: justify;\"><strong>Long break<\/strong>\u00a0: la led verte verte est allum\u00e9e pendant 13 minutes.<\/li>\n<li style=\"text-align: justify;\"><strong>Prepare to return to work<\/strong>\u00a0: pendant les deux derni\u00e8res minutes de pause, la <strong>led verte s&rsquo;\u00e9teint r\u00e9guli\u00e8rement<\/strong> pour pr\u00e9venir de la prochaine p\u00e9riode de travail.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\">Une fois les \u00e9tats d\u00e9termin\u00e9s, on recherche les transitions, et on les repr\u00e9sente sur un graphe comme celui-ci\u00a0:<\/p>\n<div id=\"attachment_4896\" style=\"width: 510px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/MSP-omodoro-diagram.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4896\" class=\"wp-image-4896\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/MSP-omodoro-diagram.png\" alt=\"Diagramme des transitions\" width=\"500\" height=\"268\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/MSP-omodoro-diagram.png 600w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/MSP-omodoro-diagram-300x161.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/a><p id=\"caption-attachment-4896\" class=\"wp-caption-text\">Diagramme des transitions<\/p><\/div>\n<h2>Impl\u00e9mentation<\/h2>\n<p style=\"text-align: justify;\">L&rsquo;impl\u00e9mentation traditionnelle d&rsquo;un automate \u00e0 nombre fini d&rsquo;\u00e9tats sur un microcontr\u00f4leur consiste \u00e0 boucler ind\u00e9finiment en attendant de d\u00e9tecter l&rsquo;occurrence d&rsquo;un \u00e9v\u00e9nement d\u00e9clenchant une transition \u00e0 partir de l&rsquo;\u00e9tat en cours. Toutefois la r\u00e8gle 8 des descriptions ci-dessus nous emp\u00eache d&rsquo;utiliser une boucle active infinie. Nous devons essayer d&rsquo;endormir le CPU le plus souvent possible pour limiter sa consommation d&rsquo;\u00e9nergie.<\/p>\n<p style=\"text-align: justify;\">Nous allons donc utiliser un m\u00e9canisme d&rsquo;interruptions qui r\u00e9veilleront ponctuellement le CPU et tout le travail r\u00e9el sera ex\u00e9cut\u00e9 dans les routines de gestion de ces interruptions (<em>handlers<\/em>). Nous avons deux types de transitions\u00a0: celles li\u00e9es au temps et celles li\u00e9es \u00e0 la pression sur le bouton. Nous nous reposerons donc tout naturellement sur les interruptions d&rsquo;un <em>timer<\/em> mat\u00e9riel int\u00e9gr\u00e9 dans le MSP 430 et celles du bouton-poussoir.<\/p>\n<p style=\"text-align: justify;\">Il y a plusieurs designs possibles. Celui que j&rsquo;ai choisi ici consiste \u00e0 utiliser l&rsquo;interruption <em>timer<\/em> pour faire le travail central. \u00c0 chaque <em>tick<\/em>, nous v\u00e9rifierons si le temps \u00e9coul\u00e9 correspond \u00e0 la limite pour l&rsquo;\u00e9tat en cours ou si le bouton a \u00e9t\u00e9 press\u00e9. Le <em>timer<\/em> est configur\u00e9 pour d\u00e9clencher des <em>ticks<\/em> tous les dixi\u00e8mes de seconde, et une variable globale enregistre la pression \u00e9ventuelle sur le bouton.<\/p>\n<p style=\"text-align: justify;\">L&rsquo;impl\u00e9mentation est disponible sur Github. Il y a un <a href=\"https:\/\/github.com\/cpb-\/MSP-omodoro\/blob\/master\/msp-omodoro.c\">fichier source en C<\/a> et<br \/>\nun <a href=\"https:\/\/github.com\/cpb-\/MSP-omodoro\/blob\/master\/Makefile\">fichier Makefile<\/a> permettant de compiler et flasher le code dans le MSP430.<\/p>\n<pre>$ <strong>git clone https:\/\/github.com\/cpb-\/MSP-omodoro<\/strong>\nClonage dans 'MSP-omodoro'...\n[...]\n$ <strong>cd MSP-omodoro\/<\/strong>\n$ <strong>make<\/strong>\nmsp430-gcc -Wall -mmcu=msp430g2553 msp-omodoro.c -o msp-omodoro.elf<\/pre>\n<p style=\"text-align: justify;\">Pour pouvoir programmer le MSP430, il faut que le <em>launchpad<\/em> soit connect\u00e9 sur un port USB\u00a0:<\/p>\n<pre>$ <strong>make flash<\/strong>\nmspdebug rf2500 erase\n[...]\nErasing...\nProgramming...\nWriting  846 bytes at c000 [section: .text]...\nWriting   32 bytes at c34e [section: .rodata]...\nWriting   32 bytes at ffe0 [section: .vectors]...\nDone, 910 bytes total\n$<\/pre>\n<p style=\"text-align: justify;\">Et voil\u00e0, le syst\u00e8me est dans l&rsquo;\u00e9tape \u00ab\u00a0<em>Time to Work<\/em>\u00a0\u00bb et attend une pression sur le bouton <code>S1<\/code> (celui \u00e0 c\u00f4t\u00e9 des leds) pour entamer une p\u00e9riode de travail.<\/p>\n<h1>Conclusion<\/h1>\n<p style=\"text-align: justify;\">Le programme ci-dessus n&rsquo;est pas parfait. On pourrait dans certain cas rater un appui sur le bouton ou au contraire d\u00e9clencher une pause trop longue si un rebond du poussoir se produit juste au moment du <em>tick timer<\/em>. N\u00e9anmoins, pour une utilisation simple il fonctionne tr\u00e8s bien et remplit son r\u00f4le d&rsquo;illustration p\u00e9dagogique d&rsquo;un d\u00e9veloppement \u00e0 microcontr\u00f4leur.<\/p>\n<p style=\"text-align: justify;\">Un aspect particuli\u00e8rement int\u00e9ressant du microcontr\u00f4leur MSP430 est sa simplicit\u00e9 de mise en \u0153uvre sur un montage ind\u00e9pendant. Il suffit en effet de l&rsquo;alimenter en +3.3\u00a0V et de relier sa broche <em>Reset<\/em> \u00e0 ce niveau haut (via une r\u00e9sistance) pour qu&rsquo;il fonctionne parfaitement avec son oscillateur interne en guise d&rsquo;horloge (on peut lui ajouter un quartz si on souhaite une meilleure pr\u00e9cision). Il suffit alors de relier les entr\u00e9es-sorties d\u00e9sir\u00e9es. Voici un petit sch\u00e9ma de mise en oeuvre\u00a0:<\/p>\n<div id=\"attachment_4898\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/sch\u00e9ma-pomodoro.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4898\" class=\"size-full wp-image-4898\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/sch\u00e9ma-pomodoro.png\" alt=\"Sch\u00e9ma Pomodoro\" width=\"300\" height=\"269\" \/><\/a><p id=\"caption-attachment-4898\" class=\"wp-caption-text\">Sch\u00e9ma Pomodoro<\/p><\/div>\n<p style=\"text-align: justify;\">La valeur pr\u00e9cise des r\u00e9sistances n&rsquo;est pas tr\u00e8s importante. Dans mon petit montage en <a href=\"https:\/\/fr.wikipedia.org\/wiki\/Wrapper_(%C3%A9lectronique)\" target=\"_blank\" rel=\"noopener noreferrer\">wrapping<\/a>, j&rsquo;ai choisi trois r\u00e9sistances identiques de 1,3\u00a0kOhm.<\/p>\n<p style=\"text-align: justify;\">Comme on peut le voir sur la photo ci-dessous, j&rsquo;ai remplac\u00e9 la led verte par une bleue qui me semblait plus adapt\u00e9e \u00e0 l&rsquo;id\u00e9e de pause, de repos. Avec le bouton blanc au milieu \u00e7a donne involontairement un c\u00f4t\u00e9 <em>french touch<\/em> \u00e0 mon pomodoro&nbsp;!<\/p>\n<div id=\"attachment_4899\" style=\"width: 510px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/pomodori.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4899\" class=\"wp-image-4899\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/pomodori.png\" alt=\"Montage du pomodoro\" width=\"500\" height=\"183\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/pomodori.png 600w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2017\/04\/pomodori-300x110.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/a><p id=\"caption-attachment-4899\" class=\"wp-caption-text\">Montage du pomodoro<\/p><\/div>\n<p style=\"text-align: justify;\">L&rsquo;alimentation est fournie par deux piles de 1,5\u00a0V (le bo\u00eetier ci-dessus peut en contenir trois, mais un emplacement est vide). Il serait int\u00e9ressant de r\u00e9aliser un petit bo\u00eetier en impression 3D, rappelant \u00e9ventuellement la tomate du pomodoro original&#8230;<\/p>","protected":false},"excerpt":{"rendered":"<p>Le modeste programme pr&eacute;sent&eacute; dans cet article est extrait d&rsquo;un exercice de travaux pratiques que je propose aux participants de la formation &laquo;&nbsp;Programmation en C sur microcontr&ocirc;leurs&nbsp;&raquo; que j&rsquo;anime r&eacute;guli&egrave;rement. Cet exercice permet de r&eacute;fl&eacute;chir en profondeur sur le d&eacute;veloppement d&rsquo;un petit projet sur microcontr&ocirc;leur. Comme l&rsquo;objet m&ecirc;me de la r&eacute;alisation peut &ecirc;tre utile au [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,8,16],"tags":[],"class_list":["post-4878","post","type-post","status-publish","format-standard","hentry","category-embarque","category-linux-2","category-microcontroleur"],"_links":{"self":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4878","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/comments?post=4878"}],"version-history":[{"count":31,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4878\/revisions"}],"predecessor-version":[{"id":4918,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4878\/revisions\/4918"}],"wp:attachment":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/media?parent=4878"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/categories?post=4878"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/tags?post=4878"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}