Blynk + Node.js + Johnny-Five : piloter un mini kit Pan-Tilt PTZ SG90 sur Orange Pi avec un Arduino/Firmata • Domotique et objets connectés à faire soi-même

y8wlmhjhneoilwy2aydd-8706948

Dans le tutoriel précédent, nous avons vu comment remplacer le GPIO de l’Orange Pi par un Arduino (fonctionnant avec le firmware Firmata) puis comment réaliser un script en Javascript pour piloter une Led depuis un smartphone avec la librairie Blynk et Johnny-Five. Dans ce tutoriel, nous allons mettre en oeuvre une nouvelle méthode pour piloter un système articule PTZ à base de servomoteurs.

Rappel des épisodes précédents et présentation du projet

Nous avons déjà vu plusieurs méthodes pour piloter un système articulé Pan-Tilt à base de servomoteurs SG90 :

Dans ce nouveau tutoriel, nous allons utiliser un Arduino/Firmata qui servira à remplacer le GPIO de l’Orange Pi qui pêche par son manque de librairies abouties pour gérer le GPIO. Pour cela nous allons développer un script en Javascript qui sera exécuté par Node.js. Nous utiliserons la librairie Johnny-Five (tous les articles sur Johnny-Five) ainsi que la librairie Blynk pour Node.js. La librairie Blynk permettra de faire le lien entre l’application mobile, le serveur Blynk local (ou officiel) et le script Node.js. La librairie Johnny-Five sera utilisée pour piloter les servomoteurs des axes Pan et Tilt. Voici un petit schéma qui résume l’architecture du projet.

Un petit aperçu en vidéo

Matériel nécessaire

Suivez ce guide étape par étape pour le montage de votre kit Pan-Tilt PTZ.

No posts for this criteria.

Circuit

Installer le firmware Firmata sur un Arduino

Le firmware Firmata permet d’accéder à toutes les fonctionnalités de l’Arduino via le port série (à l’aide d’un câble USB). Connectez la carte à l’ordinateur et ouvrez l’IDE Arduino. Dans le menu des examples, vous trouverez un sous-menu nommé Firmata. Sélectionnez le firmware qui correspond à votre besoin. Le plus courant est d’utiliser le firmware Standard. Il existe également une version Plus qui permet de communiquer avec des périphériques par liaison série UART, USART ou SoftwareSerial. Téléversez simplement le firmware sur la carte. C’est prêt ! Pour personnaliser le firmware, lisez cet article.

vkmife3ex4ss2lnnnw1k-8005969

Installer Node.js sur Armbian ou Raspbian

Node.js est un moteur d’exécution (runtime) qui permet de faire fonctionner des scripts Javascript sur un ordinateur ou un mini-PC (Raspberry Pi, Orange Pi…). C’est un moteur multi-plateforme, c’est à dire que le code écrit sur un environnement pourra fonctionner à l’identique (à condition que les ressources matérielles existent également) sur un autre environnement. Node.js est disponible pour Windows, macOS, Linux (x86 et ARM).

Commencez par vérifier que Node.js n’est pas déjà installé sur votre distribution

# node -v && npm -v
v5.12.0
3.8.6

Si vous obtenez un message d’erreur, installez Node.js 4.x (suffisant) ainsi que Python et Build

curl -sL https://deb.nodesource.com/setup_4.x | sudo bash -
sudo apt-get install -y build-essential python-dev nodejs

Installation des plugins Node.js nécessaires : Blynk, Johnny-Five

Pour ce projet, nous aurons besoin d’installer les packages Blynk (pour Nodejs) et Johnny-Five. Exécutez cette commande pour les installer. La commande sudo est préférable sur les systèmes Unix. L’option -g permet d’installer glabalement les packages, permettant ainsi de les utiliser dans tous les scripts. Les dépendances nécessaires aux packages seront automatiquement installées en même temps (la magie npm).

npm install -g blynk-library johnny-five

Projet Blynk sur l’application mobile

Lancez Blynk sur votre smartphone ou tablette. Si vous disposez d’un serveur local, connectez vous à celui-ci en modifiant la source comme indiqué sur la copie d’écran ci-dessous.

