Communication i2c¶
Article qui indique comment exploiter la communication i2c avec divers appareils électroniques. On n'explore pas la science derrière ce protocole, mais plutôt son utilisation.
Introduction¶
À date, nous avons vu l'échange de données à partir du port série. Nous avons vu que le port série est un protocole de communication asynchrone. C'est-à-dire que les données sont envoyées les unes après les autres, sans synchronisation entre l'émetteur et le récepteur.
Il existe un autre protocole de communication qui est très utilisé dans les systèmes embarqués: le protocole i2c. Ce protocole est un protocole de communication synchrone. C'est-à-dire que les données sont transmises en utilisant une horloge commune (SCL) qui synchronise la communication entre l'émetteur et le récepteur.
On retrouve ce protocole sur les capteurs qui nécessitent la transmission ou la réception de données plus complexes. Par exemple :
- Horloge en temps réel
- Date, heure
- Configuration de celle-ci
- Capteur de température
- Accéléromètre
- Les données d'accélération sont souvent sur 3 axes
- Un accéléromètre vient parfois avec un gyroscope intégré qui a lui-même 3 axes
- Chaque axe est un capteur
- Anecdote : Les manettes de Wii fonctionnent avec le protocole i2c
Branchement¶
- Le i2c utilise 2 fils pour échanger de l'information
- SDA (Serial Data) : ligne de données
- SCL (Serial Clock) : ligne d'horloge
- Jetez un coup d'oeil à votre Arduino, vous devriez voir les pins SDA et SCL
- Sur Arduino Mega : SDA = pin 20, SCL = pin 21
- Sur Arduino Uno : SDA = pin A4, SCL = pin A5
- Le i2c fonctionne avec le principe de maître et d'esclave
- Le maître est celui qui contrôle le bus i2c (génère l'horloge)
- L'esclave est celui qui reçoit les commandes du maître

Question
Si le maître peut communiquer avec plusieurs composants, quelle méthode est utilisée pour savoir à qui il doit envoyer les données?
- Les appareils sont branchés en parallèle sur les fils SDA et SCL
- Voir l’illustration plus bas
- Chaque appareil possède une adresse qui lui est propre
- Souvent les manufacturiers de composants fournissent les adresses dans la documentation
- De plus dans le cercle Arduino, la plupart des composants ont des librairies

L'accéléromètre¶
- L'accéléromètre est un appareil dit "Centrale à inertie" (Inertial measurement unit, IMU).
- Dans le kit, il y a un accéléromètre à 6 dof (degree of freedom)
- Il s’agit du modèle MPU6050 (Google that! ;))
- Ce modèle a un accéléromètre sur 3 degrés, un gyroscope sur 3 degrés ainsi qu’un thermomètre
- Il est peu dispendieux soit quelques sous
- C'est aussi le modèle que l'on retrouvera dans le robot Makeblock Ranger

Utilité¶
- Un IMU permet de mesurer la vitesse, l’orientation, l’accélération, le déplacement et autres types de mouvement
- On peut le brancher avec un programme dans le PC pour voir les mouvements
- Sur le robot, il y aura un accéléromètre d’intégré
Question
Dans quel genre d’appareil que l’on peut retrouver un accéléromètre?
Fonctionnement¶
- L’accéléromètre permet d’obtenir les accélérations dans les 3 axes
- On peut imaginer une balle dans un cube 3d
- Lorsqu’il n’y a aucune accélération, par exemple en état d’apesanteur, les valeurs retournées seront de zéro sur tous les axes

- Si l’on donne un coup sur le côté de l’accéléromètre dans l’axe des X, ce dernier retournera une valeur sur cet axe

Question : Quelle sera la valeur de l’accéléromètre en Z si celui-ci est sur Terre et ne bouge pas?
Réponse
Sur Terre, on a une accélération constante de \(9.8 m/s^2\)

