Un serveur RTD Excel pour les capteurs Yoctopuce

Un serveur RTD Excel pour les capteurs Yoctopuce

Il y a bientôt deux ans, nous vous montrions comment accéder aux modules Yoctopuce depuis Excel en créant votre propre plug-in pour Excel grâce à Excel-DNA. Aujourd'hui nous allons voir comment faire plus simple et encore mieux: lire n'importe quel senseur Yoctopuce depuis Excel, avec rafraîchissement instantané, sans que vous deviez recompiler une seule ligne de code...



La première amélioration qui nous aide par rapport au précédent article vient de la librairie Yoctopuce: depuis le début de l'année, il est possible d'utiliser la classe abstraite YSensor pour accéder à n'importe quel senseur, plutôt que de devoir utiliser une classe spécifique. C'est ce qui vous permettra de pouvoir tester notre code avec n'importe quel capteur Yoctopuce sans même devoir recompiler le plug-in pour Excel.

La deuxième nouveauté nous a été suggérée par un client: implémenter un "Serveur de données en temps réel" pour Excel (RTD Server) plutôt que des appels de fonctions VisualBasic. Un serveur RTD se présente à l'utilisateur comme une simple fonction Excel, mais elle a la particularité de pouvoir changer spontanément de valeur et de notifier Excel afin qu'il recalcule toutes les cases dépendantes. C'est l'équivalent direct pour Excel de nos callbacks de changement de valeur. Et c'est naturellement avec une fonction de callback que nous allons l'implémenter, offrant ainsi une possibilité de rafraîchissement grande vitesse.

La démonstration


Vous voulez essayer tout de suite ? Commencez par installer un Framework .NET récent. Ensuite ouvrez Excel, activez le menu "développeur", dans lequel vous trouverez le bouton "Complément". En cliquant sur "Parcourir", vous verrez le répertoire ou Excel cherche vos plug-ins. Ajoutez-y le contenu de ce fichier zip contenant le server RTD pour les senseurs Yoctopuce, et activez le plug-in YoctoRTD.xll. C'est tout.

Ajouter le plug-in dans Excel
Ajouter le plug-in dans Excel



Si vous avez branché un module Yoctopuce à votre ordinateur, vous pouvez maintenant ajouter dans n'importe quelle case la formule


=YSensorValue("any")
 


pour y faire apparaître la valeur courante du premier capteur trouvé. Et la valeur change automatiquement. A la place de "any", vous pouvez mettre l'identifiant unique de n'importe quelle fonction (par exemple "LIGHTMK2-24F0F.lightSensor") ou le nom logique correspondant, si vous en avez donné un. Par défaut, Excel ne met à jour les valeurs dynamiques que toute les deux secondes, mais notre plug-in ajoute un menu qui permet facilement de monter la fréquence jusqu'à 100Hz. Voyez plutôt:

  



L'implémentation


Si vous êtes intéressé à savoir comment cela fonctionne et à modifier cet exemple, voici quelques explications. Comme dans le précédent exemple de plug-in basé sur Excel-DNA, nous avons commencer par créer un project C# de type DLL dans VisualStudio Express 2012 (vous trouverez tout le projet dans ce fichier zip). A part la référence à ExcelDNA.Integration et le fichier de base de la librairie Yoctopuce yocto_api.cs, il a suffi d'un seul petit fichier source pour implémenter ce serveur RTD.

La structure du projet C# .net
La structure du projet C# .net



Voici quelques mots sur les méthodes les plus importantes de YoctoRTDServer.cs:

ServerStart()

C'est la méthode appelée par Excel lorsque l'utilisateur ajoute pour la première fois une référence à YSensorValue(). Nous devons y activer la librairie Yoctopuce, y compris un timer qui donnera régulièrement le contrôle à la librairie pour gérer les notifications.


    string errmsg = "";
    YAPI.RegisterLogFunction(log);
    if (YAPI.RegisterHub("usb", ref errmsg) == YAPI.SUCCESS) {
        Console.Beep();
        log("USB ready");
        _notifyUpdates = true;
        _timer = new Timer(delegate {
            string dummy = "";
            YAPI.HandleEvents(ref dummy);
        }, null, 0, 10);
    }
    else log(errmsg);
 



ServerTerminate()

C'est la méthode qui fait l'inverse de la précédente, lorsque la dernière référence à YSensorValue() est supprimée.


    if (_timer != null) {
        Console.Beep();
        _timer.Change(Timeout.Infinite, Timeout.Infinite);
        _timer = null;
        _notifyUpdates = false;
        YAPI.UnregisterHub("usb");
        YAPI.FreeAPI();
        log("USB closed");
    }
 



