[TUTORIEL] Conversions de types et Fonctions Arduino

Les cartes Arduino, les platines

[TUTORIEL] Conversions de types et Fonctions Arduino

Message non lude Florian » Ven 31 Juil 2015 16:15

Bonjour,

Aujourd'hui, approche de la programmation Arduino. Conversions des différents types de data et quelques fonctions Arduino.

Blink.png
Blink.png (67.6 Kio) Vu 1059 fois

Il peut être utile de savoir qu'il est possible de convertir un type de donnée en un autre type. Pour cela, plusieurs méthodes sont possibles.
Dans un premier temps, nous allons aborder les conversions de types les plus répandues sous Arduino. Ensuite, la méthode des "Cast Operator".


Conversion de type:

Les conversions d'un type de variable vers un autre sont simples à mettre en place. Ces fonctions ont le même nom que le type de variable que l'on souhaite convertir.
Les fonctions de conversion sont:
byte(), char(), int(), word(), long() et float().
Ces fonctions fonctionnent comme suit, on veut convertir la variable X dans le type byte. On l'écrira alors:
Code: Tout sélectionner
byte(X);

Voici un petit sketch d'exemple qui va vous permettre de bien comprendre comment employer ces fonctions.
Code: Tout sélectionner
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  float X = 82.88;
 
  Serial.print("La valeur de type int est: ");
  Serial.println(int(X));    // Force le type float de la variable X au type int.
 
  Serial.print("La valeur de type char est: ");
  Serial.println(char(X));    // Force le type float de la variable X au type char.
 
  delay(5000);
}

La fonction word() est la seule de ces fonctions qui est "plus évoluée". Il est possible si nécessaire de former un mot de 16 bits, composé de 2 mots de 8 bits. Les 8 bits de poids forts sont dans la variable pforts et les 8 bits de poids faibles sont dans la variable pfaibles.
Comme ceci:
Code: Tout sélectionner
word(pforts, pfaibles);

Autre méthode de conversion, le Cast Operator:
En réalité, il s'agit de la même méthode que précédemment. C'est à dire qu'on va forcer un type de variable à en devenir un autre. La seule différence est l'écriture de cette dernière, sa syntaxe.
Syntaxe:
(type)variable

Comme avant, voici un petit sketch d'exemple qui va vous permettre de bien comprendre comment employer ces fonctions.
Code: Tout sélectionner
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  float X = 82.88;
 
  char C = (char)X;    // Force le type float de la variable X au type char.
  int I = (int)X;    // Force le type float de la variable X au type int.
 
  Serial.print("La valeur de type int est: ");
  Serial.println(I);   
 
  Serial.print("La valeur de type char est: ");
  Serial.println(C);   
 
  delay(5000);
}



Divers Fonctions:

============================================================================================
==> Arithmétique:
    Les fonctions arithmétiques que nous allons aborder sont les suivantes:
      - ++ et --
      - min(x,y) et max(x,y)
      - constrain(x,a,b)
      - abs(x)
      - map(Valeur, ValeurBasse, ValeurHaute, versLeBas, versLeHaut)
      - pow(base, exposant)
      - sqrt(x)

____________________________________________________________________________________________
++ et --

Ces opérateurs servent à incrémenter (++) et à décrémenter (--) une variable d'une unité.
Voici un sketch exemple pour mieux comprendre:
Code: Tout sélectionner
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  Serial.print("Incrementation: ");
  int Nombre = 2;    // Déclaration d'une variable Nombre égale à 2.
  Nombre++;    // Incrémentation d'une unité de la variable Nombre.
  Serial.println(Nombre);
 
  Serial.print("Decrementation: ");
  int Chiffre = 2;    // Déclaration d'une variable Chiffre égale à 2.
  Chiffre--;    // Décrémentation d'une unité de la variable Chiffre.
  Serial.println(Chiffre);
 
  delay(5000);
}

Il existe une subtilité d'utilisation de cette opérateur. On peut l'écrire;
i++/i--
et
++i/--i

Lors de la première notation, i est checké puis incrémenté/décrémenté. A l'inverse dans la deuxième notation, i est d'abord incrémenté/décrémenté avant d'être checké.

____________________________________________________________________________________________
min(x,y) et max(x,y)