gpy9vye6490lpvxsztc7-9313044

Ajoutez 2 sliders. Le premier V0 permettra de piloter le servo PAN. Le second V1 permettra de piloter le servo TILT. Pour les deux sliders, cochez Send values on release only si vous voulez que le servo se déplace uniquement lorsque le slider est relâché. Modifiez le niveau de sortie maximum à 180 (pour 180 degrés)

Vous pouvez également ajouter 4 boutons

  • V2 (Center) : repositionne les 2 axes au centre (90°, 90°)
  • V3 (Stop) : stop tous les mouvements en cours
  • V4 (Pan Sweep) : balayage horizontal
  • V5 (Tilt Sweep) : balayage Vertical

Voici le projet obtenu

Code Javascript du projet (Node.js)

Votre environnement doit être prêt avant de continuer. Connectez-vous à l’Orange Pi (ou au Raspberry Pi) en SSH (ou en direct). Créez un nouveau répertoire (nodebot) et placez vous à l’intérieur

cd ../..
mkdir nodebot && cd nodebot;

Créez un nouveau script javascript

nano j5PanTilt.js

En début de script, nous allons appeler les différents librairies nécessaires :

  • Blynk : blynk-library
  • Johnny-Five
  • Events : permet d’envoyer et de recevoir des événements.
var Blynk = require('blynk-library');
var five = require("johnny-five");
var EventEmitter = require('events').EventEmitter;

Ensuite, nous allons créer plusieurs objets :

  • board : c’est l’objet de base qui permet d’utiliser l’API Johnny-Five, par exemple pour commander les servos, allumer les Led…
  • event : cet objet permet d’émettre et de recevoir des événements Javascripts
  • blynk : permet d’utiliser l’API Blynk
  • connector : objet contenant la connexion HTTP au serveur Blynk local
  • Vx : objets permettant d’échanger des données avec le serveur Blynk
var board = new five.Board();                   // Objet permettant l'appel à l'API J5 - Object to call J5 API
var AUTH = 'b065eb0a6e36434da42367b3fa7c3340';  // Remplacer par votre Token Blynk - Replace by your Blynk Token

var event = new EventEmitter();                 // Evenements javascript - Javascript Events
var DEBUG = true; //false;                      // Active les messages de mise au point - Activate debug message

// Setup Blynk
var blynk = new Blynk.Blynk(AUTH, options = {
  // Connecteur au serveur Blynk local - Local Blynk server connector
  connector : new Blynk.TcpClient( options = { addr:"xxx.xxx.xxx.xxx", port:8442 } )
});
var V0 = new blynk.VirtualPin(0);  // Pan servo           
var V1 = new blynk.VirtualPin(1);  // Tilt servo
var V2 = new blynk.VirtualPin(2);  // Reset position

Il est très facile de surveiller l’état de la connexion au serveur Blynk à tout moment et “branchant” une fonction qui est déclenchée lorsqu’un événement est émis par l’objet. On peut par exemple surveiller que l’on est bien connecté (connect) au serveur, ou au contraire que l’on est déconnecté. On pourra par exemple réaliser un traitement en cas de déconnexion. Ici, nous allons simplement afficher un message lorsqu’on sera connecté au serveur, ou si le script est déconnecté.

blynk.on('connect', function() { console.log("Blynk ready."); });
blynk.on('disconnect', function() { console.log("DISCONNECT"); });

Il faut attendre que la communication avec la carte Arduino soit établie avant de pouvoir utiliser l’API de Johnny-Five. Pour cela, on va se brancher sur l’événement ready comme ceci. L’événement ready ne renvoi aucune information.

board.on("ready", function() {
  // code
  console.log("J5 Board is Ready");
})

Comment piloter un servomoteur avec Johnny-Five ?

Johnny-Five met à disposition deux classes pour piloter les servomoteurs :

  • servo : on pilote individuellement un servomoteur. La documentation complète se trouve ici
  • servos : on peut piloter simultanément deux servomoteurs. La documentation complète se trouve ici. Cette API est recommandée si vous voulez créer des mouvements parfaitement synchronisés de plusieurs servos. Toutes les méthodes de l’API servo sont disponibles !

