Premiers essais avec Arduino

Cet année le père noël (belle maman) m'a offert un chouette joujou : un arduino uno.
Je dois avouer que ça faisait longtemps que je lorgnais sur ces petites bestioles.

Mais c'est quoi un arduino ?

Un arduino est une carte programmable sous licence libre (wikipédia).
Ces cartes peuvent servir à tout un tas de chose : création de drone, robot, pilotage d'arrosage automatique, domotique, etc.
Les gros avantages de ces cartes sont qu'elles sont peu chères (une vingtaine d'euros) et les composants additionnels ne coûtent que quelques euros, autre avantage, on peut les programmer dans un langage dérivé du C/C++, ce qui permet de laisser libre cours à sa créativité tant que l'on reste dans les capacités de la carte, par exemple pour un Arduino Uno:

  • Micro contrôlleur : ATmega328P
  • Mémoire Flash : 32ko
  • EEPROM : 1ko
  • SRAM : 2ko
  • Broches d'entrées sorties : 14ko
  • dimensions : 68,6 mm x 53,3 mm

Travailler avec des contraintes ça a souvent du bon sur la qualité de code (jusqu'à un certain point).

Par où commencer

Tout d'abord je vous conseille d'investir dans un kit histoire d'avoir tout le nécessaire pour s'amuser, j'ai reçu celui ci : Funduino chez Amazon mais ils en existent de nombreux autres avec plus ou moins de composant.
Le minimum syndical :

  • une carte arduino
  • un cable usb
  • une bread board (pour réaliser ses montages)
  • quelques files éléectrique
  • quelques led
  • quelques résistances

Je vous conseille également l'achat d'un multimètre pour vérifier que vos composants n'ont pas cramés ça vous évitera de perdre du temps à chercher un bug dans votre montage.

Ensuite si vous êtes néophyte/rouillé soit en programmation soit en électroniques voici quelques sites qui vous guideront :

Je dois dire que j'ai sacrément dût me remettre à niveau en électronique, car à part quelques souvenirs genre U = R * I, il ne me restait pas grand chose. Mais ça revient vite et c'est très amusant et passionnant. Au début je suis tombé sur des tutos qui ne détaillaient que la partie code, partie qui ne me servait à rien... par contre en électronique tout était considéré comme acquis, c'est pour cela que je recommande le site zeste de savoir qui détaille très bien la partie électronique.

Côté logiciel vous pouvez télécharger le SDK sur le site Arduino
Le SDK est accompagné d'un IDE minimaliste :

Travaillant au quotidien sur Visual Studio 2015 je me suis empressé d'installer l'extension de Visual Micro :

Cette extension accessible via le menu Tools\Extensions and update de Visual Studio intègre tout le nécessaire pour développer sur Arduino (vous devez quand même installer le SDK que j'ai cité précédemment).
Vous aurez alors accès à l'autocomplétion, à un débugger, une console de communication série, bref pour ceux qui bossent sous visual vous ne serez pas perdu.
Et un point très sympathique et que cela permet de créer des solutions qui intègrent le projet arduino, le projet serveur qui communique avec l'arduino et éventuellement le projet client.

Afficher le résultat d'un capteur dans une page web

Avoir un capteur sur une carte électronique dans une boite c'est bien, mais pouvoir récupérer les informations et les afficher dans un navigateur web c'est mieux.

J'ai donc décidé de commencer à me familiariser avec la communication série sur Arduino. Le but de cet exemple est de créer récupérer la valeur d'un capteur photosensible est de l'afficher toutes les secondes sous forme de graphique dans une page web. La communication entre l'arduino et la page web se fera au travers d'une application NodeJS.
En gros un truc comme ça :

le montage électronique

Pièces nécessaires pour la partie électronique :

  • Arduino
  • Résistance 1kohm
  • Cellule photo électrique
  • 3 fils électriques
  • la bread board

Vue schématique :

Le montage aura la forme suivante :

le code du programme stocké dans l'arduino

//la cellule photo électrique est branchée sur le port analogique 0
#define CDS_INPUT 0

void setup() {  
// on ouvre la liaison série à une vitesse de 9600 bauds
    Serial.begin(9600);
}

void loop() {  
// on lit la valeur sur l'entrée analogique 0
    int value = analogRead(CDS_INPUT);
// on écrit cette valeur sur la liaison série
    Serial.println(value);

    delay(1000);
}

Et c'est tout, c'est qui m'a tout de suite plus sur Arduino c'est que pour faire des choses simples, c'est simple, pas d'usine à gaz juste ce qu'il faut.

Pour vérifier que cela fonctionne, chargez le programme et ouvrez le monitor série (soit celui d'Arduino, soit celui de visual :)
Si tout se passe bien vous devriez voir apparaître les valeurs de la cellule, en passant le doigt au dessus de la cellule les valeurs doivent changer :

Attention si cela ne fonctionne pas c'est peut être que la vitesse d'écoute n'est pas bonne, dans notre exemple il faut qu'elle soit de 9600bps

le code du serveur

Le serveur a plusieurs rôles : récupérer les informations sur la liaison série (via l'USB) de l'arduino, transmettre ces informations à un tiers via une socket et enfin servir la page web qui affichera notre graphique dynamique (un serveur web type IIS/Apache peut également se charger de ce rôle mais je voulais que l'exemple se concentre sur l'essentiel)

Coté serveur on utilise donc NodeJS, pour effectuer nos différents traitements, il va falloir installer quelques paquets supplémentaires.
Tout d'abord le paquet permettant d’interagir avec une liaison série :
serialport

npm install serialport  

Ensuite il nous faut de quoi communiquer avec la page web, j'ai pris le parti de partir sur la librairie socket.io, j'aurai pu également utiliser une api REST mais la encore j'ai voulu avoir un code concis pour l'exemple.

npm install socket.io  
//initialisation de la socket de communication avec le navigateur sur le port 8001
var io = require('socket.io').listen(8001);  
var serialport = require('serialport');

//à remplacer par votre nom de port COM
var portName = 'COM4';  
var sp = new serialport.SerialPort(portName, {  
    baudRate: 9600,
    dataBits: 8,
    parity: 'none',
    stopBits: 1,
    flowControl: false,
    parser: serialport.parsers.readline("\r\n")
});

//à la connexion d'un client on lui répond hello
io.sockets.on('connection', function (socket) {  
    socket.emit('news', { hello: 'world' }); 

    //sur la reception de données depuis la liaison série, on transmet sur le socket du navigateur la valeur de la cellule
    sp.on('data', function (input) {
        console.log(input);
        socket.emit('news', { sensor: input });
    }); // Send data to client
});


// ici on initialise notre serveur http, son unique rôle est d'envoyer la page index.html qui contient le code du client
var http = require('http'),  
    fs = require('fs');

fs.readFile('./index.html', function (err, html) {  
    if (err) {
        throw err;
    }
//le serveur web répond sur le port 8000, donc sur l'url en local : http://localhost:8000
    http.createServer(function (request, response) {
        response.writeHeader(200, { "Content-Type": "text/html" });
        response.write(html);
        response.end();
    }).listen(8000);
});

A ce niveau vous pouvez tester que votre serveur node est capable d'écouter l'arduino. Une fois l'arduino branché, lancez votre programme node :

node app.js  
234  
343  
320  
270  

La ligne console.log(input); nous permet d'afficher dans la console que notre serveur communique correctement avec l'arduino.

le code de la page web

Coté HTML rien de miraculeux, un canvas suffira à héberger notre graphique dynamique.
Nous devons par contre référencer deux librairies javascript :

    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
    <script src="https://cdn.socket.io/socket.io-1.3.7.js"></script>

La première chart.js s'occupe de la génération du graphique.
La deuxième socket.io s'occupe de la communication avec la socket hébergée par notre serveur.

Et enfin le code javascript pour communiquer avec le serveur et afficher le graphique. Il y a beaucoup de code juste pour l'initialisation du graphique mais très peu pour la communication.

        var optionsAnimation = {           
            scaleOverride: true,
            scaleSteps: 10,
            scaleStepWidth: 50,
            scaleStartValue: 100
        };

        var optionsNoAnimation = {
            animation: false,
            scaleOverride: true,
            scaleSteps: 20,
            scaleStepWidth: 50,
            scaleStartValue: 100
        };

        //objet d'initialisation du graphique
        var chartData = {
            // nombre de points pouvant être affichés en ordonnés, vous pouvez mettre ce que vous voulez en libellés
            labels: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
            datasets: [
         {
             label: "Arduino datas",
             fillColor: "rgba(220,220,220,0.2)",
             strokeColor: "rgba(220,220,220,1)",
             pointColor: "rgba(220,220,220,1)",
             pointStrokeColor: "#fff",
             pointHighlightFill: "#fff",
             pointHighlightStroke: "rgba(220,220,220,1)",
             data: [1000]
         }
            ]
        };

        var context = document.getElementById("myChart").getContext("2d");
        var chart = new Chart(context);

        chart.Line(chartData, optionsAnimation);

        //la communication avec notre serveur node
        var socket = io.connect('http://localhost:8001');
        socket.on('news', function (data) {
            console.log(data.sensor);
            //sur chaque nouvelle information reçue, on l'ajoute au tableau de data de notre graphique
            chartData.datasets[0].data.push(data.sensor);
            // notre fifo fait 10 éléments, au bout de 10 le plus vieux est supprimé
            if (chartData.datasets[0].data.length > 10) {
                chartData.datasets[0].data.shift();
            }
            // on demande à chart.js de redessiner le graphique
            chart.Line(chartData, optionsNoAnimation);
        });

Lancer votre navigateur à l'adresse http://localhost:8000
et observez le résultat :

Les sources sont disponibles sur le github du blog : cheesecode

Cet article me sert de préparation pour mon premier vrai projet : une boite au lettre connectée, dès que le facteur dépose une lettre la boite au lettre devra nous envoyer un push sur nos smartphone.

Je ne suis pas trop rentré dans les détails sur la plateforme arduino mais les références que j'ai mis expliquent déjà tellement bien le sujet que ça n'apporterai rien d'en remettre une couche.

Source d'inspiration de l'article : https://plot.ly/arduino/light-sensor-tutorial/