Le fonctionnement de ces deux fonctions est identique pour les deux. La fonction min(x,y) donnera toujours la valeur la plus petite des deux. A l'inverse la fonction max(x,y) donnera toujours la valeur la plus grande des deux.
Sketch exemple:
Code: Tout sélectionner
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int X = 42;
  int Y = 24;
 
  int Minimum = min(X,Y);
  int Maximum = max(X,Y);
 
  Serial.print("Le minimum est: ");
  Serial.println(Minimum);
  Serial.print("Le maximum est: ");
  Serial.println(Maximum);
 
  delay(5000);
}

____________________________________________________________________________________________
constrain(x,a,b)

Cette fonction oblige simplement la variable x à rester bloquer entre les bornes a et b.
Code: Tout sélectionner
NomVariable = constrain(X,A,B);    // NomVariable égale à X tant que ce dernier est compris entre A et B.

C'est à dire que si X est compris entre A et B alors la variable NomVariable prendra la valeur X. Si X est inférieur à la plage [A;B], la variable prendra la valeur la plus petite possible de la plage [A;B]. A l'inverse si X est supérieur à cette dernière plage alors la variable prendra la plus grande valeur possible de cette plage.
Un sketch d'exemple vaut mieux qu'un grand discours:
Code: Tout sélectionner
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  // Nom des variables.
  int Variable;
  int Variable2;
  int Variable3;
     
  // Valeurs que les variables sont supposées prendre.
  int X = 42;
  int Y = 38;
  int Z = 54;
     
  // Les limites de la plage acceptée.
  int A = 40;    // Minimum.
  int B = 50;    // Maximum.
     
  // Vérification que les valeurs X,Y,Z soient comprises entre A et B.
  // Puis affectation du résultat dans une variable.
  Variable = constrain(X,A,B);
  Variable2 = constrain(Y,A,B);
  Variable3 = constrain(Z,A,B);
     
  // Affichage des résultats.
  Serial.print("Valeur Variable: ");
  Serial.println(Variable);
     
  Serial.print("Valeur Variable2: ");
  Serial.println(Variable2);
     
  Serial.print("Valeur Variable3: ");
  Serial.println(Variable3);
     
  delay(5000);
}

____________________________________________________________________________________________
abs(x)

Cette fonction abs(x) détermine la valeur absolue de vos nombres et chiffres. De façon très simplifiée, elle exclut les négatifs. C'est à dire lorsque x sera égal à une valeur positive alors abs(x) sera égal à x, en revanche quand x sera égal à une valeur négative alors abs(x) sera égal à -x. Donc un positif puisque x est déjà négatif au départ, ( - (-x)) fait +.
Voilà un sketch qui vous aidera à mieux comprendre les propos ci-dessus:
Code: Tout sélectionner
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  // Valeurs de départ.
  int X = 42;
  int Y = -54;
     
  // Réalisation de la valeur absolue des valeurs précédentes.
  // Et affichage.
  Serial.print("Valeur absolue de X: ");
  Serial.println(abs(X));
     
  Serial.print("Valeur absolue de Y: ");
  Serial.println(abs(Y));
     
  delay(5000);
}

____________________________________________________________________________________________
map(Valeur, deBas, deHaut, versBas, versHaut)

Lors de l'utilisation d'un capteur, il est souvent nécessaire de convertir sa plage de mesure en donnée compréhensible pour l'Homme. Ainsi avec cette fonction on peut modifier la plage de variation d'une variable.
Les variables "deBas" et "deHaut" sont respectivement la valeur minimum et la valeur maximum de la plage de variation de la variable "Valeur". Et les variables "versBas" et "versHaut" sont respectivement le minimum et le maximum de la nouvelle plage de variation.
Il est important de savoir que cette fonction n'utilise que des entiers, aussi bien négatifs que positifs mais que des entiers.
Code: Tout sélectionner
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int Tension;    // Tension qu'on exprimera en pourcentage.
  int Lecture = analogRead(0);    // Lecture de la broche O.
     
  // Conversion de la plage de valeur de la broche 0,
  // sur une échelle de 0 à 100 (en pourcentage).
  Tension = map(Lecture, 0, 1023, 0, 100);
     
  // Affichage du niveau de tension en pourcentage.
  Serial.print("La tension est a ");
  Serial.print(Tension);
  Serial.println("%");
     
  delay(5000);
}

____________________________________________________________________________________________
pow(base,exposant)

Cette fonction permet d'élever un nombre à une puissance donnée. C'est à dire que la variable "base" aura comme exposant la valeur de la variable "exposant".
Exemple de sketch:
Code: Tout sélectionner
void setup()
{
 Serial.begin(9600);
}

