Projet

Général

Profil

Capteur Vegetal Signals

Le capteur Vegetal Signal a été prêté M. F. Le Bourdiec de la Start Up Vegetal Signals. Sur les capteurs nous avons :
  • 8 ports : les capteurs utilisés sont contenus dans des boîtiers de 8 ports +/-. Nous pouvons donc brancher 8 électrodes, appelées également capteurs, à l'aide d'un optocoupleur.
  • Il existe 2 types de mesures : soit un couple +/- ; soit brancher plusieurs + sauf sur 1 seul, le port SRB1 qui jouera le rôle de masse2.
  • Les électrodes utilisées sont des électrodes du milieu hospitalier. Leur longueur est de 2,5 cm. Nous les plantons à 3 voire 5 mm maximum du phloème3, le reste de celle-ci est isolée avec du polystyrène.
  • Les mesures sont différentielles : deux capteurs sont nécessaires pour effectuer un ensemble de mesure, en effet, nous mesurons une différence de potentiel. Nous plaçons donc une électrode sur la tige et une autre sur la masse au niveau du tronc de la plante.
  • La fréquence d'échantillonnage des capteurs est de : 250 Hz.
  • Concernant les unités de mesures, nous voulons étudier deux choses : le grésillement (bruit de l'ordre du µV) et la porteuse de l'ordre du mV. Les données en tension sont donc faibles.
  • L'oscilloscope est inutilisable car l'ordre de grandeur du signal mesuré est trop faible. Néanmoins, ceci nous indique que nous mesurons le bruit électronique de 50 Hz, en plus du signal, qu'il faudra donc filtrer par la suite.
  • Nous pouvons donc obtenir deux durées de mesures : en temps réel ou en accéléré sur des longues périodes. C'est la deuxième catégorie qui apporte les informations les plus riches et exploitables car la plante réagit à un ensemble de facteurs. Ainsi, une mesure instantanée ne serait donc pas très sujette aux variations.
  • Concernant l'autonomie de l'appareil de mesure, le boîtier est composé d'une carte micro-SD pouvant contenir des mesures/données sur 53 jours. Cette carte contenant les données seront récupérées par la suite. Elles sont chiffrées en hexadécimal 24 bit. Le boîtier est également composé d'une batterie pouvant durer 8 à 9 jours (soit 4 piles) d'autonomie basculant par la suite sur des panneaux solaires.
  • Amplitude du signal
    Chaque capteur renvoie 3 bytes en hexadécimal pour une valeur cryptée à un instant donné.
    Chaque byte est de la forme \x_ _, il contient 2 informations.
    Ainsi, une valeur est représentée par 6 informations hexadécimales. Le nombre de valeurs possibles vaut donc 16^6 = 16 777 216.
    L'écart entre deux mesures d'un capteur étant de 20 nA, l'amplitude des valeurs d'un capteur vaut 16^6 * 20 = 335 544 320 nA, soit une amplitude d'environ 336 mA.

Photo du capteur Vegetal Signals

1 Port SRB : nom du port

2 La masse

3 Le phloème


Traitement du signal

Analyser l'encodage du fichier

exemple de signal écrit par le capteur :

0\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00
1\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00
2\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00
3\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00
4\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00
5\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00
6\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00
7\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00
8\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00
9\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00\80\00\00
sur chaque ligne on peut lire :
  • un chiffre d'entête
  • 8 séries de 3 bytes, soit une par canal du capteur

Tableau expliquant le fichier de données renvoyées par le capteur VégétalSignals

exemple de ligne bash1 pour afficher le fichier en decimal :

cat VS20B71.TXT|od -t x1 -w26

Mais attention quand le début du buffer2 comprend 17 codes 23 (#), il faut les éliminer!!! sinon après ça décale.

1 BASH.

2 Buffer

Programme du code python gbgb3.py :

Programme python

#! /usr/bin/env python3
# -*- coding: UTF-8 -*-
import struct 
f = open("VS20B6D.TXT", "rb") #ouverture fichier en mode binaire
try:
    while True:
        record = f.read(26)
        if len(record) != 26:
            break;
        if record[:18] == b'#################\n':
            complement = f.read(18)
            record = record[18:] + complement
        record_4x8_octets = bytearray()
        i=1;
        while i<25:
            record_4x8_octets.append(record[i])
            if i % 3 == 0:
                record_4x8_octets.append(0)
            i += 1
        resultat_fois265 = struct.unpack('>iiiiiiii', record_4x8_octets)
        resultat = []
        for R in resultat_fois265:
            resultat.append(R//256)
        print(resultat) # Affiche les 8 valeurs:
except IOError:
    # Traitement d'erreurs a faire ici...
    pass
finally:
    f.close()

Explication du programme

Ce programme permet de transformer les données hexadécimales renvoyées par le capteur en des données décimales.

#! /usr/bin/env python3
# -*- coding: UTF-8 -*-
import struct 
f = open("VS20B6D.TXT", "rb") #ouverture fichier en mode binaire

Cette partie du code permet d'importer la bibliothèque struct qui sera utile plus tard pour convertir les données hexadécimales en données décimales et d'ouvrir ce fichier texte qui va être traduit.

while True:
        record = f.read(26)
        if len(record) != 26:
            break;

Le programme lit dans un premier temps 26 bytes dans le fichier : à un instant, les valeurs retournées par les 8 capteurs sont codées sur 24 bytes et l'instant est identifié avec 1 autre byte et enfin 1 byte pour le saut de ligne. Alors pour transformer la valeur hexadécimale en valeur décimale et récupérer l'information du capteur ayant retourné cette valeur hexadécimale, il faut lire à chaque fois le fichier sur 26 bytes. Cette partie du code assure aussi la fin du programme. En effet celui-ci s'arrête si le nombre de bytes non traités restants dans le fichier texte est inférieur à 26 bytes. Ainsi le programme s'arrête s'il n'y a plus de données a traiter.

if record[:18] == b'#################\n':
            complement = f.read(18)
            record = record[18:] + complement
        record_4x8_octets = bytearray()

Toutes les 19 mesures le capteur ajoute la ligne '#################\n'(cette chaîne de caractère fait 18 bytes) il faut donc "ignorer" cette ligne et lire la ligne suivante or lorsque on lit 26 bytes, les 18 premiers caractères sont '#################\n' et les 8 derniers correspondent aux 8 premiers bytes d'une valeur hexadécimale retournée par un capteur. Il manque donc 18 bytes pour lire complement la valeur hexadécimale retournée par le capteur. Afin d'ignorer '#################\n' on commence par déclarer la variable complément qui comporte les 18 prochains bytes du programme puis on modifie record (sensé contenir les 26 bytes d'une valeur hexadecimal retournée par un capteur). On affecte à record la nouvelle valeur record[18:] (qui correspond aux 8 bytes après '#################\n') et on y ajoute complement qui correspond aux 18 derniers bytes.

i=1;
while i<25:
      record_4x8_octets.append(record[i])
      if i % 3 == 0:
          record_4x8_octets.append(0)
      i += 1

Dans cette partie on ajoute un byte null tous les 3 bytes à partir du 2ème byte jusqu'à l'avant dernier : en commençant à partir du 2ème byte et donc de l'indice 1 du tableau record, cela permet d'ajouter des bytes null uniquement dans la valeur hexadécimale retournée par le capteur. En ajoutant un byte null tous les 3 bytes, cela permet de passer le codage de chaque valeur hexadécimale renvoyée par un capteur de 3 à 4 bytes, transformation nécessaire pour pouvoir retourner des entiers du complément signé 2 en utilisant la fonction struck.unpack, sans cette ajout l'information n'est pas suffisante pour permettre d'obtenir un entier signé. Cet ajout de byte va avoir pour conséquence de décaler les bytes de chaque capteur en ajoutant \x00 à la fin de chaque, cet ajout ayant pour effet de multiplier le résultat par 256.

resultat_fois265 = struct.unpack('>iiiiiiii', record_4x8_octets)

L'utilisation de la fonction struct.unpack va permettre de transformer les valeurs hexadécimales en valeurs décimales du complément signé 2. Néanmoins on se souvient que l'ajout de bytes nulls a multiplié les valeurs par 256.

resultat = []
        for R in resultat_fois265:
            resultat.append(R//256)
        print(resultat) # Affiche les 8 valeurs:

Ainsi le résultat final est obtenu en divisant chaque valeur par 256. Les valeurs décimales des données captés par tous les capteurs à un instant donné sont finalement contenues dans le tableau résultat.

Filtrage du signal

Représentation graphique

Axes de recherche

Traitement du signal

Calcul de la puissance d'un signal

Définition de la puissance d'un signal (périodique ou non) sur un intervalle. Voir p.17 (2.6)
formule de la puissance d'un signal sur un intervalle
Source : https://www.lias-lab.fr/perso/olivierbachelier/reserve_docs/TdS_MP.pdf