summaryrefslogtreecommitdiff
path: root/chapters/c.rst
blob: 2948db45744d146d5304bd32199eb1809fea9062 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
.. -*- mode: rst -*-
.. -*-  coding: utf-8 -*-

.. role:: raw-latex(raw)
   :format: latex

La carte Arduino se programme en langage C.

Les types
=========

La carte Arduino (ou l'ordinateur), ne comprend que le binaire, mais nous
n'allons pas écrire nos programme en binaire. Nous avons besoin de manipuler
des nombres pour calculer des délais, mesurer des températures etc. Nous avons
besoin d'indiquer au programme comment ces données binaires doivent être
chargée en mémoire pour pouvoir travailler avec.

Chaque type occupe une certaine quantité d'octets en mémoire, en fonction de la
donnée, et de ce que l'on peut faire avec. Plus la taille mémoire est grande,
meilleure sera la précision de la valeur (ou la liste des valeurs possibles etc).

L'instruction :index:`sizeof` `sizeof` [#]_ permet de calculer la taille
d'une variable, elle est utile dans le cas où l'on souhaite faire des calculs
directement sur la mémoire de l'arduino.

.. [#] https://www.arduino.cc/reference/en/language/variables/utilities/sizeof/

Les booléens
------------

.. sidebar:: Boole

  L'adjectif booléen vient du nom du mathématicien George Boole qui a travaillé
  sur la logique et catégorisé ce type qui ne peut prendre que deux valeurs.

Le type booléen représente une valeur binaire `1` ou `0`, ou encore *Oui* ou
*Non*. Nous l'avons vu quand nous avons utilisé les valeurs `HIGH` ou `LOW` sur
les sorties de la carte Arduino.

.. code-block:: c

  /* Crée une variable qui servira à savoir s'il faut mettre à
     jour les données.
   */
  bool mettre_a_jour = true;
  if (mettre_a_jour) {
    /* fait la mise à jour, puis passe l'indicateur à false
       pour éviter de le faire une deuxième fois.
    */
    mettre_a_jour = false;
  }

Opérations sur les booléens
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Il existe trois opérations principales que l'on peut retrouver sur les booléens
et qui permettent de construire la logique du programme.

:et:

  Le *et* (`&&` [#]_ :index:`&&`) permet d'associer deux booléens entre eux, et
  donne un résultat qui est lui-même booléen, et vaut `true` si les deux sont à
  `true`.

.. [#] https://www.arduino.cc/reference/en/language/structure/boolean-operators/logicaland/

:ou:

  Le *ou* (`||` [#]_ :raw-latex:`\index{\textbar{} \textbar{}}\marginpar{\texttt{||}}`) permet d'associer deux booléens entre eux, et
  donne un résultat qui est lui-même booléen, et vaut `true` si l'un ou l'autre
  est à `true`.

.. [#] https://www.arduino.cc/reference/en/language/structure/boolean-operators/logicalor/

:non:

  Le *non* (`!` [#]_ :raw-latex:`\index{"!}\marginpar{\texttt{!}}`) permet d'inverser la valeur d'un booléen

.. [#] https://www.arduino.cc/reference/en/language/structure/boolean-operators/logicalnot/

.. note::

    Ces opérateurs peuvent se combiner entre eux pour réaliser, on les retrouve
    dans les tests de condition pour faire des tests évolués. Par exemple, pour
    mettre à jour l'affichage si la température a changé, ou si la pression a
    changé, ou s'il s'est écoulé plus d'une heure depuis la dernière mise à jour…

Les nombres entiers
-------------------

Les nombres entiers permettent de représenter des nombres entre deux bornes.
Ils peuvent être signés (prendre une valeur négative) ou non.

En fonction de la taille occupée en mémoire, les types auront des plages de
valeurs possibles plus ou moins importantes :

=============== =============== ================ ===============
Type            Valeur Minimale Valeur Maximale  Taille mémoire
=============== =============== ================ ===============
`byte`          0               256              1
`int`           -32 768         32 767           2
`unsigned int`  0               65 536           2
`long`          -2 147 483 647  2 147 483 647    4
`unsigned long` 0               4 294 967 295    4
=============== =============== ================ ===============

.. admonition:: Attention
  :class: warning

  Si jamais la valeur dépasse la limite, aucune erreur ne sera remontée par
  l'application, mais la valeur va repartir à 0 !

Les nombres flottants
---------------------

Les nombres flottants peuvent représenter des nombres décimaux, avec toutes les
valeurs possibles. Cela se fait au prix d'une plus grande consommation de la
mémoire, et d'une approximation de la valeur.


Comparer deux nombres flottants
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Il n'est pas possible de comparer directement deux nombres flottants
différents, car la probabilité d'avoir exactement deux fois la même valeur est
quasiment nulle. Il faut utiliser une méthode de ce type, qui permet de
comparer les deux nombres avec une marge d'erreur :

.. code-block:: C

  bool Equality(float a, float b, float epsilon)
  {
    return fabs(a - b) < epsilon;
  }

Ce code utilise la valeur absolue de la différence des nombres `a` et `b`
:index:`fabs` pour comparer ce résultat avec le delta.

Les tableaux
------------

Les tableaux permettent de représenter une *série* de donnée d'un même type.

Le texte
--------

Le texte est représenté par le type `char` qui peut stocker un caratère. C'est
pourquoi on utilise souvent des tableaux de caratères qui permettent de stocker
des mots.

Formatter du texte
~~~~~~~~~~~~~~~~~~

.. code-block:: C

   char str[80];
   sprintf(str, "Value of Pi = %f", M_PI);


Pour les nombres flottants, il faut d'abord convertir le nombre en texte :

.. code-block:: C

  char str_temp[6];

  /* 4 is mininum width, 2 is precision; float value is copied
     onto str_temp*/
  dtostrf(temp, 4, 2, str_temp);
  sprintf(temperature,"%s F", str_temp);