void loop()
{
  int Base = 2;    // Nombre élevé à la puissance.
  int Exposant = 3;    // Puissance.
  int Resultat;
 
  Resultat = pow(Base, Exposant); // Stocke le résultat du calcul dans Resultat.
 
  Serial.println(Resultat);    // Affichage.
 
  delay(5000);
}

____________________________________________________________________________________________
sqrt(x)

Cette fonction permet simplement de calculer la racine carrée de la variable x.
Code: Tout sélectionner
void setup()
{
 Serial.begin(9600);
}

void loop()
{
  int X = 16;    // Valeur qui va subir la racine carrée.
  int Resultat;
 
  Resultat = sqrt(X); // Stocke le résultat du calcul dans Resultat.
 
  Serial.println(Resultat);    // Affichage.
 
  delay(5000);
}


============================================================================================
==> Trigonométrie :
    Les fonctions trigonométriques que nous allons aborder sont les suivantes:
      - cos(x)
      - sin(x)
      - tan(x)

____________________________________________________________________________________________
cos(x), sin(x) et tan(x)

Ces trois fonctions calculent comme elles l'indiquent le cosinus, le sinus et la tangente d'un angle. Le résultat est en radians et elles s'utilisent toutes les trois de la même façon.
Voyez plutôt:
Code: Tout sélectionner
void setup()
{
 Serial.begin(9600);
}

void loop()
{
  float Angle = 38.6;    // Angle "mesuré".
  float Cosinus;
  float Sinus;
  float Tangente;
 
  Cosinus = cos(Angle);    // Calcul du cosinus.
  Sinus = sin(Angle);    // Calcul du sinus.
  Tangente = tan(Angle);    // Calcul de la tangente.
 
  // Affichage
  Serial.print("Le cosinus de l'angle est: ");
  Serial.print(Cosinus);
  Serial.println(" radians.");
 
  Serial.print("Le sinus de l'angle est: ");
  Serial.print(Sinus);
  Serial.println(" radians.");
 
  Serial.print("La tangente de l'angle est: ");
  Serial.print(Tangente);
  Serial.println(" radians.");
 
  delay(5000);
}


============================================================================================
==> Manipulation de bits :
    Les fonctions que nous allons aborder sont les suivantes:
      - lowByte(x)
      - highByte(x)
      - bitRead(x)
      - bitWrite(x)
      - bitSet(x) et bitClear(x)

____________________________________________________________________________________________
lowByte(x)

Cette fonction extrait les 8 bits de poids faibles de vos variables. Soit le premier octet d'une variable en partant de la droite.
Syntaxe :
Code: Tout sélectionner
byte Resultat = lowByte(Variable);

____________________________________________________________________________________________
highByte(x)

