Transformer un Raspberry Pi en multimètre réseau

Transformer un Raspberry Pi en multimètre réseau

Les appareils de mesure qui peuvent être connectés directement sur le réseau sont en général très chers, plus de 1000 EUR. Pourtant, de nombreuses applications pourraient en profiter s'ils étaient plus abordables, comme par exemple le suivi d'une expérience commencée sur un coin de table. Nous allons donc vous montrer comment transformer très simplement un Raspberry Pi en un multi-mètre Ethernet très flexible, à l'aide d'un simple script Python. Une solution simple à base de modules USB standards, vidéo à l'appui.

Update: le code source est disponible sur GitHub: https://github.com/yoctopuce-examples/multimeter

Pour faire notre multi-mètre Ethernet, nous allons utiliser
- un Raspberry Pi modèle B, pour la connexion Ethernet (28 EUR)
- un écran OLED Yocto-Display, pour un affichage très lisible (70 EUR)
- une RaspBox, pour l'habillage (12 EUR)
- des capteurs Yoctopuce, par ex. un Yocto-Thermocouple (37 EUR) ou un Yocto-Volt (48 EUR)
- un petit script Python tournant sur le Raspberry Pi pour le contrôle de l'écran (gratuit)
- le logiciel VirtualHub (téléchargeable sur notre site) pour l'accès distant aux mesures (gratuit)
Le prix final dépendra des capteurs que vous utilisez, mais restera très avantageux par rapport à une solution commerciale (dans l'exemple ci-dessus, deux entrées thermocouple plus une mesure de tension avec isolation revient à moins de 200 EUR).

L'assemblage

Rien de compliqué pour cette réalisation puisqu'on utilise que des périphériques USB standards. En faisant 4 petits trous sur la plaque supérieure de la RaspBox, on fixe le Yocto-Display dessous afin qu'il soit protégé. L'écran est raccordé par un câble USB via un connecteur 1.27mm, moins encombrant qu'une fiche micro-B, qui s'adapte à tous nos modules et que nous aurons en vente sur notre shop d'ici quelques jours.

Voilà ce qu'on va réaliser
Voilà ce qu'on va réaliser



L'installation

Prenez une image Linux pour Raspberry Pi standard, et vérifiez bien que votre Raspberry Pi est à jour en exécutant "sudo raspi-config" et en sélectionnant "update". Le bug USB du Raspberry Pi n'a toujours pas été complètement fixé, il faut donc s'assurer que votre fichier /boot/cmdline.txt contienne bien l'option dwc_otg.speed=1 et redémarrer. Édit: L'option "dwc_otg.speed" n'est plus nécessaire pour les Raspberry Pi B+ et suivants.

Téléchargez et installez ensuite le VirtualHub de Yoctopuce, qui fournira automatiquement un accès réseau à vos capteurs, pour pouvoir les interroger à distance depuis votre station de travail, et installez la librairie Yoctopuce pour Python yoctopuce via PyPi. C'est tout, il ne reste plus qu'à écrire les quelques lignes de Python pour piloter le tout.

Le code

Pour être le plus pratique possible, le code va détecter à tout moment les modules connectés afin de s'adapter automatiquement à la sonde connectée. Pour ce faire, nous allons partir de l'exemple de programmation par événement fourni dans la librairie Yoctopuce, et le généraliser un peu pour tenir à jour un dictionnaire de sondes disponibles pour l'affichage.

# List of sensors to display (discovered by Plug-and-play)
sensors = { }
currentSensor = ""

# add sensor to dictionary when plugged
def deviceArrival(m):
    global sensors, currentSensor
    for i in range(m.functionCount()):
        fctName = m.functionId(i)                     # eg. "voltage1"
        fctType = re.sub("\d+$", "", fctName)         # eg. "voltage"
        hwId = m.get_serialNumber() + "." + fctName
        yocto_mod = getattr(yoctopuce, "yocto_"+fctType.lower(), None)
        if(yocto_mod is not None):
            className = fctType[0].upper()+fctType[1:]# eg. "Voltage"
            YClass = getattr(yocto_mod, "Y"+className)# eg. YVoltage
            yFind = getattr(YClass, "Find"+className) # eg. YVoltage.FindVoltage
            fct = yFind(hwId)
            if getattr(fct, "get_unit", None) is not None:
                currentSensor = fct.get_hardwareId()
                sensors[currentSensor] = \
                    { "name" : fct.get_friendlyName(),
                      "val"  : fct.get_unit() }
                fct.registerValueCallback(sensorChanged)
    refreshDisplay()

# update display when sensor changes
def sensorChanged(fct,value):
    hwId = fct.get_hardwareId()
    if hwId in sensors: sensors[hwId]['val'] = value+" "+fct.get_unit()
    refreshDisplay()

# remove sensor from dictionary when unplugged
def deviceRemoval(m):
    deletePattern = m.get_serialNumber()+"\..*"
    deleteList = []
    for key in sensors:
        if re.match(deletePattern, key): deleteList.append(key)
    for key in deleteList:
        del sensors[key]
    refreshDisplay()



Le code d'affichage ne prend que quelques lignes. Comme il peut y avoir plusieurs senseurs, on garde le nom de la fonction actuellement affichée dans une variable.

# Get the display object
display = YDisplay.FirstDisplay()
if display is None:
    sys.exit("Display not connected")
display.resetAll()
dispLayer = display.get_displayLayer(1)
dispLayer.hide()

# Update the display value if needed (with double-buffering)
def refreshDisplay():
    global currentSensor
    if currentSensor not in sensors:
        currentSensor = sensors.keys()[-1]
    sensor = sensors[currentSensor]
    dispLayer.clear()
    dispLayer.selectFont("Small.yfm")
    dispLayer.drawText(0,0,YDisplayLayer.ALIGN.TOP_LEFT,sensor["name"])
    dispLayer.selectFont("Medium.yfm")
    dispLayer.drawText(127,28,YDisplayLayer.ALIGN.BOTTOM_RIGHT,sensor["val"])
    display.copyLayerContent(1,2)



Pour changer la fonction affichée, on utilise simplement les entrées bouton disponibles sur l'écran. Il n'est même pas indispensable d'y mettre un vrai bouton poussoir en l'occurrence: comme il s'agit d'entrées analogiques avec calibration, il suffira d'effleurer les contacts avec les doigts pour activer les entrées, selon le même principe que le Makey-Makey.

# Get the buttons objects, get an event when "pressed"
serial = display.get_module().get_serialNumber()
prevButton = YAnButton(serial+".anButton1")
nextButton = YAnButton(serial+".anButton6")
prevButton.set_userData(False)   # False = released
nextButton.set_userData(False)   # False = released
prevButton.registerValueCallback(buttonPressed);
nextButton.registerValueCallback(buttonPressed);

# Callback whenever a button value changes
def buttonPressed(fct,value):
    global currentSensor
    if(int(value) > 500):    # button is released
        fct.set_userData(False)
        return
    if(fct.get_userData()): # button was already pressed
        return
    # Button was just pressed, cycle through sensors values
    fct.set_userData(True)
    delta = (1 if fct.get_hardwareId()[-1] == '1' else -1)
    if(delta != 0):
        keys = sensors.keys()
        idx = len(keys)-1
        for i in range(len(keys)):
            if keys[i] == currentSensor:
                idx = (i+delta+len(keys)) % len(keys)
        currentSensor = keys[idx]
        refreshDisplay()



Pour le confort d'utilisation, on ajoute une fonction affichable supplémentaire: l'adresse IP du Raspberry Pi. Ça facilite grandement la vie pour ces machines sans écran...

# Put the Raspberry Pi itself as default sensor, to show IP address
sensors[""] = { "name" : socket.gethostname(),
                "val"  : findMyIP() }
refreshDisplay()



Voilà pour l'affichage en direct, vous avez maintenant un multi-mètre Ethernet. Comme nous avons mis le VirtualHub, les capteurs peuvent être interrogés à travers le réseau par la même API Yoctopuce, et ce depuis (presque) n'importe quel langage de programmation.

Et, cerise sur le gâteau, vous pouvez en quelques clicks configurer le VirtualHub pour poster automatiquement sur Cosm les valeurs mesurées. Ainsi vous pourrez suivre vos expériences sur votre Smartphone sans même écrire une ligne de code...

Les données peuvent être collectées automatiquement sur Cosm
Les données peuvent être collectées automatiquement sur Cosm



Le résultat

  

Commenter 5 commentaires Retour au blog



1 - sartog Mardi 03 novembre 2015 13H30

Bonjour,

A la lecture du titre, je me suis dit que j'avais enfin trouvé la solution à mon problème de relevé de valeur de résistance ... hélas non et ce malgré un article très intéressant et passionnant !

Je n'ai pas trouvé mon bonheur dans votre boutique mais je tente ma chance malgré tout ... est-il possible de faire des relevés de valeur de résistance (R = U/I mais comment fixer U et I) ?

Je vous remercie par avance pour votre réponse.

2 - sartog Mardi 03 novembre 2015 13H32

Complément d'information :

La résistance que je souhaite mesurer à une valeur variable (résistance de ballon d'eau chaude permettant de déterminer la T° de l'eau).

3 - mvuilleu (Yocto-Team)Mardi 03 novembre 2015 13H45

@sartog: je pense qu'il vous faut simplement utiliser un Yocto-MaxiThermistor à la place du Yocto-Volt. Le Yocto-MaxiThermistor sera même capable de vous faire directement la conversion résistance vers température, d'après la table correspondant à votre NTC ou PTC.

4 - jms Mardi 17 novembre 2015 15H07

Bonjour.
J'ai un Raspberry Pi avec lequel je fais des mesures de température avec des sondes DS18B20 mais là j'ai un problème de mesure d'une résistance.
Sur des capteurs solaires j'ai des sondes collées de type Cuproswem qui font 233 ohms à zéro degrés et varient de 1 ohm par degrés.
Comme elles sont à l'intérieur du capteur solaire je ne peux pas les remplacer par des DS18B20.
Je voudrais donc mesurer avec mon Raspberry la valeur de résistance pour en déduire la température.
Je suppose qu'il me faut une petite alim pour ensuite mesurer la tension aux bornes de mes sondes mais je suis nul en électronique et je n'ai pas trouvé sur Internet de montage correspondant.
Quelqu'un pourrait-il me renseigner sur les composants à utiliser, le montage à faire et le programme à mettre dans mon Raspberry ?
Merci par avance.
jms

5 - mvuilleu (Yocto-Team)Mardi 17 novembre 2015 15H12

Si vous cherchez une solution simple, branchez simplement un Yocto-MaxiThermistor par USB et mettez votre résistance sur une des entrée. Pour une solution basée pure électronique + Raspberry Pi, je pense qu'il vaudrait mieux poser la question sur electronics.stackexchange... mais prenez garde au problème de l'isolation électrique entre la terre de la tension mesurée et la terre de votre PC, sinon ça fera un Barbecue-Pi

Yoctopuce, get your stuff connected.