Un coeur qui bat

Pour contredire les films de science-fiction/horreur qui présentent trop souvent les robots comme des machines tueuses, notre premier composant robotique sera un coeur, que nous allons faire battre selon les émotions du robot. On va commencer par quelque chose de simple, et choisir les états émotionnels nous-mêmes à partir d'une interface HTML... réaliser un programme de réactions émotionnelles est quelque chose qui viendra plus tard!

Ce sera aussi l'occasion de montrer comment on peut faire communiquer le corps d'un robot avec une interface de contrôle et de commande réalisée par nous-même, en utilisant localement WebSocket.

Interface au coeur du robot

Lorsque vous cliquez sur "Robot is happy" (le robot est heureux) le voyant clignote en bleu. "Robot is angry" (le robot est fâché) le fait clignoter en rouge, et la troisième option en blanc.
En même temps s'affiche dans "Messages received" un message envoyé par le script qui fournit l'équivalent textuel de la commande reçue et l'action qu'il exécute.

Composants et logiciels

Il nous faut aussi installer un module JavaScript supplémentaire, socket.io:

npm install socket.io@"~0.8.1"

Il s'agit de la version 0.8 parce que la version 0.9 pose des problèmes en voulant installer gyp (que nous avons déjà installé pour Johnny-Five), avec une série de dépendences sans fin. A l'avenir nous essaierons de nous passer de socket.io, mais pour gagner du temps, procédons pour le moment avec une version antérieure qui fonctionne.

Nous utiliserons une feuille de carton dans laquelle nous découpons la forme d'un coeur. On imprime l'image ci-dessous sur une feuille de papier et on se sert de l'image du coeur pour découper la forme dans le carton. On collera ensuite la feuille de papier sur le carton et l'on placera le tout sur le robot, sur la LED qui représente son coeur.

Coeur de papier

Montage

LED RGB

  1. La broche la plus courte est reliée par une une résistance au port 9. Elle correspond à la couleur rouge.
  2. La broche la plus longue à sa gauche est reliée au sol.
  3. La broche à gauche de la broche la plus longue est reliée au port 10. Elle correspond à la couleur verte.
  4. La broche la plus à gauche est reliée au port 11 et correspond au bleu.
  5. On relie la planche de prototype à 5v et à Gnd sur l'Arduino.
Photo du montage LED RVB Photo du montage

Scripts

Tester le montage

On utilisera d'abord un script de test simple pour vérifier que notre montage fonctionne bien. Le script est fait à la fois pour Scriptol.com en anglais et Scriptol.fr, c'est pourquoi les variables et codes sont en anglais.

var j5 = require("johnny-five");

var mood="";

j5.Board().on("ready", function() {
  var myLed = new j5.Led.RGB([ 9, 10, 11 ]);
  
  // on rend la LED bleue pour une seconde et demie
  this.wait(500, function() {
    myLed.color("#00ff00");
  });
 
  // on rend la LED rouge pour une seconde
  this.wait(2000, function(){
    myLed.color("#ff0000");
  });  

  // on fait clignoter la couleur rouge pour l'émotion "angry" (fâché)
  mood = "angry";
  this.wait(3000, function(){
    var color; 
    switch(mood) {
      case "happy":
        color="#00ff00";
        break;
      case "angry":	
        color="#ff0000";
        break;
      default:	
        color="#ffffff";
    }	
    myLed.color(color);
    myLed.strobe(500);
  });

  // après 6 secondes on éteint tout
  this.wait(6000, function(){
    myLed.off();
  });

});

Vous pouvez essayer de changer le code et assigner "happy" ou "" à la variable mood (humeur en français).

Utiliser une interface de contrôle

Pour communiquer avec l'Arduino par l'interface HTML, on ouvre un navigateur et on entre l'URL suivante:

localhost:8100

D'abord on lance le script avec node:

node heart.js  

Puis on ouvre la page HTML.

Le script est plus long que le premier parce qu'il crée aussi un mini serveur local pour envoyer une page HTML au navigateur. Cette page communique ensuite avec le serveur qui envoie des signaux à l'Arduino. C'est une bonne façon de tester un montage et on reprendra le même principe dans les montages à venir.

var uri="/websocket.html"; // le nom de la page d'interface

var j5 = require("johnny-five");

var myLed;

// la LED clignote en bleu au départ
j5.Board().on("ready", function() {
  myLed = new j5.Led.RGB([ 9, 10, 11 ]);
  myLed.color("#ffffff");
  this.wait(2000, function() {
    myLed.color("#00ff00");
    myLed.strobe(1000);
  });
});

// on crée un serveur local
var fs = require('fs'),
    http = require('http'),
    socket = require("socket.io");

var page = fs.readFileSync(__dirname + uri);

function handler(request, response)
{
  response.write(page);   // on envoie la page au navigateur
  response.end(); 
}

var app = http.createServer(function(r, s){ handler(r,s); });
app.listen(8100);

var listener = socket.listen(app, { log: false });

console.log("Waiting...")

// c'est ici que le script interprète les commandes de l'interface HTML
// et lance les commandes à l'Arduino
function start(socket) 
{
  socket.emit('notification', 'Server online via websocket...');
  socket.on('data', function (data) {
    var message;
    var color;
    switch(data) 
    {
      case 'happy':
         message="robot happy";
         color="#003399";
         break;
      case 'angry':
         message="robot angry";
         color="#990000";
         break;
      default:
         message="no emotion";
         color="#ffffff";
         mood=''; 
    }
    listener.sockets.emit('notification', "Data received, " +message);
    
    myLed.color(color);
    myLed.strobe(1000);
    
  });    
}

listener.sockets.on('connection', function (socket) { start(socket);} );

La page HTML contient un formulaire pour choisir une émotion:

<form name="form1" method="post" action="">
<input type="button" value="Robot is happy" onClick="callserver('happy')">
<input type="button" value="Robot is angry" onClick="callserver('angry')">
<input type="button" value="No emotion" onClick="callserver('neutral')">
</form>

Et un script pour communiquer avec le robot:

var socket = io.connect();
function notification(content) {
  var x= document.getElementById("storage");
  x.innerHTML = content;
}

socket.on('notification', function(x) { 
  notification(x); 
});	

function callserver(mood) {
  socket.emit('data', mood);	
}	

Le fonctionnement de WebSocket avec un script local est expliqué dans l'article: Premiers pas avec WebSocket et Node.js.

Les fichiers sources sont contenus dans l'archive des codes sources.

Dépannage

La LED ne s'allume pas

Cela arrive souvent avec la LED RVB et ses pattes de longueurs différentes: il est difficile de relier le bon fil à la bonne patte! Vous devez avoir de gauche à droite trois broches de taille croissantes, puis une plus petite qui correspond à la couleur rouge. La plus longue juste avant doit être reliée au sol.

Les couleurs de correspondent pas

Cela peut être un échange de fils ou un problème logiciel: les codes de couleurs ont été intervertis. Le rouge est donné par les deux premiers chiffres hexadécimaux (FF = 255), le bleu par les deux suivants (ce n'est pas usuel) et le vert par les deux derniers.

Etendre le montage

Vous pouvez ajouter plus d'émotion. Par exemple "très heureux" ou "très fâché". Pour ce faire vous ajouterez deux options au formulaire, et ferez battre le coeur plus vite pour les nouvelles émotions en donnant la valeur de 500 à la méthode strobe...

Par la suite on pourra envisager de représenter toutes les émotions de la roue de Plutchik!