Cette conférence présente le framework Johnny-Five qui permet de programmer des cartes embarquées à l'aide d'un module Node.js. Après un tour rapide du JavaScript et de son fonctionnement, en particulier la programmation fonctionnelle et l'exécution pilotée par les évènements, la présentation décrit Node.js et aborde rapidement son fonctionnement. La troisième partie présente Johnny-Five et plusieurs exemples simples de contrôle d'une LED et de l'utilisation des entrées/sorties numériques et analogiques.
2. Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons
Attribution – Pas d’Utilisation Commerciale – Pas de Modification 4.0 International.
3. Contexte
Programmation de cartes embarquées
Arduino, BeagleBone Black, RaspberryPi...
Utilisation d’une librairie commune à toutes les cartes
JavaScript/Node.js à l’aide de la librairie Johnny-Five
Développement de robots ou d’objets connectés
Connaissances de la Robotics et de l’Internet of Things (IoT)
3
4. Différentes cartes
Processeur simple, performant ou spécialisé
Micro-contrôleur, processeur ARM, GPU, RTU...
Quantité de mémoire disponible
Mémoire centrale (RAM) et disque de stockage (SD-Card...)
Connectivité avec le monde extérieur
Port USB, connexion Ethernet, WiFi, Bluetooth...
4
6. HTML
Description d’un document à l’aide de l’HTML
HyperText Markup Language, dernière version 5.0 en 2014
Langage de description à balisage permettant des liens
Délimitation de portions de documents à l’aide de balises
Plusieurs autres roles
Information sémantique par rapport au contenu
Information de mise en forme du contenu
Inclusion de ressources multimédia (image, formulaire...)
6
7. Document HTML
L’élément racine d’un document HTML est html
Méta-informations sur le document dans l’élément head
Contenu du document dans l’élément body
1 <! DOCTYPE html >
2
3 <html >
4 <head >
5 <title >Programmer un robot </ title >
6 </head >
7
8 <body >
9 <p>Un seul tuyau : Johnny -Five !</p>
10 </body >
11 </html >
7
8. JavaScript (JS)
Langage de script de haut niveau, non typé et interprété
Le JavaScript est exécuté côté client, par le browser
Langage orientée objet à prototype
Bref historique des différentes versions
Créé en 1995 par Brendan Eich (pour le compte de Netscape)
Adoption d’un standard ECMAScript en juin 1997
Troisième version d’ECMAScript en 1999 (JavaScript 1.5)
8
9. Lien avec HTML
Deux manières d’attacher du code JavaScript
Avec l’élément script
Dans un fichier séparé, avec l’extension .js
Code depuis des fichiers externes avec l’élément script
<script src="myscript.js" type="text/javascript"></script>
Exécution du code au moment du chargement
Peut agit sur le contenu HTML déjà chargé
9
10. Affichage
Programme qui affiche un message de bienvenue
Code exécuté au moment où celui-ci est chargé par le navigateur
Inclusion du script à l’endroit où on souhaite l’exécuter
1 window.alert(’Hello Marcin!’);
1 <p>Bienvenue sur ce site !</p>
2
3 <script src="helloworld.js" type="text/javascript" ></script >
10
11. Affichage
Programme qui affiche un message de bienvenue
Code exécuté au moment où celui-ci est chargé par le navigateur
Inclusion du script à l’endroit où on souhaite l’exécuter
1 window.alert(’Hello Marcin!’);
1 <p>Bienvenue sur ce site !</p>
2
3 <script src="helloworld.js" type="text/javascript" ></script >
10
12. Variable et opérations
Déclaration d’une variable avec le mot réservé var
Les variables possèdent un type dynamique
Données de type nombre entier, flottant, booléen...
Une variable peut changer de type en cours d’exécution
1 var max = 20;
2 var score = 7.5;
3 var succeeded = score >= 10;
4 var mean = score / max * 100;
5
6 window.alert(succeeded); // Affiche false
7 window.alert(’Moyenne de ’ + mean); // Affiche Moyenne de 37.5
11
13. Instruction if-else
Exécution conditionnelle de blocs avec if-else
Un bloc de code est délimité avec des accolades
Bloc else optionnel si pas de cas alternatif
1 var max = 20;
2 var score = 7.5;
3 var succeeded = score >= 10;
4 var mean = score / max * 100;
5
6 if (succeeded) {
7 window.alert(’Réussi avec une moyenne de ’ + mean + ’%’);
8 } else {
9 window.alert(’Dommage , raté :-(’);
10 }
12
14. Instruction if-else/else if
Représentation de plusieurs alternatives avec if-else/else if
Plusieurs cas d’exécution possibles et exclusifs
1 var max = 20;
2 var score = 7.5;
3 var mean = score / max * 100;
4
5 if (score >= 10) {
6 window.alert(’Réussi avec une moyenne de ’ + mean + ’%’);
7 } else if (score >= 8) {
8 window.alert(’Oh zut , pas loin !’);
9 } else {
10 window.alert(’Dommage , raté :-(’);
11 }
13
15. Instruction switch
Exécution conditionnelle de blocs avec switch
Saut du flux d’exécution en fonction d’une valeur
Sortie de l’instruction switch avec l’instruction break
Cas par défaut représenté avec default
1 var trafficlight = ’red’;
2
3 switch ( trafficlight ) {
4 case ’red ’:
5 window.alert(’Passez pas !’);
6 break;
7
8 case ’orange ’:
9 window.alert(’Prudence !’)
10 break;
11
12 case ’green ’:
13 window.alert(’On y va !’)
14 break;
15
16 default :
17 window.alert(’Euh ... erreur !’)
18 }
14
16. Valeur undefined
Une variable uniquement déclarée possède la valeur undefined
Possible de faire un test pour savoir si elle a une valeur
Opérations avec undefined provoque une erreur
Notamment pour les opérations arithmétiques
1 var total;
2
3 if (total == undefined ) {
4 window.alert(’Variable total non définie !’);
5 } else {
6 window.alert(’Le total est de ’ + total);
7 }
15
17. Égalités de valeur
JavaScript est un langage non typé statiquement
Chaque variable possède un type dynamique
Comparaison des valeurs et/ou des types des données
Utilisation des opérateurs == et ===
Affichage du type d’une variable avec typeof
1 var a = 42;
2 var b = "42";
3
4 window.alert(typeof(a)); // Affiche number
5 window.alert(typeof(b)); // Affiche string
6
7 window.alert(a == b); // Affiche true
8 window.alert(a === b); // Affiche false
16
18. Modification de la page (1)
On peut accéder aux éléments de la page pour les modifier
Avec la fonction document.getElementById
On modifie ensuite le contenu avec la propriété innerHTML
1 <p>Bienvenue sur ce site !</p><p id="result" ></p>
1 var max = 20;
2 var score = 7.5;
3 var succeeded = score >= 10;
4 var mean = score / max * 100;
5
6 var p = document . getElementById (’result ’);
7 if (succeeded) {
8 p.innerHTML = ’Réussi avec une moyenne de ’ + mean + ’%’;
9 } else {
10 p.innerHTML = ’Dommage , raté :-(’;
11 }
17
19. Modification de la page (1)
On peut accéder aux éléments de la page pour les modifier
Avec la fonction document.getElementById
On modifie ensuite le contenu avec la propriété innerHTML
1 <p>Bienvenue sur ce site !</p><p id="result" ></p>
1 var max = 20;
2 var score = 7.5;
3 var succeeded = score >= 10;
4 var mean = score / max * 100;
5
6 var p = document . getElementById (’result ’);
7 if (succeeded) {
8 p.innerHTML = ’Réussi avec une moyenne de ’ + mean + ’%’;
9 } else {
10 p.innerHTML = ’Dommage , raté :-(’;
11 }
17
20. Modification de la page (2)
On peut modifier les éléments de la page
Propriétés et fonctions d’accès aux éléments du document
1 <p id="intro">Bienvenue sur ce site !</p>
1 var p = document . getElementById (’intro ’);
2 p.style.fontSize = ’35’;
3 p.style.fontFamily = ’Arial ’;
4 p.style.color = ’#ff00ff ’;
18
21. Modification de la page (2)
On peut modifier les éléments de la page
Propriétés et fonctions d’accès aux éléments du document
1 <p id="intro">Bienvenue sur ce site !</p>
1 var p = document . getElementById (’intro ’);
2 p.style.fontSize = ’35’;
3 p.style.fontFamily = ’Arial ’;
4 p.style.color = ’#ff00ff ’;
18
22. Instruction while
Répéter un bloc tant qu’une condition est vraie avec while
Attention aux boucles infinies si la condition est toujours vraie
Construction du résultat avec une chaine de caractères
Génération de contenu HTML depuis le JavaScript
1 var result = ’’;
2 var i = 1;
3
4 while (i <= 10) {
5 result += i + ’ x 2 = <b>’ + (i * 2) + ’</b><br />’;
6 i += 1;
7 }
8 document . getElementById (’result ’).innerHTML = result;
19
23. Instruction while
Répéter un bloc tant qu’une condition est vraie avec while
Attention aux boucles infinies si la condition est toujours vraie
Construction du résultat avec une chaine de caractères
Génération de contenu HTML depuis le JavaScript
1 var result = ’’;
2 var i = 1;
3
4 while (i <= 10) {
5 result += i + ’ x 2 = <b>’ + (i * 2) + ’</b><br />’;
6 i += 1;
7 }
8 document . getElementById (’result ’).innerHTML = result;
19
24. Instruction for
Répéter un bloc un certain nombre de fois avec for
Attention aux boucles infinies si la condition est toujours vraie
Équivalence entre boucle while et for
1 var result = ’’;
2
3 for (var i = 1; i <= 10; i++) {
4 result += i + ’ x 2 = <b>’ + (i * 2) + ’</b><br />’;
5 }
6 document . getElementById (’result ’).innerHTML = result;
20
25. Fonction
Une fonction rassemble une séquence d’instructions
Reçoit un nom, une liste de paramètres et renvoie une valeur
Une fonction est stockée dans une variable
Deux façons différentes de déclarer une fonction
1 function add(a, b) {
2 return a + b;
3 }
4
5 var sub = function (a, b) {
6 return a + b;
7 }
8
9 window.alert(add (40, 2));
10 window.alert(sub(2, 40));
21
26. Programmation fonctionnelle (1)
Une fonction peut recevoir une fonction en paramètre
Cette fonction peut ensuite être appelée (callback)
Déclaration préalable de la fonction ou fonction anonyme
Fonction déclarée sans l’avoir nommée
1 function compute(a, b, f) {
2 f(a + b);
3 }
4
5 var show = function (value) {
6 window.alert(’Valeur : ’ + value);
7 }
8
9 compute (40, 2, show);
22
27. Programmation fonctionnelle (2)
Une fonction peut recevoir une fonction en paramètre
Cette fonction peut ensuite être appelée (callback)
Déclaration préalable de la fonction ou fonction anonyme
Fonction déclarée sans l’avoir nommée
1 function compute(a, b, f) {
2 f(a + b);
3 }
4
5 compute (40, 2, function (value) {
6 window.alert(’Valeur : ’ + value);
7 });
23
28. Portée des variables
Portée d’une variable en fonction de son endroit de déclaration
Une variable déclarée dans une fonction est locale
Variable globale déclarée en dehors de toute fonction
Variable sans déclaration automatiquement globale
1 function init () {
2 var x = 12;
3 s = ’Hello ’;
4 }
5
6 init ();
7 window.alert(s); // Hello
8 window.alert(x); // Uncaught ReferenceError : x is not defined
24
29. Réaction à un évènement
Association d’une action à un élément (une fonction)
Par exemple, l’évènement onclick
1 <a id="dontclick">Ne me cliquez pas !</p>
1 var cnt = 0;
2 link = document . getElementById (’dontclick ’);
3 link.onclick = function () {
4 cnt += 1;
5 window.alert("Pas cliquer que c’était mis ... (déjà " + cnt + "
clics)");
6 }
25
30. Réaction à un évènement
Association d’une action à un élément (une fonction)
Par exemple, l’évènement onclick
1 <a id="dontclick">Ne me cliquez pas !</p>
1 var cnt = 0;
2 link = document . getElementById (’dontclick ’);
3 link.onclick = function () {
4 cnt += 1;
5 window.alert("Pas cliquer que c’était mis ... (déjà " + cnt + "
clics)");
6 }
25
31. Types d’évènement
Évènements liés aux éléments de la page ou au browser
Les évènements sont traités séquentiellement
Évènement Description
onchange Changement d’un élément HTML
onclick Clic sur un élément HTML
oncontextmenu Un clic droit a été fait sur un élément HTML
onmouseover La souris rentre sur un élément HTML
onmouseout La souris sort d’un élément HTML
onkeydown Une touche du clavier a été enfoncée
onsubmit Un formulaire est en train d’être soumis
oncopy Le contenu d’un élément a été copié dans le presse-papier
26
32. JavaScript Object Notation (JSON) (1)
Permet de représenter des objets
Notation issue de la notation des objets Javascript
Ensemble de paires (étiquette, valeur)
Étiquette entre guillemets, deux-points et valeur
Valeurs sont soit une simple valeur, soit une liste de valeurs
Liste de valeurs délimitée par des crochets []
27
34. Objet
Un objet est caractérisé par deux éléments
Un objet possède des propriétés
On peut appeler des méthodes d’un objet
Définition d’un nouvel objet comme un document JSON
1 var person = {
2 firstname: ’Sébastien ’,
3 lastname: ’Combéfis ’,
4 getname: function () {
5 return this.firstname + ’ ’ + this.lastname;
6 }
7 };
8
9 window.alert(person.firstname);
10 window.alert(person[’firstname ’]);
11 window.alert(person.getname ());
29
35. Types de donnée
Plusieurs types de données existants en JavaScript
Types dynamiques pouvant changer pour une même variable
1 var size = 12; // number
2 var price = 28.5; // number
3 var flag = false; // boolean
4 var sentence = ’Coucou ’; // string
5
6 var data = [12, 9, 4.5, 0]; // object
7
8 var person = { // object
9 firstname: ’Sébastien ’,
10 lastname: ’Combéfis ’
11 };
12
13 var sayhello = function () { // function
14 window.alert(’Hello World!’);
15 }
30
36. Mode strict
Exécution du code en mode strict avec ’use strict’;
Par exemple, pas d’utilisation de variables non déclarée
Directive peut être utilisée uniquement au sein d’une fonction
Limitation de la portée de la vérification
1 ’use strict ’;
2
3 x = 11;
4 window.alert(x);
Uncaught ReferenceError : result is not defined(anonymous function
) @ test.htm :8
31
38. Framework Node.js
Environnement d’exécution du JavaScript
Basé sur le moteur JavaScript V8 de Chrome
Orienté évènement et avec entrées-sorties non bloquantes
Moteur léger et efficace
Accompagné du gestionnaire de librairies npm
Plus gros écosystème de librairies open-source au monde
33
39. Fonctionnalités
Asynchrone (non bloquant) et dirigé par les évènements
L’appel d’une API n’attend jamais son résultat
Exécution très rapide des programmes
Grâce à l’utilisation du moteur V8 de Chrome
Unique thread d’exécution pour gérer tous les évènements
Contrairement à un serveur classique multi-threadé
Aucune utilisation de buffers pour les données
Les données sont générées par blocs
34
40. Hello World ! (1)
Affichage à l’écran à l’aide de l’objet console
Utilisation de la fonction log
Exécution d’un fichier JS à l’aide de la commande node
1 console .log(’Hello World!’)
$ node helloworld.js
Hello World!
35
41. Structure
Application Node.js constituée de trois parties principales
Importation de modules avec require
Création du serveur qui écoute les requêtes des clients
Lecture des requêtes et envoi des réponses
Gestionnaire de requêtes représenté par une fonction
Reçoit une request et génère une response
36
42. Hello World ! (2)
Création d’un serveur HTTP à l’aide du module http
Appel de la fonction createServer
Génération de la réponse en plusieurs parties
Entête avec writeHead et corps avec end
1 var http = require (’http ’);
2
3 var server = http. createServer ( function (request , response) {
4 response.writeHead(’200’, {
5 ’Content -Type ’: ’text/plain ’
6 });
7 response.end(’Hello World !n’);
8 });
9 server.listen (8080);
10
11 console .log(’Server running at http ://127.0.0.1:8080 ’)
37
43. Environnement REPL
Node.js offre un environnement Read Eval Print Loop (REPL)
Mode interactif comme dans une console
Plusieurs étapes dans un cycle
Read lit et parse ce que l’utilisateur a tapé
Eval prend et évalue la structure de données
Print affiche le résultat
Loop boucle et recommence
$ node
> x = 10
10
> console.log(x)
10
undefined
38
45. Hello LED (1)
LED rouge reliée à l’entrée digitale numéro 13
Clignotement avec une période de 100ms
40
46. Hello LED (2)
Création de la board avec l’objet five.Board
Possibilité de fournir des paramètres pour configurer la carte
Ajout d’un gestionnaire évènement avec la fonction on
Nom de l’évènement et fonction de gestion en paramètres
1 var five = require ("johnny -five"),
2 board = new five.Board ();
3
4 board.on("ready", function () {
5 var led = new five.Led (13);
6
7 led.strobe ();
8 });
41
47. BeagleBone Hello LED
Configuration de la carte pour mode BeagleBone
Via une option en construisant l’objet Board
Attention à la façon de nommer les pins qui dépend des cartes
Différentes méthodes disponibles pour les LEDs
1 var five = require ("johnny -five");
2 var BeagleBone = require ("beaglebone -io");
3 var board = new five.Board ({
4 io: new BeagleBone ()
5 });
6
7 board.on("ready", function () {
8 var led = new five.Led(’P9_14 ’);
9
10 led.blink (500);
11 });
42
48. Entrée/Sortie numérique
Pin GPIO de type numérique prend deux valeurs possibles
En alternant la tension entre 0V et 3.3V
Représentation d’une pin avec un objet Pin
Il faut spécifier le numéro de la pin à utiliser
Utilisation de fonctions pour agir sur les pins
Fonction write permet d’écrire dans la pin
1 board.on("ready", function () {
2 var pin = new five.Pin (13);
3 pin.write (1);
4 });
43
49. Exécution asynchrone
Un appel d’une fonction retourne directement
Callback pour exécuter du code après l’exécution d’une fonction
Interrogation de la valeur d’une pin avec query
Callback appelé lorsque la valeur est disponible
1 board.on("ready", function () {
2 var pin = new five.Pin (13);
3
4 pin.high ();
5
6 this.wait (1000 , function () {
7 pin.query( function (state) {
8 if (state.state == 1) {
9 pin.low ();
10 }
11 });
12 })
13 });
44
50. Sortie analogique
Pin PWM de type analogique prend une valeur entière
Une valeur comprise entre 0V et 3.3V
Représentation d’une pin avec un objet Pin
Il faut spécifier le numéro de la pin à utiliser
1 board.on("ready", function () {
2 var led = new five.Led (11);
3
4 led.on();
5 led.fade(0, 2000);
6 });
45
51. Fonction de haut niveau
Fonction au niveau de la carte (objet Board)
Configuration et utilisation directe des pins
1 board.on("ready", function () {
2 this.pinMode (13, five.Pin.OUTPUT);
3
4 this. digitalWrite (13, 1);
5
6 this.wait (10000 , function () {
7 this. digitalWrite (13, 0);
8 });
9 });
46
53. Exemple avancé (2)
Utilisation de l’objet Sensor
Évènement de type data lorsque la valeur change
1 var five = require ("johnny -five"),
2 board = new five.Board ();
3
4 board.on("ready", function () {
5 var slider = new five.Sensor("A0");
6 var led = new five.Led (11);
7
8 slider.scale ([0, 255]).on("data", function () {
9 led.brightness(this.value);
10 });
11 });
48