URL:
https://linuxfr.org/news/taptempo-pour-arduino-uno
Title: TapTempo pour Arduino Uno
Authors: xulops
Ysabeau et Benoît Sibaud
Date: 2020-12-18T16:40:11+01:00
License: CC By-SA
Tags: arduino et taptempo
Score: 4
Puisqu’elle n’existe pas encore, voici une version de TapTempo pour Arduino Uno, utilisant Arduino IDE sous Linux.
Arduino est une marque italienne proposant des cartes de développement open-source basées sur des micro-contrôleurs AVR, ARM et Cortex-A3.
L’Arduino Uno est la carte la plus connue et la plus accessible : compter environ deux euros en Chine pour des copies d’Arduino, et moins de dix euros en France. Elle est équipée d’un micro-contrôleur Atmel ATmega328P, dont les caractéristiques techniques sont : architecture Atmel AVR, 16MHz, 8bit, 32ko Flash, 1ko EEPROM, 2ko de SRAM. On est donc loin des PC avec CPU en GHz et RAM en Go.
----
[Le projet TapTempo](
https://linuxfr.org/wiki/taptempo)
[TapTempo en Verilog](
https://linuxfr.org/news/taptempo-en-verilog)
[Portage de TapTempo en VHDL](
https://linuxfr.org/news/portage-de-taptempo-en-vhdl)
[Page wikipédia Arduino](
https://fr.wikipedia.org/wiki/Arduino)
[Site officiel Arduino](
https://www.arduino.cc/)
[Installation d’Arduino IDE sous Linux](
https://www.arduino.cc/en/guide/linux)
[Site sur les IoT à base d’Arduino, ESP8266, ESP32 et leurs capteurs/accessoires](
https://randomnerdtutorials.com/)
----
# Les avantages de la carte
Les avantages de cette carte sont :
- 14 entrées/sorties numériques, dont 6 PWM ;
- 6 entrées analogiques ;
- port série, bus I2C et SPI ;
- consommation électrique autour de 50mA sous 5V ;
- un nombre phénoménal de capteurs et accessoires en tous genres et pas chers (shield moteur, capteurs ultrason, température, pression, humidité, vibration…) ;
- un port USB pour transférer le programme dans le micro-contrôleur, et retourner des infos au PC via le port série de la carte ;
- un IDE (Arduino IDE sous GPL 2.0) qui fonctionne sous Linux et prend en charge toute la partie transfert du code. Il fait également office de moniteur série, et plotter/grapheur bien pratique pour suivre l’évolution de valeurs de capteurs dans le temps.
C’est donc une carte simple et idéale pour apprendre à faire des robots, automatiser sa serre de jardin ou son aquarium, faire une serrure à carte sans contact, etc.
Pour l’exemple TapTempo, j’utilise une « Funduino UNO », copie chinoise à bas prix, un écran LCD de deux lignes de 16 caractères avec interface I2C, et un bouton poussoir câblé entre l’entrée numérique n°2 et la masse.

Comme je n’aime pas les câbles Dupont mâles, j’utilise ici une carte supplémentaire qui vient se poser sur l’Arduino Uno, qui ne fait que rendre plus accessible les pins de connexion (un sensor shield). C’est facultatif et ça marche très bien sans. Le câblage est d’ailleurs simple à réaliser.

# Le programme
Le programme est écrit dans Arduino IDE qui permet de faire du C et C++. On peut utiliser d’autres IDE et d’autres langages (LUA, microPython). Voici le TapTempo basique :
```c
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2); // parametres de l'ecran à cristaux liquides
// quelques constantes et variables globales
const byte TAP_PIN = 2; // bouton poussoir connecté sur l'entrée 2
bool bouton_status = true;
unsigned long t[6]; // stocke 6 taps pour avoir 5 intervalles
byte i;
byte n;
unsigned long tempo;
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("TapTempo Arduino");
lcd.setCursor(0,1);
lcd.print("Tempo : ....");
pinMode(TAP_PIN, INPUT_PULLUP); // on s'évite une résistance
for (i = 0; i < 6; i++) t[i] = 0;
}
void loop() {
if (! bouton_status) {
bouton_status = digitalRead(TAP_PIN);
} else {
bouton_status = digitalRead(TAP_PIN);
if (! bouton_status) {
// ok, un appui est detecté
for (i = 0; i < 5; i++) t[i] = t[i + 1];
t[5] = millis();
if (t[5] - t[4] < 3000) {
// calcul de la moyenne des 5 derniers taps
tempo = 0;
n = 0;
for (i = 1; i < 6; i++) {
if (t[i - 1] > 0) {
tempo += t[i] - t[i - 1];
n++;
}
}
tempo = 60000 / (tempo / n);
// affichage du resultat
lcd.setCursor(8, 1);
lcd.print(tempo);
lcd.print(" ");
} else {
// premier tap, on attend le suivant
}
} else {
if (millis() - t[5] > 3000) {
// rien depuis 3s (tempo < 20), on reinitialise
lcd.setCursor(8, 1);
lcd.print("....");
for (i = 0; i < 6; i++) t[i] = 0;
}
}
}
delay(10); // pour ne pas se taper le rebond du bouton
}
```
# Les fonctions setup et loop
Arduino IDE impose la présence de deux fonctions : _setup_ et _loop_.
La fonction _setup_ ne s’exécute qu’une seule fois, lorsque l’Arduino Uno est mis sous tension ou après un _reset_ (le tranfert d’un nouveau code dans le micro-contrôleur est toujours automatiquement suivi d’un _reset_).
Elle est assez facile à comprendre, elle initialise l’écran (facultatif), les entrées/sorties utilisées (ici uniquement le pin 2 pour le bouton poussoir), et le tableau des taps. On peut juste s’appesantir un peu sur le INPUT_PULLUP qui indique au micro-contrôleur qu’il doit activer la résistance interne de pullup de cette entrée. Si cette entrée est déclarée en INPUT seulement, il faut alors ajouter une résistance (10kOhm par exemple) entre l’entrée 2 et le 5V, afin de ramener l’entrée proche de 5 volts (HIGH, true) lorsque le bouton n’est pas pressé. Sinon l’entrée ne serait connectée à rien, donc avec un potentiel électrique indéterminé. Lorque le bouton est pressé, l’entrée est en connexion directe avec la masse, donc quasiment à 0V (LOW, false).
La fonction _loop_, comme son nom l’indique, s’exécute en boucle.
On commence par regarder si le bouton était pressé à la fin de la boucle précédente (bouton_status à false), si oui, on lit l’état du bouton jusqu’à relâchement. Sinon, le bouton était relâché, on peut donc regarder si maintenant il est pressé ou pas.
Suit le classique calcul du tempo basé sur les 5 dernières mesures et l’affichage. L’affichage et le tableau se réinitialisent si pas de tap pendant plus de 3 secondes.
La fonction _loop_ se termine par un mystérieux délai de 10 ms, dont l’unique but est de ne pas capter le rebond du bouton. En effet, un bouton poussoir ne passe pas toujours franchement d’un état ouvert à l’état fermé, il rebondit, pouvant donner des séries d’ouvertures-fermetures perturbantes pendant quelques millisecondes. Sur ce bouton, la transition est normale (avec légère surtension pendant 2ms) au moins 9 fois sur 10, mais des rebonds sont présents sur environ un dixième des taps. Ces rebonds ne dépassent toutefois jamais les 3ms.

Avec un délai de 10 ms, il n’y a donc pas de risques que les rebonds viennent perturber le programme.
Patienter un centième de seconde ne gêne pas à l’usage, j’ai mesuré avec précision (à l’unité près, je ne pense pas que descendre sous la virgule soit d’un grand intérêt musical) entre 20 BPM et 240 BPM, l’erreur la plus grande vient de mon doigt qui appuie sur le bouton (et du cerveau qui commande le doigt), bref je n’arrive pas à suivre, faudrait faire un robot (à base d’Arduino Uno ?) qui appuie sur le bouton à ma place.

# Usage mémoire
En incluant les bibliothèques I2C (wire.h) et LiquidCrystal pour l’écran LCD, la compilation donne :
- 4092 octets de FLASH utilisés sur les 32ko disponibles ;
- 323 octets de SRAM utilisés sur les 2ko disponibles.
En n’utilisant pas l’écran LCD et en envoyant le tempo mesuré sur le port série :
- 2454 octets de FLASH utilisés ;
- 218 octets de SRAM utilisés.
Pour comparaison, pour un programme vide (juste les deux fonctions sans autre ligne de code), la compilation donne respectivement 444 octets de FLASH et 9 octets de SRAM utilisés. Ça peut sembler bizarre, mais le compilateur ajoute toujours un appel pour surveiller les événements sur le port série.
Pas de drame, tout cela reste léger.
# Avec d’autres micro-contrôleurs
Les ESP8266 et ESP32, qui sont des micro-contrôleurs wifi de la société Expressif, ont aussi la cote en ce moment, principalement pour les remontées de mesures à distance, alertes par courriel… Pour ces micro-contrôleurs bien mieux équipés (160 MHz, 4 Mo RAM) qu’un Arduino Uno, le programme serait le même, Arduino IDE se chargeant de compiler et transférer le programme au micro-contrôleur. Il faudra penser cependant à ajouter une résistance de pullup suivant les modèles, tous les micro-contrôleurs ne sont pas pourvus de ces résistances internes. L’ESP32 est pourvu d’entrées tactiles (capacitive touch sensor), il serait intéressant de remplacer le bouton poussoir par une simple plaque métallique et regarder s’il est possible de s’affranchir des problèmes de rebonds.