Les fonctions

Une fonction est un bloc d’instructions que l’on peut appeler à tout endroit d’un programme.

En langage Arduino, des bibliothèques de fonctions prédéfinies sont disponibles afin de manipuler facilement les entrées/sorties, gérer le temps, gérer la communication série…

On peut également créer ses propres fonctions qui seront utiles pour l’exécution de tâches répétitives et évitant alors la réécriture des lignes de codes à chaque fois que se présente ces tâches.

 

1. Fonctions des Entrées/Sorties numériques


. pinMode()

Configure la broche spécifiée pour qu’elle se comporte soit en entrée, soit en sortie.

Syntaxe :

pinMode(broche, mode)

Paramètres :

broche: le numéro de la broche de la carte Arduino dont le mode de fonctionnement (entrée ou sortie) doit être défini.

mode: soit INPUT (entrée en anglais) ou OUTPUT (sortie en anglais)

 

. digitalWrite()

Met un niveau logique HIGH (HAUT en anglais) ou LOW (BAS en anglais) sur une broche numérique.

Si la broche a été configurée en SORTIE avec l’instruction pinMode(), sa tension est mise à la valeur correspondante : 5V  pour le niveau HAUT, 0V (masse) pour le niveau BAS.

Si la broche est configurée en ENTREE, écrire un niveau HAUT sur cette broche a pour effet d’activer la résistance interne de 20K sur cette broche.

A l’inverse, mettre un niveau BAS sur cette broche configurée en ENTREE désactivera la résistance interne.

Syntaxe :

digitalWrite(broche, valeur)

Paramètres :

broche: le numéro de la broche de la carte Arduino

valeur: HIGH ou LOW (ou bien 1 ou 0)

Exemple :

int ledPin = 13; // LED connectée à la broche numérique n° 13

void setup()
{
pinMode(ledPin, OUTPUT); // met la broche utilisée avec la LED en SORTIE
}

void loop()
{
digitalWrite(ledPin, HIGH); // allume la LED
delay(1000); // pause 1 seconde
digitalWrite(ledPin, LOW); // éteint la LED
delay(1000); // pause 1 seconde
}


Remarques
 :

– Les broches analogiques peuvent être utilisées en tant que broches numériques, représentées par les nombres 14 (entrée analogique 0) à 19 (entrée analogique 5).

– Cette instruction met la valeur 0/1 dans le bit de donnée qui est associé à chaque broche, ce qui explique qu’on puisse le mettre à 1, même si la broche est en entrée.

– Ne pas oublier qu’une broche numérique ne peut fournir que 40mA (milliampères) tant en entrée qu’en sortie, et que l’ensemble des broches de la carte Arduino ne peut fournir que 200mA. Par conséquent, limiter l’intensité utilisée pour chaque broche à une dizaine de mA par des résistances adaptées : 220 Ohms pour une LED par exemple.

 

. digitalRead()

Lit l’état (= le niveau logique) d’une broche précise en entrée numérique, et renvoie la valeur HIGH (HAUT en anglais) ou LOW (BAS en anglais).

Syntaxe :

digitalRead(broche)

Paramètres :

broche : le numéro de la broche numérique que vous voulez lire. (int)

Valeur retournée :

Renvoie la valeur HIGH (HAUT en anglais) ou LOW (BAS en anglais)

Exemple :

int ledPin = 13; // LED connectée à la broche n°13
int inPin = 7; // un bouton poussoir connecté à la broche 7
int val = 0; // variable pour mémoriser la valeur lue

void setup()
{
pinMode(ledPin, OUTPUT); // configure la broche 13 en SORTIE
pinMode(inPin, INPUT); // configure la broche 7 en ENTREE
}
void loop()
{
val = digitalRead(inPin); // lit l’état de la broche en entrée et met le résultat dans la variable
digitalWrite(ledPin, val); // met la LED dans l’état du BP (càd allumée si appuyé et inversement)
}

Dans ce programme, la broche 13 reflète fidèlement l’état de la broche 7 qui est une entrée numérique.

Remarques :

– Si la broche numérique en entrée n’est connectée à rien, l’instruction digitalRead() peut retourner aussi bien la valeur HIGH (HAUT en anglais) ou LOW (BAS en anglais) (et cette valeur peut changer de façon aléatoire)

– Les broches analogiques peuvent être utilisées en entrée numériques et sont désignées par les numéros 14 (entrée analogique 0) à 19 (entrée analogique 5).

 

