Bon, on va déjà commencer par les petits méa-culpa pour le code précèdent. Comme je vous l’ais dit, c’est un projet en live et meme si c’est fonctionnel, ça n’évite pas les petites erreurs que l’on ne voit qu’a la relecture.
Dans le code du fichier spi_io.
js, vous pouvez supprimer la ligne 5 qui déclare une variable
_rpio qui ne sert à rien. Vous pouvez aussi modifier la ligne 29 (
b = adcResult… ) en ajoutant var devant (
var b = adcResult …). Ce sont des petits détails, mais c’est justement ce genre de petits détails qui vous pourrissent un programme.
Bien, on sait maintenant discuter avec un convertisseur analogique/digitale sur une liaison SPI. Pour l’instant on n’a que des valeurs numériques qui n’ont pas vraiment de sens par rapport au monde extérieur. On va donc transformer tout ça en capteurs paramétrables.
Si je résume un capteur de base il a déjà un minimum de propriétés. Déjà je peux lui donner un nom ne serait-ce que pour l’identifier par rapport à d’autres. Ensuite il a une unité de mesure. Ça peut être des Volts, des °C, des PSI, des kilogrammes …. Il a aussi une plage de mesure, donc une valeur minimum et une valeur maximum. Par principe je vais aussi lui donner un id unique ce qui pourra servir ultérieurement. Pour faciliter la lecture, je peux aussi définir le nombre de décimal que je veux afficher pour le capteur.
Dans l’absolu, je n’ai pas encore de capteur, mais les lignes d’entrés analogiques savent déjà mesurer des tensions de 0 et 5 volts. Donc je peux déjà définir mes capteurs de base comme étant des voltmètres mesurant cette plage de valeur.
Ecrit au format JSON le capteur 0 peut ressembler à ca :
{"Iden": 0, "Name": "Voltmètre 0","Unite": "Volt","Vmin": 0.0, "Vmax": 5.0, "Dec" :3 }
Je vais donc créer un fichier de paramètre qui va contenir un tableau de 8 objets capteur que je vais appeler Analog (eh oui, mon fichier pourrait aussi contenir d’autres paramètres …). Voilà ce que ça donne. J'ai nommé le fichier sensor.json

- sensorjson.png (16.48 Kio) Vu 7902 fois
Après, pour convertir mes données numériques en valeurs réelle, il va falloir faire une petite opération mathématique. La valeur analogique que me retourne le composant est comprise entre 0 et 4095 pour une tension comprise entre 0 et 5 volts. Pour transformer ça en en valeur volts il suffit juste que je fractionne ces 5v en 4095 et que je multiplie cette valeur par la valeur numérique que me retourne la lecture de la ligne analogique. Ce qui donne :
Résultat en volt = 5/4095 * valeur numérique lue.
La dessus il faut aussi penser que je peux avoir des capteurs qui feront des mesures qui n’ont pas forcement 0 comme valeur minimum et meme certain qui auront des valeurs négative. Donc je complète l’opération ce qui m’amène a ca :
Résultat réel = (valeur maxi – valeur mini) /4095 * valeur numérique lue + valeur mini
Théoriquement, avec cette opération toute simple, je peux potentiellement utiliser n’importe quel capteur linéaire qui retourne une tension qui sera comprise en 0 et 5 volts. Electroniquement parlant, je peux meme aller plus loin et dire que je peux utiliser n’importe quel capteur qui retourne une tension linéaire quelle qu’elle soit et tout ça sans modifier autre chose que mon fichier de paramètre de capteur.
Pour le code, c’est tout simple. Comme NodeJs sait nativement désérialisé un fichier Json pour le transformer en objets j’ajoute juste l’include de mon fichier capteur.json (ligne 3) et je modifie la fonction test pour afficher mes valeurs réelle de capteur.

- index2.png (34.99 Kio) Vu 7902 fois
Je relance mon petit programme et j’ai bien mes 8 voltmètres.

- vltmtr.png (11.94 Kio) Vu 7902 fois
Ça fonctionne mais Il y a pourtant un petit détail qui n’échappe pas à l’œil averti d’un développeur. La variable r dans la fonction test est entièrement recalculée à chaque lecture de capteur alors que si on regarde bien, la partie
(analog.Vmax - analog.Vmin) / 4095 est invariable pour chaque capteur et pourrait être convertie en un coef une seule fois pour toute juste après le chargement du fichier sensor.json. C’est encore un petit détail me direz-vous, mais c’est quand meme une soustraction et une multiplication de nombre décimaux à chaque lecture et ce n’est pas anodin.
La prochaine fois, on verra comment améliorer ça et je vais tacher de trouver 3 capteurs susceptible de répondre aux besoins de Didier (voir cahiers des charges).
Voila les codes actuels pour éviter de perdre du temps les recopier (ce qui ne vous empêche pas de les lire pour les comprendre ...).
index.js
Code : Tout sélectionner
var rpio = require("rpio");
var spi_io = require("./spi_io.js");
var analog = require("./sensor.json").Analog;
rpio.init({ gpiomem: false, mapping: 'gpio' });
rpio.spiBegin();
var mcp3208 = new spi_io.MCP3208(rpio, 0, 512);
var test = function () {
var b = mcp3208.ReadAll();
for (var i = 0; i < analog.length; i++) {
var r = (analog[i].Vmax - analog[i].Vmin) / 4095 * b[i] + analog[i].Vmin;
console.log(analog[i].Name + ": " + r.toFixed(analog[i].Dec) + " " + analog[i].Unite);
}
console.log("\r\n");
};
setInterval(test, 1000);
process.on('SIGINT', function () {
rpio.spiEnd();
process.exit();
});
spi_io.js
Code : Tout sélectionner
var Spi_IO = {
MCP3208: function (rpio, cs, clk) {
this.Cs = cs;
this.Clk = clk;
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
},
{
"Iden": 1,
"Name": "Voltmetre 1",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3
},
{
"Iden": 2,
"Name": "Voltmetre 2",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3
},
{
"Iden": 3,
"Name": "Voltmetre 3",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3
},
{
"Iden": 4,
"Name": "Voltmetre 4",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3
},
{
"Iden": 5,
"Name": "Voltmetre 5",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3
},
{
"Iden": 6,
"Name": "Voltmetre 6",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3
},
{
"Iden": 7,
"Name": "Voltmetre 7",
"Unite": "Volt",
"Vmin": 0.0,
"Vmax": 5.0,
"Dec": 3
}
]
}
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).