Projet

Général

Profil

Transformation du signal racinaire en son (TSRS)

Résumé

Ce projet a pour but de produire de la musique, de façon asynchrone en un premier temps, et de façon synchrone au final, à partir du signaux des plantes.

Introduction

Nous nous sommes demandés si nous pouvions capter les signaux électriques d'une plante et s'il serait possible de les traduire en son. Une des applications directes serait de mieux comprendre les besoins de la plante et donc d'optimiser sa croissance ainsi que son développement.

Matériels et méthodes

Test sur une plante existante au sein du Fablab

Le test a été fait sur une plante existante au sein du Fablab de Gradignan à l'aide du Capteur Vegetal Signals. Des électrodes ont été placées sur différentes parties de la plante (tiges secondaires et principale). En effet, le phloème1 est une sorte de canal qui sert, entre autre, à transporter la sève élaborée2 (riche en glucide) jusque dans les parties de la plante en croissance.
Les 20 premières mesures représentent la réaction de la plante à la blessure infligée par l'implantation de l'électrode dans le phloème1. De fait, les mesures ne sont exploitables que 20 minutes après la pose des capteurs. Lors des mesures, nous comparons le fonctionnement normal de la plante (saine) à des conditions où la plante est stressée (mise sous contrainte) comme par exemple un stress hydrique (apport insuffisant en eau), ce à quoi nos plantes ont été habituées. Le signal mesuré est la combinaison de deux sources de signaux physiologiques :
  • l'activité chlorophyllienne (en haut)
  • les échanges électrochimiques (H2O, suit l'état du substrat) (en bas)
    C'est pourquoi, nous nous plaçons dans la tige principale car il y a la convergence des deux flux d'informations, ascendant et descendant.

Pour pouvoir capter le signal de la plante, il a fallu faire un formatage de la carte SD sous Unix (FAT) et pas sur Windows. Mais il faut un formatage sans effacer les données car c'est plus rapide. Bien essuyer les tiges de la plante avec de planter les capteurs (entre 3 à 5 mm dans le phloème) en veillant à ce que celui-ci ne soit pas trop à l'air libre (en complétant par exemple avec du polystyrène). Démarrer le Capteur Vegetal Signals et lire les données de la carte SD (sachant que 5 minutes d'enregistrement correspondent à environ 25 Mo).

Photo générale sur les branchements des électrodes ......................... Zoom du branchement sur une tige

Photos du montage des électrodes sur la plante existante reliée au capteur Vegetal Signals

Carte des interférences au sein du Fablab et à l'extérieur

Au vu des différents signaux captés et afin de mieux les comprendre, une carte des PEM (Perturbations Électro-Magnétique) a été établie via les électrodes plantées dans la plante et reliées à un oscilloscope.

Cartographie des PEM au Fablab

Cartographie des PEM au Fablab

Cette même expérience a été tentée à l'extérieur du Fablab afin de réduire encore les PEM. Les PEM étant encore présentes même à l'extérieur, nous avons donc décidé d'utiliser la Cage de Faraday afin d'isoler toutes les perturbations.

Mise en place de la cage de Faraday

La cage de Faraday3 est une cage qui permet d'isoler des nuisances électromagnétiques (PEM). Un calcul a été fait afin de déterminer la taille de la maille pour isoler le signal à 50Hz.
λ = c/f avec en m, c en m/s, f en Hz. D’où λ = 6.10^(6) m
Plus la longueur d’onde est grande plus la taille des mailles doit être petite. Les cages de Faraday pour se protéger du 50Hz sont peu courantes et très peu de résultats circulent dessus. Il semblerait que les calculs conventionnels (prendre λ/10 pour avoir 95% d’absorption ou λ/2 pour avoir une isolation suffisante) ne donnent pas de résultats satisfaisants pour déterminer la taille des mailles.
Cependant selon certaines recherches il semblerait que 5 mm soit efficace (ou du moins utilisé) mais aucune preuve mathématique n’est apportée. Il se trouve que certaines personnes ont déjà traité des sujets similaires sans communiquer de données concernant la taille des mailles ou le traitement du signal effectué.

Schéma du montage de la captation du signal

Schéma du montage de la captation du signal

Traitement du signal

Traitement du signal hexadécimal en décimal par l'intermédiaire du programme python "gbgb3.py" où il faut juste modifier le fichier à ouvrir en début de programme.


#! /usr/bin/env python3
# -*- coding: UTF-8 -*-

import struct

# ouverture fichier en mode binaire
f = open("VS407AF.TXT", "rb")
compteur = 0;

try:
    while True:
        # Lecture 26 octets dans le fichier
        record = f.read(26)
        if len(record) != 26:
            break;
        compteur += 1
        # Test si on est sur la ligne de #####...
        if record[:18] == b'#################\n':
            # Lit le complement et reconstitue l'enregistrement
            complement = f.read(18)
            record = record[18:] + complement

        # Ajoute un octet null tous les 3 octets a partir du 2ème caractère jusqu'à l'avant dernier
        record_4x8_octets = bytearray()
        i=1;
        while i<25:
            record_4x8_octets.append(record[i])
            if i % 3 == 0:
                record_4x8_octets.append(0) # Tous les 3 octets, on en ajoute un null
            i += 1

        # print as hex pour debug
        #print(record.hex())
        #print(record_4x8_octets.hex())

        # Converti l'enregistrement (tableau de bytes) en 8 entiers signés
        resultat_fois265 = struct.unpack('>iiiiiiii', record_4x8_octets)

        # Divise les résultats par 256 pour recadrer les 3 octets à gauche en conservant le signe
        resultat = []
        for R in resultat_fois265:
            resultat.append(R//256) # // => division entière

        # Affiche les 8 valeurs:
        print(resultat)

except IOError:
    # Traitement d'erreurs a faire ici...
    pass

finally:
    f.close()

Transformation des données brutes en son avec le logiciel gratuit en libre Audacity .

Ouvrir le logiciel --> Fichier --> Importer --> Données brutes (RAW) --> Choisir le fichier (ici VS407AF.txt)

Paramètres à modifier :
  • Encodage : Signed 24 bit PCM
  • Canaux : 8 canaux
  • Fréquence : 50 Hz

On obtient 8 pistes représentant les 8 canaux du Capteur Vegetal Signals. Il faut ensuite compresser les données en temps : Effet --> Changer le tempo --> Longueur (secondes) from : 10105,38 to : 326,00
Cette compression permet de remettre le fichier dans la bonne durée c'est-à-dire la durée initiale d'enregistrement qui est de 5min26 soit 326 secondes.
Nous obtenons un signal capté toutes les 10 millisecondes par canal.
Exporter le fichier : Fichier --> Exporter --> Export multiple --> Enregistrer tous les fichiers en 24 bit PCM en WAV

Transformation du son en signal qui peut être analysé avec le logiciel libre Scilab .

Ouvrir le logiciel --> Entrer les lignes de codes en python pour un canal

// Traitement du signal 

// Présentation du signal sur un graphique 1 
scf(1); // Ouverture de la fenêtre
y = wavread("C:\Users\isaly\OneDrive\Documents\FABLAB\TRAITEMENT_DU_SIGNAL\Audios Captés\01-VS407AF-1.wav") // Ouverture de l'emplacement du fichier
s = y(1,1:32599); //Définition de l'axe des abscisses avec un pas de 1 allant du signal 1 à 32 599 
t = linspace(0,326,32599); // Définition du temps partant de 0 à 326 secondes contenant 32599 signaux captés en 326 secondes (1 signal est capté toutes les 10 milisecs) 
plot(t,s); // Définition du graphique
xtitle("Niveau (dB)","temps en secondes") // Titre des axes

// Transformation de Fourier sur un graphique 2 
scf(2); // Ouverture de la fenêtre
x = fft(s); // Définition de l'axe des abscisses avec la transformation de Fourier
plot(abs(x)); // Définition du graphique
xtitle("Transformation de Fourier du signal") // Titre du graphique

// Transformation de Fourier centrée sur un graphique 3 
scf(3); // Ouverture de la fenêtre
plot(fftshift(x)); // Centre la transformation de Fourier
xtitle("Transformation de Fourier centrée") // Titre du graphique 

Exemple de résultat avec le fichier "01-VS407AF-1.wav" qui est le fichier contenant le son enregistré sur le premier canal.

Présentation du signal graphique 1 : Présentation du signal sur un graphique 1 issu du fichier exemple 01-VS407AF-1.wav sur Scilab
Transformation de Fourier sur un graphique 2 : Transformation de Fourier sur un graphique 2 issu du fichier exemple 01-VS407AF-1.wav sur Scilab
Transformation de Fourier centrée sur un graphique 3 : Transformation de Fourier centrée sur un graphique 3 issu du fichier exemple 01-VS407AF-1.wav sur Scilab

Logiciel OSSIA-score


Ossia score est un logiciel gratuit et open source, c'est un séquenceur interactif et intermédia. Il permet de séquencer différents types de médias et de paramètres (par exemple, des messages OSC, des fichiers sonores, des effets vidéo)... dans le temps sur une timeline. La timeline a des fonctions interactives : il est possible de spécifier qu'une partie de la partition s'exécutera lorsqu'un événement se produira, comme une note jouée, etc.

Transformation des signaux en .csv en .json compatible avec Ossia-Score avec le code "CsvToJson.py"


import csv

#Notre fichier csv a été obtenu via le code du projet transdi 2019-2020.
#Il est composé de lignes de valeurs espacées d'une ligne vide
#Ses valeurs correspondent aux 8 valeurs des capteurs à chaque unité de temps

#On crée une liste contenant 8 listes avec les valeurs pour chaque capteurs
valeurs = [[],[],[],[],[],[],[],[]]

#Permet d'ouvrir le fichier csv de lecture (r correspond au mode de lecture,
#ici lecture seule)
with open("CSVFILE.CSV",'r') as infile:
    lecture = csv.reader(infile) #On définit un objet qui lit notre fichier

#Pour les données que nous utilisons ici, nous réduissons le nombre de points trop nombreux
#pour être lu par Ossia Score. On en prend 1 sur 1000.
    compteur=0;

    for row in lecture: #On boucle sur chaque ligne du fichier
        if row: #Agit seulement sur la ligne n'est pas vide
            if compteur%50==0:
                for i in range(8):
                    valeurs[i].append(row[i])
            compteur=compteur+1

#Il faut traduire les valeurs en les remettant sur une échelle de 0 à 1 pour
#qu'elles soient compatibles avec Ossia Score :
for i in range(len(valeurs)):
    for j in range(len(valeurs[i])):
        valeurs[i][j] = float(valeurs[i][j])
        valeurs[i][j] = valeurs[i][j] + 8398930 #on remet tout en positif
        valeurs[i][j] = valeurs[i][j] / 16777216 #On met sur une échelle de 0 à 1
        valeurs[i][j] = str(valeurs[i][j])

#On récupère le script du fichier JSON
with open("scriptsignaux.json",'r') as infile:
    script = infile.readlines()

#Maintenant qu'on a nos données dans une liste, on écrit les fichiers JSON :
for i in range(8):
    with open(f"capteur{i}.layer",'w') as outfile: #On écrit un nouveau fichier (w = écriture seule) pour chaque capteur
        for j in range(48): #Les 48 premières lignes du script sont les mêmes pour tous les fichiers
            outfile.write(script[j]) #lire les lignes du fichier JSON et les copier dans le fichier

        #Insertion des valeurs : on commence par calculer l'échantillonnage (nb
        #de points)
        ech = 1 / (len(valeurs[i]) - 1)

        #Dernière valeur:
        outfile.write('{\n"uuid": "1e7cb83f-4e47-4b14-814d-2242a9c75991",\n"ObjectName": "CurveSegmentModel",')
        outfile.write(f'"id": {len(valeurs[i])-2},')
        outfile.write(f'"Previous": {len(valeurs[i])-3},')
        outfile.write('"Following": null,')
        outfile.write(f'"Start": [ {ech*(len(valeurs[i])-2)}, {valeurs[i][len(valeurs[i])-2]} ],')
        outfile.write(f'"End": [ 1.0, {valeurs[i][len(valeurs[i])-1]} ],')
        outfile.write('"Power": 1.0\n},')

        for j in range(len(valeurs[i]) - 3, 0, -1):
            outfile.write('{\n"uuid": "1e7cb83f-4e47-4b14-814d-2242a9c75991",\n"ObjectName": "CurveSegmentModel",')
            outfile.write(f'"id": {j},')
            outfile.write(f'"Previous": {j-1},')
            outfile.write(f'"Following": {j+1},')
            outfile.write(f'"Start": [ {ech*(j)}, {valeurs[i][j-1]} ],')
            outfile.write(f'"End": [ {ech*(j+1)}, {valeurs[i][j]} ],')
            outfile.write('"Power": 1.0\n},')

        #Première valeur:
        outfile.write('{\n"uuid": "1e7cb83f-4e47-4b14-814d-2242a9c75991",\n"ObjectName": "CurveSegmentModel",')
        outfile.write('"id": 0,')
        outfile.write('"Previous": null,')
        outfile.write('"Following": 1,')
        outfile.write('"Start": [ 0.0, 0.0 ],')
        outfile.write(f'"End": [ {ech*1}, {valeurs[i][0]} ],')
        outfile.write('"Power": 1.0\n}')

        for j in range(34): #les lignes 69 à 102 sont les même pour tous les fichiers
            outfile.write(script[68 + j])

Tutoriel d'utilisation du logiciel

Pour lancer sur linux :

➜ ~ cd Téléchargements
➜ Téléchargements chmod +x ossia.score-3.0.0-a22-linux-amd64.AppImage
➜ Téléchargements ./ossia.score-3.0.0-a22-linux-amd64.AppImage

Si il y a un bug d’affichage :
➜ ./ossia.score-3.0.0-a22-linux-amd64.AppImage --no-opengl

Une fois sur le logiciel, commencez par vérifier les sorties audios en allant dans settings > audio > devices > _puis choisir son périphérique de sortie.

Ensuite, désactiver le mode musical (enable musical mode) en cliquant sur la petite note de musique en bas à gauche.

Pour ajouter une courbe personnalisée, vous devez d'abord la placer dans votre user library ossia (placée dans Documents par défaut), dans Presets par exemple. Vous pouvez y placer les sorties du code cité précédemment. Une fois dans Ossia, il vous suffit de drag and drop un fichier dans la zone de travail pour l'importer. Attention à ne pas importer un fichier trop lourd qui pourrait ne pas être supporter.

Les onglets qui pourront vous servir pour la suite sont situés en bas a gauche de l'interface. Vous utiliserez le deuxième (mapping) et le troisième (user library).

Ensuite, il faut sélectionner une option de mapping, c'est à dire une transformation mathématique (linéaire ou autre) que vous voudrez appliquer à votre signal. Pour cela, allez dans l'onglet mapping et vous pourrez drag and drop a nouveau le mapping souhaité.

Enfin, vous pouvez trouver la librairie par défaut à cette adresse , si vous suivez par exemple le chemin Presets > Faust > rain.dsp, vous pouvez drag and drop le fichier rain.dsp sur votre zone de travail. Finissez par relier (point vert plein vers point vert vide) le signal au mapping puis le mapping au fichier trouver dans la librairie.

Vous pourrez obtenir un résultat de ce style.
Ossia transformation signal en son

Pistes pour la suite

La principale piste pour la suite est tout d'abord de corriger les courbes obtenues par les données pour les rendre plus précises. En effet, les modifications se font que sur quelques dizaines de milliers, ou un millions, alors que les données sont sur 160 millions. Il faut donc mettre la valeur la plus haute comme étant 1 et la plus basse comme étant 0 sur le code de transformation en json. Cela permettra d'obtenir des courbes précises dans Ossia Score.

Ensuite, il faudra créer le script Ossia permettant de transformer les courbes de données en musique. Plusieurs pistes : soit transformer les courbes en notes de musiques, avec une certaine note pour un certain intervalle de valeur, soit faire des modifications par facteurs selon les valeurs de la courbe.

Résultats

Bibliographie

1 Phloème

2 Sève élaborée par opposition à la sève brute

3 Cage de Faraday

https://sites.google.com/site/electromagnetismesante/se-proteger-des-ondes/protection-rayons-non-ionisants
https://fr.wikipedia.org/wiki/Cage_de_Faraday
https://arxiv.org/ftp/arxiv/papers/1611/1611.09766.pdf
ELECTRICAL SIGNALS IN PLANTS A PHYTL SIGNS PRIMER 10 May 2016 Carrol Plummer Research on Characteristics of Plant Electrical Signal under High Voltage Pulse
Stimulation Haiyong Weng, a, Dapeng Ye, Jingui Zheng, Haiyun Li, Xiao Liang, Shuhui Chen, Fujian Agriculture and Forestry University
Plant Electrical Signal Classification Based on Waveform Similarity Yang Chen, Dong-Jie Zhao , Zi-Yang Wang, Zhong-Yi Wang, Guiliang Tang and Lan Huang
Study and Evaluation of Plant Electrical Signal Processing Method Lu Jingxia College of Engineering Nanjing Agricultural University Nanjing, China Ding Weimin College of Engineering Nanjing Agricultural University Nanjing, China
https://fr.coursera.org/lecture/physique-optique/calcul-numerique-transformees-de-fourier-discretes-avec-scilab-1-2-thJHo
https://help.scilab.org/docs/5.3.1/fr_FR/section_391527fc8412a4b95ddd24555b4b81ab.html
https://ossia.io/