2. Fonctions des Entrées/Sorties analogiques

. analogRead()

Lit la valeur de la tension présente sur la broche spécifiée.

La carte Arduino comporte 6 voies connectées à un convertisseur analogique-numérique 10 bits.
Cela signifie qu’il est possible de transformer la tension d’entrée entre 0 et 5V en une valeur numérique entière comprise entre 0 et 1023.

Il en résulte une résolution (écart entre 2 mesures) de : 5 volts / 1024 intervalles, autrement dit une précision de 0.0049 volts (4.9 mV) par intervalle.

Une conversion analogique-numérique dure environ 100 µs pour convertir l’entrée analogique, et donc la fréquence maximale de conversion est environ de 10 000 fois par seconde.

Syntaxe :

analogRead(broche_analogique)

Paramètres :

broche_analogique : le numéro de la broche analogique (et non le numéro de la broche numérique) sur laquelle il faut convertir la tension analogique appliquée (0 à 5 sur la plupart des cartes Arduino)

Valeur retournée :

valeur int (0 to 1023) correspondant au résultat de la mesure effectuée

Exemple :

int analogPin = 3; // Capteur analogique relié à la broche A3
int val = 0; // variable de type int pour stocker la valeur de la mesure

void setup()
{
Serial.begin(9600); // initialisation de la connexion série
}

void loop()
{
// lit la valeur de la tension analogique présente sur la broche
val = analogRead(analogPin);

// affiche la valeur (comprise en 0 et 1023) dans la fenêtre terminal PC
Serial.println(val);
}

 

. analogWrite()

Génère un signal carré de fréquence 490 Hz sur une broche de la carte Arduino (onde PWM – Pulse Width Modulation en anglais ou MLI – Modulation de Largeur d’Impulsion en français).

Après avoir appelé l’instruction analogWrite(), la broche générera un signal carré stable avec un rapport cyclique (fraction de la période où la broche est au niveau haut) de durée spécifiée (en %), jusqu’à l’appel suivant de l’instruction analogWrite() (ou bien encore l’appel d’une instruction digitalRead() ou digitalWrite() sur la même broche).

Syntaxe :

analogWrite(broche, valeur);

Paramètres :

broche: la broche utilisée pour « écrire » l’impulsion. Cette broche devra être une broche ayant la fonction PWM, Par exemple, sur la UNO, ce pourra être une des broches 3, 5 ,6 ,9 ,10 ou 11.

valeur: la largeur du « duty cycle » (proportion de l’onde carrée qui est au niveau HAUT) : entre 0 (0% HAUT donc toujours au niveau BAS) et 255 (100% HAUT donc toujours au niveau HAUT).

Exemple :

Le programme suivant fixe la luminosité d’une LED proportionnellement à la valeur de la tension lue depuis un potentiomètre :

int ledPin = 9; // LED connectée sur la broche 9
int analogPin = 3; // le potentiomètre connecté sur la broche analogique 3
int val = 0; // variable pour stocker la valeur de la tension lue

void setup()
{
pinMode(ledPin, OUTPUT); // configure la broche en sortie
}

void loop()
{
val = analogRead(analogPin); // lit la tension présente sur la broche en entrée
analogWrite(ledPin, val / 4);
// Résultat d’analogRead entre 0 to 1023,
// résultat d’analogWrite entre 0 to 255
// => division par 4
}

Remarques :

– Il n’est pas nécessaire de faire appel à l’instruction pinMode() pour mettre la broche en sortie avant d’appeler la fonction analogWrite().

– L’impulsion PWM générée sur les broches 5 et 6 pourront avoir des rapport cyclique plus long que prévu en raison de l’interaction avec les instructions millis() et delay(), qui partagent le même timer (base de temps) interne que celui utilisé pour générer l’impulsion de sortie PWM.

 

3. Fonctions prédéfinies des Entrées/Sorties avancées


. tone()

Génère une onde carrée (onde symétrique avec rapport cyclique (niveau haut/période) à 50%), à la fréquence spécifiée en Hertz (Hz) sur une broche.

La durée peut être précisée, sinon l’impulsion continue jusqu’à l’appel de l’instruction noTone().

La broche peut être connectée à un buzzer piézoélectrique ou autre haut-parleur pour jouer des notes (les sons audibles s’étendent de 20Hz à 20 000Hz).

