Au lieu d'utiliser le langage natif d'arduino, on installe un programme 'firmata' qui permet de dialoguer avec un programme en javascript tournant sur un PC.
Johnny-five propose deux modes d'utilisation:
En interractif: REPL :Read - Eval - Print - Loop. C'est l'équivalent d'un interpréteur de commande.
(voir exemple dans mon post cité plus haut).
Soit en mode autonome: Le programme se déroule sur le PC et envoie ses instructions sur l'arduino.
Maintenant comment piloter son arduino depuis Internet, son smartphone , un site WEB .. ?
Le montage était destiné à piloter un laser pour distraire un chat (et moi par la même occasion)
Nous devons introduire un dialogue supplémentaire entre le PC et le robot. Ce dialogue utilisera le protocole MQTT: Le protocole des 'choses' reliées à Internet.( MQ Telemetry Transport)
MQTT is a machine-to-machine (M2M)/"Internet of Things" connectivity protocol.
Une série de slide ici sur MQTT.
Ce protocole est très léger et il connu par la plupart des objets connectés. Et son domaine d'utilisation s'est élargie au transport de message pour les Tchats.
Pour mémoire, Facebook utilise MQTT pour sa messagerie instantanée (ici un lien sur l'histoire de MQTT)
Pour le mettre en place , il faut disposer d'un serveur MQTT et des clients.
Pour le serveur, mon choix s'est porté sur MOSCA. C'est un serveur MQTT en javascript propulsé par le réacteur Node.js
Lien ici.
Mosca vous permet de construire votre propre serveur MQTT.
Mon code pour le serveur est le suivant:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var mosca = require('mosca') | |
var ascoltatore = { | |
//using ascoltatore | |
type: 'mongo', | |
url: 'mongodb://localhost:27017/mqtt', | |
pubsubCollection: 'ascoltatori', | |
mongo: {} | |
}; | |
var moscaSettings = { | |
port: 1883, | |
backend: ascoltatore, | |
persistence: { | |
factory: mosca.persistence.Mongo, | |
url: 'mongodb://localhost:27017/mqtt' | |
} | |
}; | |
var server = new mosca.Server(moscaSettings); | |
server.on('ready', setup); | |
server.on('clientConnected', function(client) { | |
console.log('client connected', client.id); | |
}); | |
// fired when a message is received | |
server.on('published', function(packet, client) { | |
console.log('Published', packet.payload); | |
}); | |
// fired when the mqtt server is ready | |
function setup() { | |
console.log('Mosca server is up and running') | |
} |
Le serveur se teste facilement avec un outil en ligne de commande: mosquitto
(MQTT est protocole de type : PubSub : publier , souscrire)
mosquitto_sub -t 'hello/you'
mosquitto_pub -m "c est moi" -t 'hello/you'
Le schéma général est le suivant:
![]() |
réalisé avec http://shaky.github.bushong.net/ |
La partie web est en mode REST
Trois motifs sont utilisés pour décoder es URL , un pour l'axe des X , un pour l'axe des Y, le dernier pour allumer ou éteindre le laser.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mqtt = require 'mqtt' | |
mosca_host = 'localhost' | |
mosca_port = '1883' | |
client_settings = | |
keepalive: 1000 | |
protocolId: 'MQIsdp' | |
protocolVersion: 3 | |
clientId: 'client-2' | |
express = require 'express' | |
routes = require './routes' | |
http = require 'http' | |
app = express() | |
client = mqtt.createClient(mosca_port, mosca_host, client_settings); | |
myMiddleware = (req, res, next) -> | |
if (req.method == 'GET') | |
console.log "hi , I am here" | |
## keep executing the router middleware | |
next() | |
app.configure -> | |
app.set 'port', process.env.PORT || 3000 | |
app.set 'views', __dirname + '/views' | |
app.set 'view engine', 'ejs' | |
app.use express.favicon() | |
app.use express.logger 'dev' | |
app.use express.bodyParser(uploadDir : "./") | |
app.use express.methodOverride() | |
app.use app.router | |
app.use myMiddleware | |
app.use express.static(__dirname + '/public') | |
app.get '/', routes.index | |
app.get '/y/:nb' , (req,res) -> | |
nb = req.params.nb | |
console.log nb | |
client.publish 'laser/cat',"axey:#{nb}" | |
res.send 'ok' | |
app.get '/x/:nb' , (req,res) -> | |
nb = req.params.nb | |
console.log nb | |
client.publish 'laser/cat',"axex:#{nb}" | |
res.send 'ok' | |
app.get '/laser/:nb' , (req,res) -> | |
nb = req.params.nb | |
console.log nb | |
client.publish 'laser/cat',"laser:#{nb}" | |
res.send 'ok' | |
server = http.createServer(app) | |
server.listen app.get('port'),() -> | |
console.log "Express server listening on port " + app.get('port') |
La parie contrôle d'arduino est de la forme:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
five = require "johnny-five" | |
mqtt = require 'mqtt' | |
mosca_host = 'localhost' | |
mosca_port = '1883' | |
client_settings = | |
keepalive: 1000 | |
protocolId: 'MQIsdp' | |
protocolVersion: 3 | |
clientId: 'client-ard' | |
board = new five.Board() | |
client = mqtt.createClient mosca_port, mosca_host, client_settings | |
reg = /(\w+):(\d+)/ | |
tab = reg.exec("vertical:123"); | |
board.on "ready", ()-> | |
myServoX = new five.Servo 9 | |
myServoY = new five.Servo(pin: 8 , range: [ 70, 115 ]) | |
myLed = new five.Led 7 | |
# board.repl.inject servo: myServoX | |
# board.repl.inject servo: myServoY | |
# servo = | |
# servoX: myServoX | |
# servoY: myServoY | |
# led : myLed | |
client.subscribe 'laser/cat' | |
client.on 'message', (topic, message) -> | |
console.log 'received', topic, message | |
console.log( typeof message) | |
tab = reg.exec(message) | |
ordre = tab[1] | |
too = tab[2] | |
console.log ordre | |
console.log too | |
if ordre == "axex" | |
myServoX.to(too) | |
if ordre == "axey" | |
myServoY.to(too) | |
if ordre == "laser" | |
if too == '1' | |
myLed.on() | |
else | |
myLed.off() | |
console.log( typeof too) | |
# myLed.off() | |
myServoY.to(too) | |
# board.repl.inject servo | |
myLed.on() | |
myServoY.center() | |
myServoX.center() | |
Bonne fête les chats.