Cette fonction peut s'apparenter à la précédente mais n'est pas totalement identique. En réalité, cette fonction va extraire le deuxième octet d'une variable en partant de la gauche.
Autrement dit pour une variable qui ne contient que deux octets cette fonction fournira effectivement les 8 bits de poids forts (l'octet de poids fort). Autrement dit pour une variable de taille plus importante, cette fonction n'extraira pas les 8 bits de poids fort mais seulement les 8 bits contenus dans le deuxième octet en partant de la droite.
Syntaxe:
Code: Tout sélectionner
byte Resultat = highByte(Variable);

____________________________________________________________________________________________
bitRead(x)

Cette fonction permet comme son nom l'indique de lire l'état d'un bit précis dans une variable.
Syntaxe:
Code: Tout sélectionner
byte Resultat = bitRead(Variable, n);

n est le numéro à renseigner pour savoir quel bit aller lire. On commence à 0 et par la droite donc par le bit de poids le plus faible.
Sketch exemple:
Code: Tout sélectionner
void setup()
{
 Serial.begin(9600);
}

void loop()
{
  byte Resultat;
  int Test = 1023;    // Application d'une valeur à la variable de test.
 
  Resultat = bitRead(Test, 3);    // On va lire l'état du troisième bit,
                                  // en partant de la droite.
 
  Serial.println(Resultat);    // Affichage 0 ou 1.
 
  delay(5000);
}

____________________________________________________________________________________________
bitWrite(x)

Cette fonction permet comme son nom l'indique de forcer l'état d'un bit précis à 0 ou 1 dans une variable.
Syntaxe:
Code: Tout sélectionner
byteWrite(variable, n, bit);

Comme précédemment n permet de spécifier le numéro du bit à écrire. Comme avant on commence à 0 pour le bit de poids faible.
La variable bit ne prend donc que deux valeurs 0 ou 1.
Voici un sketch pour illustrer les explications :
Code: Tout sélectionner
void setup()
{
 Serial.begin(9600);
}

void loop()
{
  byte Resultat;
  int Test = 1023;    // Application d'une valeur à la variable de test.
 
  Resultat = bitRead(Test, 3);    // On va lire l'état du troisième bit,
                                  // en partant de la droite.
 
  Serial.print("L'etat du troisieme bit avant modification: ");                               
  Serial.println(Resultat);    // Affichage de l'état du troisième bit,
                               // avant modification (bit à 1).
 
  bitWrite(Test, 3, 0);    // On va forcer l'état du troisième bit à 0.
                                   
  Resultat = bitRead(Test, 3);    // On va lire l'état du troisième bit,
                                  // en partant de la droite après modification.
 
  Serial.print("L'etat du troisieme bit apres modification: ");                               
  Serial.println(Resultat);    // Affichage (bit à 0).
 
  delay(5000);
}

____________________________________________________________________________________________
bitSet(X) et bitClear(X)

Ces deux fonctions permettent d'écrire un bit à 1[bitSet()] ou un bit à 0 [bitClear()].
Syntaxe:
Code: Tout sélectionner
bitSet(variable, n);
bitClear(variable, n);

Comme pour les fonctions bitRead() et bitWrite(), "n" permet de spécifier le bit à écrire. Comme pour ces fonctions "n" commence encore à 0 par le bit de poids faible donc celui le plus à droite de la variable.
Sketch d'utilisation:
Code: Tout sélectionner
void setup()
{
 Serial.begin(9600);
}

void loop()
{
  byte Resultat;
  int Test = 1023;    // Application d'une valeur à la variable de test.
 
  Resultat = bitRead(Test, 3);    // On va lire l'état du troisième bit,
                                  // en partant de la droite.
 
  Serial.print("L'etat du troisieme bit avant modification: ");                               
  Serial.println(Resultat);    // Affichage de l'état du troisième bit,
                               // avant modification (bit à 1).
 
  bitClear(Test, 3);    // On va forcer l'état du troisième bit à 0.
                                   
  Resultat = bitRead(Test, 3);    // On va lire l'état du troisième bit,
                                  // en partant de la droite après modification.
 
  Serial.print("L'etat du troisieme bit apres bitClear(): ");                               
  Serial.println(Resultat);    // Affichage (bit à 0).
 
  bitSet(Test, 3);    // On va forcer l'état du troisième bit à 1.
 
  Resultat = bitRead(Test, 3);    // On va lire l'état du troisième bit,
                                  // en partant de la droite après modification.
 
  Serial.print("L'etat du troisieme bit apres bitSet(): ");                               
  Serial.println(Resultat);    // Affichage (bit à 1).
 
  delay(5000);
}


============================================================================================
==> Entrées/Sorties particulières
    Les fonctions que nous allons aborder sont les suivantes:
      - tone(x)
      - noTone(x)
      - pulseIn(x)
      - shiftOut(x)

____________________________________________________________________________________________
tone(x)

Cette fonction permet de générer un signal carré (pwm de 50%) basse fréquence sur une des sorties numériques de l'Arduino.
Syntaxe:
Code: Tout sélectionner
tone(sortie, fréquence);
tone(sortie, fréquence, durée);

La variable sortie indique le numéro de la sortie Arduino.
La variable fréquence définit, comme elle l'indique, la fréquence voulue (en Hertz).
La variable durée n'est pas obligatoire et sert à définir une limite de temps de la génération du signal carré (en milliseconde).

____________________________________________________________________________________________
noTone(x)

Cette fonction permet de faire cesser la génération d'un signal carré.
Syntaxe:
Code: Tout sélectionner
noTone(sortie);

Comme ci-dessus, la variable sortie indique le numéro de la sortie Arduino.

____________________________________________________________________________________________
pulseIn(x)

Cette fonction permet de mesurer la durée d'une impulsion.
Syntaxe:
Code: Tout sélectionner
durée = pulseIn(entrée, type);
durée = pulseIn(entrée, type, délaiMax);

La variable entrée indique le numéro de la broche Arduino.
La variable type permet de définir le type d'impulsion. C'est à dire si l'impulsion détectée est sur front montant ou sur front descendant.
La variable délaiMax renseigne le temps d'attente maximum pour un changement d'état (TimeOut) en microsecondes. Si rien n'est renseigné pour cette variable il sera par défaut d'une seconde. Si rien n'est détecté au delà de cette seconde la fonction retourne 0.

____________________________________________________________________________________________
shiftOut(x)

Cette fonction permet d’émettre un par un les bits d'un octet de donnée (8 bits). Elle peut aussi bien commencer par envoyer le bit de poids fort comme le bit de poids faible. On parle ici d'un protocole de série synchrone.
Autrement dit les bits de l'octet sont envoyés chacun leur tour un à un sur une ligne de communication. A chaque fois qu'un bit est placé sur cette ligne de communication, l'horloge change d'état pour indiquer qu'un bit est disponible.
Syntaxe:
Code: Tout sélectionner
shiftOut(sortie donnée, sortie horloge, ordre des bits, donnée);

La variable sortie donnée indique sur quelle broche sort les données.
La variable sortie horloge indique la broche qui va être utilisée pour le signal horloge.
La variable ordre des bits fixe l'ordre dans lequel les bits doivent être émis. Cela peut être égal seulement à MSBFIRST (le bit de poids fort envoyé en premier) ou à LSBFIRST (le bit de poids faible envoyé en premier).
La variable donnée est le type de donnée à envoyer, type byte.

Les broches sortie donnée et sortie horloge doivent toujours être configurées en sortie à l'aide de la fonction pinMode().


============================================================================================
==> Génération de nombres aléatoires
    Les fonctions que nous allons aborder sont les suivantes:
      - randomSeed(x)
      - random(x)

____________________________________________________________________________________________
randomSeed(x)

Cette fonction permet d'initialiser la fonction random(x) qui permet de générer un nombre aléatoire. Un nombre aléatoire est généré à partir d'une valeur de départ, le seed. Si l'on part toujours du même seed, on obtiendra toujours la même séquence aléatoire de nombres. Ce seed peut donc être une valeur fixe et toujours obtenir la même séquence soit également une valeur "aléatoire" comme la mesure d'une tension analogique sur une entrée non connectée. Ainsi on n'obtiendra jamais une même séquence aléatoire de nombre.
Syntaxe:
Code: Tout sélectionner
randomSeed(Valeur);

Sketch d'exemple:
Code: Tout sélectionner
void setup()
{
  Serial.begin(9600);
  randomSeed(analogRead(0)); // Initialise le générateur de nombre aléatoire en lisant broche analogique 0.
}

void loop()
{
  int Hasard = random(500); // Génération d'un nombre aléatoire.
  Serial.println(Hasard); // Affichage.

  delay(2000);
}

____________________________________________________________________________________________
random(x)

Cette fonction permet de générer des nombres aléatoires caclculés à partir du seed dans la fonction randomSeed(x).
Syntaxe:
Code: Tout sélectionner
int nombre = random(max);
int nombre = random(min, max);

La première syntaxe permet d'obtenir une séquence de nombres aléatoires entre 0 et le maximum voulu.
La deuxième syntaxe permet d'obtenir une séquence de nombres aléatoires entre un minimum et un maximum voulu.

Sketch d'utilisation de la première syntaxe:
Code: Tout sélectionner
void setup()
{
  Serial.begin(9600);
  randomSeed(analogRead(0)); // Initialise le générateur de nombre aléatoire en lisant broche analogique 0.
}

void loop()
{
  int Hasard = random(500); // Génération d'un nombre aléatoire compris entre 0 et 500 EXCLUS!
  Serial.println(Hasard); // Affichage.

  delay(2000);
}

Sketch d'utilisation de la deuxième syntaxe:
Code: Tout sélectionner
void setup()
{
  Serial.begin(9600);
  randomSeed(analogRead(0)); // Initialise le générateur de nombre aléatoire en lisant broche analogique 0.
}

void loop()
{
  int Hasard = random(220, 270); // Génération d'un nombre aléatoire compris entre 220 et 270 EXCLUS!
  Serial.println(Hasard); // Affichage.

  delay(2000);
}


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Voilà, j'espère que ce tutoriel vous apportera les informations pour comprendre certaines fonctions et savoir comment les utiliser.

Seule l'imagination peut vous stopper dans vos projets.
Florian
 
Messages: 75
Inscription: Mer 24 Juil 2013 17:36

Retourner vers Arduino

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité

cron