ConnectData()

C'est la méthode appelée chaque fois qu'une référence à YSensorValue() dans la feuille Excel. Cette méthode doit mettre en route l'appel de callback pour annoncer les nouvelles valeurs. Excel fournit un identifiant numérique topicId pour la demande, que nous devrons lui communiquer à chaque fois que nous voulons annoncer une nouvelle valeur. Nous associons donc cet identifiant à l'objet YSensor de l'API Yoctopuce, à l'aide de l'attribut userData qui est justement prévu pour ce genre d'utilisations:


    sensor = YSensor.FindSensor(sensorId);
    if (!sensor.isOnline()) {
        log("Sensor " + sensorId + " is not online, check USB cable");
    }
    sensor.set_userData(new object[] { this, (int)topicId });
    sensor.registerValueCallback(sensorValueChangeCallBack);
 


Le callback de changement de valeur se contentera de sauvegarder chaque nouvelle valeur signalée par le capteur dans un dictionnaire interne de "changements à signaler", et d'avertir Excel qu'il y a des changements à venir chercher si ce n'est pas déjà fait:


    srv._topics[topicId] = value;
    if (srv._notifyUpdates) {
        srv._notifyUpdates = false;
        srv._callback.UpdateNotify();
    }
 



RefreshData()

C'est la méthode appelée par Excel pour chercher les changements lorsqu'on l'a averti de la présence de nouvelles valeurs. Pour éviter à Excel de recalculer des cases inutilement, on n'inclut dans cette liste que les capteurs dont la valeur a effectivement changé, grâce à notre dictionnaire de "changements à signaler".


    // Count changed values
    topicCount = 0;
    foreach(var value in _topics.Values) {
        if (value != "") topicCount++;
    }
    // Create an array of changes to report
    object[,] results = new object[2, topicCount];
    int idx = 0;
    double floatVal = 0;
    foreach (KeyValuePair<int, string> pair in _topics) {
        if (pair.Value != "") {
            results[0, idx] = pair.Key;
            results[1, idx] = double.Parse(pair.Value);
            idx++;
        }
    }
    // Clear reported values from the dictionary
    for (idx = 0; idx < topicCount; idx++) _topics[idx] = "";
    // Enable further updates now that this one is processed
    _notifyUpdates = true;

    return results;
 



Voilà, tout le reste du fichier YoctoRTDServer.cs n'est que de la déco pour créer les menus. La vraie magie qui fait que tout cela marche dans Excel est implémentée par la librairie Excel-DNA, qui est décidément une très bonne librairie!

Commenter 4 commentaires
Retour au blog



1 - serguai59 Jeudi 16 octobre 2014 15H04

Bonjour

Comme d'habitude, impressionnant ... avoir un excel qui cause avec un module Yocto, je vais essayer vite fait

A voir tout ce qui vous trotte dans la tête, j'ai quand même l'impression qu'on ne fait pas que manger du chocolat en Suisse, on en fume aussi, non ? ;o)

Bon, je suis sûr que vous allez me répondre que vous avez aussi des développeurs en France ...

Merci encore pour votre travail

Cordialement

Serge

2 - martinm (Yocto-Team)Samedi 18 octobre 2014 10H08

@serguai59: en fait, on se fait aider par la marmotte, celle qui emballe le chocolat dans le papier d'alu. Merci pour vos encouragements.

3 - Benjee Dimanche 18 janvier 2015 14H05

Bonjour,
J'ai un Microsoft Excel 2011 qui tourne sur un MAC OS X Yosemite (10.10.1)!
Quand je veux ajouter le plug-in YoctoRTD.x11, j'ai un message d'erreur qui me dit que le plug-in est invalide!
Est-ce parce que je n'ai pas pu installer le Framework .NET sur MAC? Ya-t-il un autre framework disponible pour MAC?
Ou alors est-il possible d'essayer cette fonctionnalité sur MAC autrement?
Merci d'avance pour votre réponse

4 - mvuilleu (Yocto-Team)Lundi 19 janvier 2015 8H31

@Benjee: Malheureusement le mécanisme COM utilisé par les serveurs RTD d'Excel est complètement spécifique à Windows, et il n'est pas possible de faire un système équivalent pour Excel sous Mac OS X.

Yoctopuce, get your stuff connected.