Il restait à relier physiquement les alarmes. J’avais plusieurs possibilités pour ça. Soit ajouter un composant sur la SPI (genre un mcp23s08) ou alors me contenter des GPIO du Pi. J’ai choisi la seconde en considérant que tout est déjà expliqué sur le tuto pour quelqu’un qui choisirait la première.
La mise en œuvre de ces alarmes physiques se résume à quelques lignes. La première chose à faire, c’est d’ajouter une valeur à chaque capteur pour indiquer quelle pin du gpio sera rattaché à son alarme et si on en veut pas, on met 0 (j’ai appelé cette variable GpioAlm)
- gpioalm.png (21.07 Kio) Vu 6740 fois
Ensuite, initialiser ces GPIO en sortie juste après la déclaration de l’objet analogAn dans le fichier index.js (l’idéal serait de le faire depuis le fichier de capteur.js ) et aussi penser à les libérer sans le SIGINT . Et pour finir tout simplement rajouter le pilotage des sorties dans l’évent d’alarme.
- indexgpioalm.png (30.59 Kio) Vu 6740 fois
Voilà, c’est fini. J’ai désormais un dataloguer quasi universel 8 pistes avec alarme programmable et serveur web d’application temps réel. Je pourrais lui apporter beaucoup d’amélioration comme des entrés logiques, un système de sauvegarde des données locale ou distant, une page web de configuration pour les capteurs et tout un tas d’autres chose …
Les codes :
index.js
Code : Tout sélectionner
// #region Declarations Web server
var express = require('express');
var ejs = require('ejs');
var basicauth = require('basic-auth-connect');
var app = express();
app.engine('html', ejs.renderFile);
app.set('views','./templates');
app.use(express.static('./'));
app.use('/public', express.static('./public/'));
app.use('/jquery', express.static('./node_modules/jquery/dist'));
app.use('/socket.io', express.static('./node_modules/socket.io-client/dist/'));
app.use(basicauth('bud', 'spencer'));
var httpserver = require('http').createServer(app);
var socket = require('socket.io').listen(httpserver);
// #endregion
// #region Declarations Digital/Analogic
var rpio = require("rpio");
rpio.init({ gpiomem: false, mapping: 'gpio' });
rpio.spiBegin();
var spi_io = require("./spi_io.js");
var sensor = require("./sensor.js");
var mcp3208 = new spi_io.MCP3208(rpio, 0, 512);
var sensorAn = new sensor.ANALOG("./sensor.json", mcp3208);
for (var i = 0; i < sensorAn.Channel.length; i++) {
console.log(i);
if (sensorAn.Channel[i].PinAlm !== 0) {
rpio.open(sensorAn.Channel[i].GpioAlm, rpio.OUTPUT, rpio.LOW);
}
};
// #endregion
// #region Routes
app.get('/console', function (req, res) {
res.render("console.html");
});
app.get('/manometre', function (req, res) {
res.render("manometre.html");
});
app.get('/graphique', function (req, res) {
res.render("graphique.html");
});
app.get('/sensorAn', function (req, res) {
res.json(sensorAn);
});
// #endregion
// #region socket.io
socket.sockets.on("connection", function (client) {
console.log("Client connected from " + client.request.connection.remoteAddress);
client.emit("sensorAn", { sensorAn : sensorAn });
});
// #endregion
// #region Sensor Events
sensorAn.Event.on('Result', function () {
var data = [];
for (var i = 0; i < sensorAn.Channel.length; i++) {
data[i] = sensorAn.Channel[i].Value;
}
socket.sockets.emit('sensorAn.value', { value: data });
});
sensorAn.Event.on('Alarme', function (channel) {
var c = sensorAn.Channel[channel];
if (c.GpioAlm !== 0) {
rpio.write(c.GpioAlm, c.Alarme ? rpio.HIGH : rpio.LOW);
}
});
// #endregio
process.on('SIGINT', function () {
rpio.spiEnd();
for (var i = 0; i < sensorAn.Channel.length; i++) {
if (sensorAn.Channel[i].GpioAlm !== 0) {
rpio.close(sensorAn.Channel[i].PinAlm);
}
}
process.exit();
});
var test = function () {
sensorAn.Read();
};
setInterval(test, 100);
httpserver.listen(8080);
spi_io
Code : Tout sélectionner
var Spi_IO = {
MCP3208: function (rpio, cs, clk) {
this.Cs = cs;
this.Clk = clk;
this.Resolution = 12;
var adcResult = function (reg) {
rpio.spiTransfer(reg, reg, reg.length);
return reg;
};
this.ReadAll = function () {
rpio.spiSetClockDivider(this.Clk);
rpio.spiChipSelect(this.Cs);
var x = [];
var b = [];
for (i = 0; i < 8; i++) {
b = adcResult(Buffer([(i >> 2) + 6, i << 6 & 0xFF, 0x00]));
x[i] = ((b[1] & 0x0F) << 8) + b[2];
}
return x;
};
this.ReadChannel = function (channel) {
rpio.spiSetClockDivider(this.Clk);
rpio.spiChipSelect(this.Cs);
var b = adcResult(Buffer([(channel >> 2) + 6, channel << 6 & 0xFF, 0x00]));
return ((b[1] & 0x0F) << 8) + b[2];
};
}
};
module.exports = Spi_IO;
sensor.json
Code : Tout sélectionner
{
"ANALOG": [
{
"Iden": 0,
"Name": "Voltmetre 0",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3,
"Valm": 5.0,
"GpioAlm": 0
},
{
"Iden": 1,
"Name": "Courant",
"Unite": "Amp",
"Vmin": -25.0,
"Vmax": 25.0,
"Dec": 1,
"Valm": 20.0,
"GpioAlm": 0
},
{
"Iden": 2,
"Name": "Tension",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 25,
"Dec": 3,
"Valm": 20.0,
"GpioAlm": 0
},
{
"Iden": 3,
"Name": "Température",
"Unite": "°C",
"Vmin": -40,
"Vmax": 125,
"Dec": 0,
"Valm": 80.0,
"GpioAlm": 18
},
{
"Iden": 4,
"Name": "Voltmetre 4",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3,
"Valm": 5.0,
"GpioAlm": 0
},
{
"Iden": 5,
"Name": "Voltmetre 5",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3,
"Valm": 5.0,
"GpioAlm": 0
},
{
"Iden": 6,
"Name": "Voltmetre 6",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3,
"Valm": 5.0,
"GpioAlm": 0
},
{
"Iden": 7,
"Name": "Voltmetre 7",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3,
"Valm": 20.0,
"GpioAlm": 0
}
]
}
sensor.js
Code : Tout sélectionner
var events = require('events');
var Sensor = {
ANALOG: function (sensorfile, adc) {
var ch = require(sensorfile).ANALOG;
var dmax = Math.pow(2, adc.Resolution) - 1;
var chEvent = new events.EventEmitter();
for (var i = 0; i < ch.length; i++) {
ch[i].Coef = (ch[i].Vmax - ch[i].Vmin) / dmax;
ch[i].Value = 0.0;
ch[i].Alarme = false;
}
this.Read = function () {
let v = adc.ReadAll();
for (var i = 0; i < ch.length; i++) {
let alarme = ch[i].Alarme;
ch[i].Value = (ch[i].Coef * v[i] + ch[i].Vmin).toFixed(ch[i].Dec);
ch[i].Alarme = ch[i].Value > ch[i].Valm;
if (alarme !== ch[i].Alarme) {
chEvent.emit("Alarme", i);
}
}
chEvent.emit("Result");
};
this.Channel = ch;
this.Event = chEvent;
}
};
module.exports = Sensor;