Une seule note peut être produite à la fois. Si une note est déjà jouée sur une autre broche, l’appel de la fonction tone() n’aura aucun effet (tant qu’une instruction noTone() n’aura pas eu lieu).

 Si la note est jouée sur la même broche, l’appel de la fonction tone() modifiera la fréquence jouée sur cette broche.

Syntaxe :

tone(broche, frequence)

tone(broche, frequence, durée)

Paramètres :

broche : la broche sur laquelle la note est générée.

frequence : la fréquence de la note produite en hertz (Hz)

durée : la durée de la note en millisecondes (optionnel)

 

. noTone()

Stoppe la génération d’impulsion produite par l’instruction tone(). N’a aucun effet si aucune impulsion n’est générée.

Syntaxe :

noTone(broche)

Paramètres :

broche : la broche sur laquelle il faut stopper la note.

 

. pulseIn()

Lit la durée d’une impulsion (soit niveau HAUT, soit niveau BAS) appliquée sur une broche (configurée en ENTREE).

Par exemple, si le paramètre valeur est HAUT, l’instruction pulseIn() attend que la broche passe à HAUT, commence alors le chronométrage, attend que la broche repasse au niveau BAS et stoppe alors le chronométrage.

L’instruction renvoie la durée de l’impulsion en microsecondes. L’instruction s’arrête et renvoie 0 si aucune impulsion n’est survenue dans un temps spécifié.

Il est préférable de travailler avec des impulsions d’une durée de 10 microsecondes à 3 minutes.

Syntaxe :

pulseIn(broche, valeur)

pulseIn(broche, valeur, delai_sortie)

Paramètres :

broche : le numéro de la broche sur laquelle vous voulez lire la durée de l’impulsion.