Utilisation¶
- Dans le cadre du cours, nous utiliserons la librairie "AdaFruit MPU6050"
- Téléchargez la librairie et ouvrez l'exemple "basic_readings"
- Cela va faciliter la suite des notes
Code - basic_readings¶
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 | |
Analyse du code de configuration¶
- L'accéléromètre retourne beaucoup de données
- Il est préférable d’utiliser la vitesse de transfert de
115200 baudpour le port série - Il faut créer un objet de type
Adafruit_MPU6050pour pouvoir utiliser l’appareil- Exemple :
Adafruit_MPU6050 mpu;
- Exemple :
- La fonction
begin()permet d’initialiser le mpu et retourne faux s’il y a un problème- Exemple :
if (!mpu.begin()) {…} - Important : Si AD0 a du voltage, l'adresse du mpu est 0x69, sinon c'est 0x68. Il faudra mettre l'adresse dans la méthode
begin(). Exemple :mpu.begin(0x69);
- Exemple :
- Il faut configurer la plage d’accélération avec la fonction
setAccelerometerRange- Exemple :
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
- Exemple :
- Il faut configurer la plage d’accélération avec la fonction
setGyroRange- Exemple :
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
- Exemple :
- Une petite valeur pour les plages rend l’IMU plus sensible
- Il faut configurer le filtre de données avec la fonction
setFilterBandwidth- Exemple:
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ); - Cette fonction permet de lisser les données pour avoir moins de bruit
- Exemple:
Analyse du code de la boucle¶
- Dans la boucle, on crée les objets pour garder dans la mémoire les résultats
- Le type
sensors_eventde la librairie permet de garder ces résultats- Exemple :
sensors_event_t a, g, temp; - Dans ce cas, a -> Accélération, g -> gyro, temp -> température
- Exemple :
- Pour obtenir les données, on utilise la méthode
getEventavec les paramètressensors_eventen référence- Exemple :
mpu.getEvent(&a, &g, &temp); - Paramètre 1 : acceleration, 2 : Gyroscope et 3: température
- Exemple :
- Pour utiliser les valeurs, celles-ci possèdent des propriétés qui leur sont propres
- Exemple accélération (en m/s²):
a.acceleration.x,a.acceleration.y,a.acceleration.z
- Exemple gyroscope (en rad/s):
g.gyro.x,g.gyro.y,g.gyro.z- Pour convertir en degrés/s :
valeur_rad_s * 180 / PI
- Exemple température (en °C):
temp.temperature
Gyroscope¶
- Si vous avez bien observé le code, il y a la mention d'un gyroscope
- Comme indiqué plus tôt, certains IMU possèdent un gyroscope intégré
- Le gyroscope permet de mesurer la vitesse de rotation angulaire
- Il est possible de mesurer la vitesse de rotation sur 3 axes (X, Y, Z)
- La vitesse est donnée en \(rad/s\) (radian par seconde)
- Ainsi si le gyroscope ne détecte pas de mouvement, les valeurs sont proches de zéro
- Si on fait pivoter le gyroscope, on aura des valeurs non-nulles pendant la rotation
Applications pratiques :
- Détection d'orientation et de mouvement
- Stabilisation d'image
- Contrôle de jeux vidéo (manettes)
- Navigation (drones, robots)
Note
Les robots sur deux roues ou encore les hoverboards utilisent entre autres un gyroscope pour garder l'équilibre.

L'écran OLED SSD 1306¶
- L'écran OLED SSD 1306 est un écran qui utilise la technologie OLED (Organic Light-Emitting Diode)
- Le modèle utilisé en classe communique avec le protocole i2c
- Il s'agit d'un écran monochrome avec une résolution de 128x64 pixels