L’API servo propose de nombreuses fonctions :

  • to(deg ms, rate) : déplace le servo à la position indiquée (deg). ms permet d’indiquer le temps pour réaliser le déplacement et rate le nombre de pas. Par exemple servo.to(90,500,10) déplacera le servo à l’angle 90° en 500ms en 10 pas.
  • min : déplace le servo à la position mini. Par défaut 0°. Il est possible de modifier la plage de déplacement possible du servo à l’initialisation. Par exemple 30° à 150°.
var servo = new five.Servo({
  pin: 10, 
  range: [ 30, 150 ]
});
  • max : idem mais au maximum. Par défaut 180°.
  • center : positionne le servo à la position centrale. Elle est calculée au centre de la plage. Par défaut 0 – 180°, le centre sera à 90°
  • home : renvoi le servo à la position définie par le paramètre startAt
var servo = new five.Servo({
  pin: 10,
  startAt: 20
});

// Set horn to 90 degrees
servo.to(90);

// Return to startAt value of 20 degrees
servo.home();
  • sweep : balayage alternatif entre la position min et max
  • sweep([ low, high ]) : balayage alternatif de la position low à la position high
  • sweep(options) : balayage avec options. range : [position début, position fin], interval : durée d’un demi-déplacement (ms), step : pas en degré
  • stop : arrête le mouvement en cours
  • cw(vitesse 0-1) : déplacement continue dans le sens horaire
  • ccw(vitesse 0-1) :  déplacement continue dans le sens anti-horaire

Préparation des fonctions de déplacement des servos Pan et Tilt

Nous allons en profiter pour tester quelques fonctions très rapidement grâce à Johnny-Five. On pourrait par exemple développer un petit système de caméra de surveillance qui ferait régulièrement un balayage horizontal. On va ajouter une fonction pour arrêter tous les mouvements en cours et une dernière pour renvoyer les axes Pan et Tilt à leur position centrale.

Dans la fonction board.on(“ready”), on va déjà attacher les 2 servos

 var pan = new five.Servo(PIN_PAN);
 var tilt = new five.Servo(PIN_TILT);

Puis on va brancher des traitements en écoutant des événements. Par exemple, l’événement PAN déclenchera le déplacement du servo Pan à la position passée en paramètre

event.on('PAN', function(position){
  if ( DEBUG ) { console.log("Move Pan servo to ", position); }
  pan.to(position);
});

event.on('PAN_SWEEP', function(position){
  if ( DEBUG ) { console.log("Move Pan servo to ", position); }
  pan.to(position);
});

Maintenant juste après la fonction board.on(“ready”), on va émettre un message dès qu’on reçoit un ordre de l’application Blynk. En Javascript, il suffit d’appeler l’objet event (créé au début du programme) et d’utiliser la méthode emit. La méthode emit prend deux paramètres. Le premier obligatoire est une chaine qui permet de nommer l’événement. Le second optionnel est un paramètre. Ca peut être une chaine, une valeur numérique, un booléen… ou un objet JSON. Ici, on va envoyer l’angle sous la forme d’un entier. Pour cela, on utilise la fonction parseInt pour convertir la chaine en entier.

V0.on('write', function(param){
  if ( DEBUG ) { console.log("V0 (Pan) ", param); }
  event.emit('PAN',parseInt(param) );
});

Code complet du projet

Collez le code suivant dans le fichier ouvert précédemment sans oublier de modifier l’adresse IP de votre serveur Blynk local et le Token du projet.

var Blynk = require('blynk-library');
var five = require("johnny-five");
var EventEmitter = require('events').EventEmitter;

var board = new five.Board();                   // Objet permettant l'appel à l'API J5 - Object to call J5 API
var AUTH = 'b065eb0a6e36434da42367b3fa7c3340';  // Remplacer par votre Token Blynk - Replace by your Blynk Token

var event = new EventEmitter();                 // Evenements javascript - Javascript Events
var DEBUG = true; //false;                      // Active les messages de mise au point - Activate debug message