valeur : le type d’impulsion à « lire » : soit HIGH (niveau HAUT) ou LOW (niveau BAS

delai_sortie (optionnel): le nombre de microsecondes à attendre pour début de l’impulsion. La valeur par défaut est 1 seconde. (type unsigned long)

Valeur renvoyée :

La durée de l’impulsion (en microsecondes) ou 0 si aucune impulsion n’a démarrer avant le délai de sortie. (type unsigned long)

Exemple :

int broche = 7; // variable de broche
unsigned long duree; // variable utilisée pour stocker la durée

void setup()
{
pinMode(broche, INPUT); // met la broche en entrée
}

void loop()
{
duree = pulseIn(broche, HIGH); // met la durée de l’impulsion de niveau HAUT dans la variable duree
}

 

4. Fonctions prédéfinies de gestion du temps 

. delay(ms)

Réalise une pause dans l’exécution du programme pour la durée (en millisecondes) indiquée en paramètre.

Syntaxe :

delay (ms);

Paramètres :

ms (unsigned long): le nombre de millisecondes que dure la pause

 

. unsigned long millis()

Renvoie le nombre de millisecondes depuis que la carte Arduino a commencé à exécuter le programme courant. Ce nombre débordera (càd sera remis à zéro) après 50 jours approximativement.

Syntaxe :

variable_unsigned_long = millis();

Exemple :

unsigned long time;

void setup(){
Serial.begin(9600);
}

void loop(){
Serial.print(« Time: « );
time = millis();
//affiche sur le PC le temps depuis que le programme a démarré
Serial.println(time);
// pause d’une seconde afin de ne pas envoyer trop de données au PC
delay(1000);
}

 

5. Fonctions prédéfinies de communication

La librairie Serial est utilisée pour les communications par le port série entre la carte Arduino et un ordinateur ou d’autres composants.

Le port série communique sur les broches 0 (RX) et 1 (TX) avec l’ordinateur via le port USB. C’est pourquoi, si on utilise cette fonctionnalité, il n’est pas possible d’utiliser les broches 0 et 1 en tant qu’entrées ou sorties numériques.

Le logiciel Arduino IDE dispose d’un moniteur série, qui permet de recevoir et d’envoyer des informations via une liaison série. Il est particulièrement intéressant pour les tests des programmes puisqu’il permet d’afficher les valeurs des variables, les états logiques des entrées et des sorties de l’Arduino, etc…

Il suffit pour cela de cliquer sur le bouton du moniteur série dans la barre d’outils puis de sélectionner le même débit de communication que celui utilisé dans l’appel de la fonction begin() pour établir la liaison série.

Les principales fonctions de la librairie Serial :

. begin();      (Configure la vitesse de transmission du port série)

. print();        (Envoie une donnée sous forme de chaine de caractères sur le port série)

. println();    (Envoie une donnée sur le port série et fait un saut à la ligne)

. write();       (Ecrit des données binaires sur le port série. Ces données sont envoyées comme une série d’octets)

. read();        (Lis les données contenues dans la mémoire tampon (buffer) du port série)

. flush();        (Vide la mémoire tampon de la liaison série)

. available(); (Donne le nombre d’octets (caractères) disponible pour lecture dans la file d’attente (buffer) du port série)

 

Une fois la liaison série établie dans la fonction setup() avec la fonction Serial.begin(), il est possible d’envoyer des données depuis la carte Arduino vers le moniteur série avec la fonction ”print()” de la classe ”Serial”.

On peut envoyer différents types d’informations :

. Envoie d’une chaîne de caractères, sans saut de ligne à la fin :

Serial.print(”Test”);

. Envoie d’une chaîne de caractères, avec saut de ligne à la fin :

Serial.println(”Test”);

. Envoie de la valeur d’une variable, sans saut de ligne à la fin :

int a = 3;
Serial.print(a);

Exemple :

int analogValue = 0; // variable pour stocker la valeur analogique sur la broche A0

void setup() {
// initialise le port série à 9600 bauds
Serial.begin(9600);
}

void loop() {
// lit la valeur analogique sur la broche A0
analogValue = analogRead(0);

// affiche cette valeur
Serial.println(analogValue);
}

 

6. Fonctions propres au progamme

Pour pouvoir utiliser une fonction propre à un programme, il faut au préalable la déclarer et comme son appel doit être possible à tout moment du déroulement du programme, il faut qu’elle soit déclarée de façon globale. C’est-à-dire que cela se fera en dehors des fonctions setup() et loop().

Une fonction possède un nom, des paramètres d’entrée et des paramètres de sortie. On appelle prototype d’une fonction, la spécification de ces trois données :

Et tout ce que fait la fonction doit être placé entre deux accolades.

 

Il existe deux types de fonctions :

– Les fonctions qui ne renvoie aucune donnée,

– Les fonctions qui renvoie une donnée.

 

. Si la fonction ne renvoie aucune donnée, son type de retour sera void.

Exemple :

Ce programme affiche le résultat de la division de 10 par 3 avec 1 à 5 chiffres après la virgule, dans le moniteur série.

Pour cela, on déclare une fonction appelée affichfloat() dont le type de retour est void (vide) et les paramètres d’entrées sont le nombre à virgule, (float) a, à afficher et un entier, b, représentant le nombre de chiffres après la virgule du nombre a qui seront affichés.

La fonction est appelée dans une boucle for() de la fonction setup() et le résultat de la division est affiché dans le moniteur série.

void affichfloat(float a, int b) { // Déclaration de la fonction « affichfloat »
Serial.println(a,b); // Affichage de la variable a avec b chiffres après la virgule
}

void setup() {
Serial.begin(9600);
float result = 10.0/3.0;
for(int i = 1 ; i < 6 ; i++){
affichfloat(result,i); // Appel de la fonction « affichfloat »
}
}

void loop() {
}


. Si la fonction renvoie une donnée, elle devra le faire avec le mot-clef return.

Exemple :

Le programme suivant affiche la table de multiplication de 2 dans le moniteur série. Pour cela, une fonction appelée multiplication() dont le type de retour est un entier c et les paramètres d’entrées sont 2 entiers a et b est déclarée.

La fonction est appelée dans une boucle for() de la fonction setup() et le résultat de la multiplication est affiché dans le moniteur série.

int multiplication (int a, int b) { // Déclaration de la fonction « multiplication »
int c ;
c = a * b ;
return c ;
}

void setup() {
Serial.begin(9600);
for(int i = 1 ; i < 10 ; i++){
int result = multiplication(2,i); // Appel de la fonction « multiplication »
Serial.println(result); // Affichage de la donnée de retour de la fonction « multiplication »
}
}

void loop() {
}

 


Après avoir vu les bases de la programmation en langage Arduino, nous allons maintenant écrire notre premier programme basé sur « Blink », qui comme vous l’avez compris, met en application le principe de fonctionnement d’une sortie numérique, en faisant intervenir des variables.