Question
À partir de la photo, quel indice nous indique que l'appareil fonctionne avec le protocole i2c?
- Nous allons utiliser la librairie
Adafruit_SSD1306modifiée pour contrôler l'écran
Librairie Adafruit_SSD1306¶
Récupération de la bibliothèque¶
Pour récupérer la librairie, il faudra cloner mon projet sur github.
- Aller dans le dossier qui contient les librairies Arduino
- Généralement, il se retrouve dans
Documents/Arduino/libraries
- Généralement, il se retrouve dans
- Dans la barre d'adresse, taper
cmdet appuyer sur Entrée- Cela ouvrira une fenêtre de commande dans le dossier courant
- Cloner le dépôt de code avec la commande suivante
git clone https://github.com/nbourre/Adafruit_SSD1306.git- Vous pouvez copier l'adresse directement à partir de github
Si tout est bien configuré, vous devriez avoir un dossier Adafruit_SSD1306 dans le dossier libraries de votre Arduino. Vous pouvez maintenant utiliser la librairie.
Ouvrir un exemple¶
- Ouvrir l'IDE Arduino
- Dans le menu
Fichier, sélectionnerExemples - Dans le sous-menu
Adafruit SSD1306, sélectionnerssd1306_128x64_i2c - Téléverser l'exemple dans votre Arduino
S'assurer que les branchements sont corrects. Vous devriez voir du contenu qui s'affiche sur l'écran.
Code complet de l'exemple
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 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | |
Analyse du code¶
Malgré la longueur du code, il y a beaucoup de lignes très similaires.
Les inclusions¶
Pour utiliser l'écran, il faut inclure les librairies suivantes: Wire.h, Adafruit_GFX.h et Adafruit_SSD1306.h.
- La librairie
Wire.hest utilisée pour la communication i2c. - La librairie
Adafruit_GFX.hest utilisée pour dessiner sur l'écran. - La librairie
Adafruit_SSD1306.hest utilisée pour contrôler l'écran. - Note :
SPI.hn'est pas requis dans notre situation.
Variables et objets initialisés¶
- La variable
logo_bmpest un tableau d'unsigned charqui contient l'image d'une étoile. - La variable
displayest un objet de typeAdafruit_SSD1306qui permet de contrôler l'écran.
setup()¶
- On doit initialiser l'écran avec la fonction
display.begin- Le premier paramètre indique la source du voltage
- Le second l'adresse I2C
Fonctions importantes¶
Gestion de l'affichage¶
display.display(): Permet d'afficher ce qu'il y a dans le tampon d'affichagedisplay.clearDisplay(): Permet d'effacer le tampon d'affichage
Dessin¶
display.drawPixel(x, y, couleur): Permet de dessiner un pixel à la positionxetyavec la couleurcouleur- Les choix de couleur sont
SSD1306_WHITE,SSD1306_BLACKetSSD1306_INVERSE
- Les choix de couleur sont
display.drawLine(x0, y0, x1, y1, couleur): Permet de dessiner une ligne entre les pointsx0, y0etx1, y1avec la couleurcouleurdisplay.drawRect(x, y, largeur, hauteur, couleur): Permet de dessiner un rectangle à la positionxetyavec la largeurlargeuret la hauteurhauteuravec la couleurcouleurdisplay.fillRect(x, y, largeur, hauteur, couleur): Permet de dessiner un rectangle plein à la positionxetyavec la largeurlargeuret la hauteurhauteuravec la couleurcouleurdisplay.drawCircle(x, y, rayon, couleur): Permet de dessiner un cercle à la positionxetyavec le rayonrayonavec la couleurcouleurdisplay.fillCircle(x, y, rayon, couleur): Permet de dessiner un cercle plein à la positionxetyavec le rayonrayonavec la couleurcouleurdisplay.drawRoundRect(x, y, largeur, hauteur, rayon, couleur): Permet de dessiner un rectangle arrondi à la positionxetyavec la largeurlargeuret la hauteurhauteuravec le rayonrayonavec la couleurcouleurdisplay.fillRoundRect(x, y, largeur, hauteur, rayon, couleur): Permet de dessiner un rectangle arrondi plein à la positionxetyavec la largeurlargeuret la hauteurhauteuravec le rayonrayonavec la couleurcouleurdisplay.drawTriangle(x0, y0, x1, y1, x2, y2, couleur): Permet de dessiner un triangle à la positionx0, y0,x1, y1etx2, y2avec la couleurcouleurdisplay.fillTriangle(x0, y0, x1, y1, x2, y2, couleur): Permet de dessiner un triangle plein à la positionx0, y0,x1, y1etx2, y2avec la couleurcouleurdisplay.drawBitmap(x, y, bitmap, largeur, hauteur, couleur): Permet de dessiner un bitmap à la positionxetyavec la largeurlargeuret la hauteurhauteuravec la couleurcouleur- Le bitmap doit être un tableau d'
unsigned charouuint8_t
- Le bitmap doit être un tableau d'
Texte¶
display.setTextSize(taille): Permet de changer la taille du textedisplay.setTextColor(couleur): Permet de changer la couleur du textedisplay.setCursor(x, y): Permet de changer la position du curseurdisplay.println(texte): Permet d'écrire du texte à la position du curseurdisplay.cp437(true): Permet d'utiliser le jeu de caractèresCode Page 437avec le bugfix (Voir documentation de la fonction)display.write(caractère): Permet d'écrire un caractère à la position du curseurdisplay.startscroll(right|left)(début, fin): Permet de faire défiler le texte vers la droite ou gauchedébutetfinsont les positions de début et de fin du texte
display.startscrolldiag(right|left)(début, fin): Permet de faire défiler le texte en diagonale vers la droite ou gauchedisplay.stopscroll(): Permet d'arrêter le défilement du texte
Exercices¶
- Faites défiler votre nom à l'écran
- Tracez une maison dans l'écran
- Faites une lettre qui rebondit sur les bords de l'écran
- Chaque lettre a un format de 8x8
Exercices¶
- Téléchargez la librairie "AdaFruit MPU6050"
- Faites un montage qui teste le fonctionnement de l’accéléromètre
- Utilisez l’exemple « basic_readings » pour le test
- Téléversez l’exemple « plotter »
- Dans « Tools », ouvrez l’outils « Serial plotter »
- Essayez d’analyser et de comprendre les données affichées