var DEBUG = true; //false;
var PIN_PAN = 10;
var PIN_TILT = 9;

// Configure l'objet Blynk - Setup Blynk object
var blynk = new Blynk.Blynk(AUTH, options = {
  connector : new Blynk.TcpClient( options = { addr:"192.168.1.24", port:8442 } )
});

var V0 = new blynk.VirtualPin(0);  // Pan servo
var V1 = new blynk.VirtualPin(1);  // Tilt servo
var V2 = new blynk.VirtualPin(2);  // Retourne à la position centrale - Go to center position
var V3 = new blynk.VirtualPin(3);  // Stop tous les mouvements - Stop all movements
var V4 = new blynk.VirtualPin(4);  // Balayage horizontal - Pan sweep
var V5 = new blynk.VirtualPin(5);  // Balayage vertical - Tilt sweep

blynk.on('connect', function() { console.log("Blynk ready."); });
blynk.on('disconnect', function() { console.log("DISCONNECT"); });

board.on("ready", function() {
  console.log("Board J5 Ready ");
  var led = new five.Led(11);

  var pan = new five.Servo(PIN_PAN);
  var tilt = new five.Servo(PIN_TILT);

  function stopBlink(){
    led.stop();
    led.off();
  };

  event.on('PAN', function(position){
    if ( DEBUG ) { console.log("> Move Pan servo to ", position); led.blink();}
    pan.to(position);
    stopBlink();
  });

  event.on('PAN_SWEEP', function(position){
    if ( DEBUG ) { console.log("> Sweep Pan servo "); led.blink();}
    pan.sweep();
  });

  event.on('TILT', function(position){
    if ( DEBUG ) { console.log("> Move Tilt servo to ", position); led.blink();}
    tilt.to(position);
    stopBlink();
 });

  event.on('TILT_SWEEP', function(){
    if ( DEBUG ) { console.log("> Sweep Tilt servo "); led.blink();}
    tilt.sweep();
  });

  event.on('CENTER', function(position){
    if ( DEBUG ) { console.log("> Go Home Pan/Tilt servos"); led.blink();}
    pan.center();
    tilt.center();
    stopBlink();
  });

  event.on('STOP', function(){
    if ( DEBUG ) { console.log("> Stop All movements"); led.blink();}
    pan.stop();
    tilt.stop();
    stopBlink();
  });
});

V0.on('write', function(param){
  if ( DEBUG ) { console.log("V0 (Pan) ", param); }
  event.emit('PAN',parseInt(param) );
});

V1.on('write', function(param){
  if ( DEBUG ) { console.log("V1 (Tilt) ", param); }
  event.emit('TILT',parseInt(param) );
});

V2.on('write', function(param){
  if ( DEBUG ) { console.log("GO Home position "); }
  event.emit('CENTER');
});

V3.on('write', function(param){
  if ( DEBUG ) { console.log("STOP all movements"); }
  event.emit('STOP');
});

V4.on('write', function(param){
  if ( DEBUG ) { console.log("SWEEP Pan servo"); }
  event.emit('PAN_SWEEP');
});

V5.on('write', function(param){
  if ( DEBUG ) { console.log("SWEEP Tilt servo"); }
  event.emit('TILT_SWEEP');
});

Enregistrez le fichier avec CTRL + X puis Y. Lancez le script avec la commande node j5PanTilt.js , si vous avez activé le debug, vous pourrez suivre l’arrivée des commandes depuis le serveur Blynk; L’exécution de la commande est précédée d’un ‘>’.

# node j5PanTilt.js 
Connecting to TCP: 192.168.1.24 8442
Connected
1490105773157 Device(s) /dev/ttyUSB0  
1490105773264 Connected /dev/ttyUSB0  
Authorized
Blynk ready.
1490105774854 Repl Initialized  
>> Board J5 Ready 
V0 (Pan)  [ '99' ]
> Move Pan servo to  99
V0 (Pan)  [ '31' ]
> Move Pan servo to  31
SWEEP Pan servo
> Sweep Pan servo 

Une petite vidéo de démonstration pour conclure ce tutoriel.

Avez-vous aimé cet article ?