Découvrez nos Tutos, pour apprendre à hacker son biofeedback.
Tuto Good Vibes

Tutoriel Good Vibes 05 – construire son capteur de fréquence cardiaque – monter et tester son capteur DIY
Mon capteur cardiaque : montage et test
Pour la dernière étape de cette séquence, nous allons connecter notre capteur à notre microntrôleur.
Le capteur PulseSensor dispose de trois PIN, dont on peut voir sur l’image suivante que leurs fonctions sont indiquées au dos du capteur : un +, un -, et un S pour Signal.

Vous connecterez le + au PIN 3V de la Feather, le – au PIN GND (pour Ground, la masse), et le S, comme indiqué dans le code, sur le PIN A0 (qui correspond à l’entrée analogique 0).
Le montage doit suivre les schémas suivants :
Branchez maintenant votre microcontroleur à votre ordinateur, et ouvrez votre IDE avec le code des sections précédentes.
Dans la liste des cartes disponibles, sélectionnez la Feather M0 d’Adafruit.

Puis dans les Ports, sélectionnez celui qui correspond à votre carte (sur Linux, ce sera probablement le porte ACM0, peut-être ACM1, …)
Enfin, cliquez sur le bouton de vérification du code

Si des erreurs apparaissent, vérifiez que vous avez bien recopié le code donné ici, que tout parenthèse ouvrante possède sa copine fermante, que les ; sont placés aux bons endroits, et essayer de déchiffrer les messages qui s’inscrivent en bas de l’IDE.
Une fois que c’est bon, ouvrez la console d’affichage de votre IDE, et modifiez les paramètres comme dans la vidéo suivante, avant de cliquer sur Upload.
Le code est chargé dans le microcontrôleur. Si aucune erreur n’est décelée, des informations doivent s’afficher dans votre console.
Posez le doigt sur la lumière verte de votre capteur (pas du côté de l’électronique, mais de l’autre), et votre fréquence cardiaque devrait rapidement s’afficher.
Vous pouvez aussi positionner le capteur sur votre poignet, par exemple sous un bracelet qui le maintient en contact avec la peau.
La dernière étape consiste à vérifier que les bonnes informations sont transmises par Bluetooth.
Ouvrez à nouveau l’application BLE Scanner sur votre smartphone, sélectionnez votre capteur, cliquez sur le service 0x180D et observez les données qui devraient se mettre à jour.
Si elles s’affichent correctement, vous avez désormais un capteur maison qui vous permet de récupérer votre activité cardiaque et de la communiquer par Bluetooth à d’autres programmes, qu’ils soient sur vos ordis, vos smartphones, ou ailleurs.

Tutoriel Good Vibes 04 – construire son capteur de fréquence cardiaque – les fonctions setup() & loop()
Mon capteur cardiaque : fonctions setup() & loop()
Nous allons voir ici les deux fonctions les plus importantes dans un code Arduino standard.
La fonction setup()
Appelée une fois par le code, elle servira à initialiser vos variables, paramètres et objets.
Dans notre cas, elle est un peu longue, surtout à cause de la définition des comportements du module Bluetooth.
La voici intégralement :
void setup() { Serial.begin(115200); // set parameters for the PulseSensor pulseSensor.analogInput(PULSE_INPUT); pulseSensor.setSerial(Serial); pulseSensor.setThreshold(THRESHOLD); pulseSensor.begin() ; // activate BLE Module ble.begin() ; // reset all parameters ble.factoryReset() ; // don't repeat any sent command in the terminal ble.echo(false) ; // check if version is enough to support consistant connexion if ( !ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) ) { error( F("Callback requires at least 0.7.0") ) ; } // Give a name to your device that will be seen on the network ble.sendCommandCheckOK(F("AT+GAPDEVNAME=BlePulseSensor")) ; // Clean any previous Service/Characteristic if (! ble.sendCommandCheckOK( F("AT+GATTCLEAR"))) { error(F("Could not clear services and characteristics")) ; } // add a custom service Serial.println(F("Adding the Heart Service definition (UUID = 0x180D): ")) ; customServiceId = gatt.addService(0x180D) ; if (customServiceId == 0) error(F("Could not add Heart service")) ; // add a heartrate characteristic with notification of an array of 1 value Serial.println(F("Adding the custom notifiable characteristic definition (UUID = 0x2a37): ")) ; customNotificationCharId = gatt.addCharacteristic(0x2a37, GATT_CHARS_PROPERTIES_NOTIFY, 1, 1, BLE_DATATYPE_BYTEARRAY, "Heart Rate") ; if (customNotificationCharId == 0) error(F("Could not add heartrate notification characteristic")) ; // add the heart service to the advertising data (needed for Nordic apps to detect the service) Serial.print(F("Adding Custom Service UUID to the advertising payload: ")); uint8_t advdata[] { 0x02, 0x01, 0x06, 0x03, 0x02, 0x0d, 0x18} ; ble.setAdvData( advdata, sizeof(advdata) ) ; // reset your BLE module ble.reset() ; }
Pour comprendre à quoi correspond chaque ligne, je vous invite à lire dans un premier temps les commentaires dans le code (les textes qui se trouvent soit entre deux “balises” * et *, soit sur une ligne démarrant par //.
Les commentaires sont des morceaux de texte dans un code qui 1/ ne seront pas compilés, 2/ sous certaines conditions peuvent être utilisés pour automatiser la production d’une documentation.

Nous allons toutefois entrer dans les détails de quelques lignes.
ble.sendCommandCheckOK(F("AT+GAPDEVNAME=BlePulseSensor")) ;
Cette ligne permet de définir le nom sous lequel notre périphérique apparaîtra lorsqu’il sera scanné sur les réseaux. On peut le laisser libre ou au contraire suivre un certain nombre de règles qui permettront par exemple de mieux l’identifier sur nos applications futures en filtrant les dipositifs scannés par leur nom.
customNotificationCharId = gatt.addCharacteristic(0x2a37, GATT_CHARS_PROPERTIES_NOTIFY, 1, 1, BLE_DATATYPE_BYTEARRAY, "Heart Rate") ;
C’est peut-être la commande la plus importante. Elle définit les format et modalités de notification de notre caractéristique.
Le premier paramètre (0x2a37) correspond à ce que l’on appelle l’UUID de notre caractéristique. Elle est importante ici, car elle répond aux spécifications GATT (voir partie 01 du tuto à ce sujet), et sera ainsi reconnue comme une caractéristique notifiant la fréquence cardiaque.
Le second paramètre est celui qui indique que notre caractéristique utilise les notifications. Elle pourrait être en effet de différents types :
- GATT_CHARS_PROPERTIES_BROADCAST
- GATT_CHARS_PROPERTIES_READ
- GATT_CHARS_PROPERTIES_WRITE_WO_RESP
- GATT_CHARS_PROPERTIES_WRITE
- GATT_CHARS_PROPERTIES_NOTIFY
- GATT_CHARS_PROPERTIES_INDICATE
Les chiffres 1 et à nouveau 1 indiquent ici le nombre minimal et le nombre maximal de valeurs qui seront envoyées à chaque fois.
Enfin, BLE_DATATYPE_BYTEARRAY signifie que nous enverrons nos données sous la forme d’un tableau de bytes, mais nous pourrions avoir choisi les autres types suivants :
- BLE_DATATYPE_AUTO
- BLE_DATATYPE_STRING
- BLE_DATATYPE_BYTEARRAY
- BLE_DATATYPE_INTEGER
Le type auto n’est pas un type en soit, mais on signifie par là que le type de variable envoyée déterminera le type. Mouais ^^ pas hyper conseillé.
Egalement, le type INTEGER a tout l’air d’une bonne idée au début, plus facilement manipulable que les tableaux de bytes. C’est sans compter les habitudes prises de l’autre côté par les librairies. La plupart attendront soit des bytes soit des strings, et il sera très difficile de les nourrir avec autre chose.
On vous conseille donc de rester le plus possible avec des tableaux de bytes, de choisir le type string lorsque c’est vraiment nécessaire, et d’oublier les autres.
Le dernier paramètres de la fonction est une chaîne de caractère qui sera affiché dans la description de notre caractéristique. Elle sera très utile pour des personnes qui souhaitent comme vous connaître un peu plus ce qu’il se passe sous le capot.
Et rien ne vous empêche d’y laisser de petits messages persos 😉
Et voilà, nos modules bluetooth et PulseSensor ont été initialisés, et chacun vit désormais sa propre vie. Le capteur capte et le bluetooth streame.
Maintenant, il nous faut récupérer les informations du capteurs et les transmettre au module bluetooth pour qu’il les communique. C’est notre dernière étape, la fonction loop, qui comme son nom l’indique bien sera appelée en boucle par le microcontroleur Feather.
C’est notre dernière étape, elle est plus simple et plus rapide.
La fonction loop()
void loop() { if (pulseSensor.sawNewSample()) { // look if a pulse has been detected if (pulseSensor.sawStartOfBeat()) { // get value and send through gatt object uint8_t dataForNotification = pulseSensor.getBeatsPerMinute() ; gatt.setChar(customNotificationCharId, &dataForNotification, 1) ; } } }
Cette fonction permet de vérifier à l’acquisition de chaque nouveau sample par le capteur si un “Beat” a été détecté, soit une durée entre deux pics.

Si c’st le cas, alors nous récupérons la valeur calculée par la librairie, qui est ici la fréquence instantanée. La fréquence instantanée se définit par l’inverse (multiplié par 60 pour convertir en BPM) de l’intervalle entre deux pics, appelé IBI. On a donc FC = 60/IBI.
Une fois que cette fréquence est calculée, nous la passons à l’objet GATT qui la notifiera à tous les périphériques à l’écoute.
Voici le code dans son intégralité :
#define USE_ARDUINO_INTERRUPTS false #include <Arduino.h> #include <PulseSensorPlayground.h> #include “BluefruitConfig.h” #include “Adafruit_BLE.h” #include “Adafruit_BluefruitLE_SPI.h” #include “Adafruit_BluefruitLE_UART.h” #include “Adafruit_BLEGatt.h” const int PULSE_INPUT = A0 ; const int THRESHOLD = 550 ; int32_t customServiceId ; int32_t customNotificationCharId ; PulseSensorPlayground pulseSensor ; #define MINIMUM_FIRMWARE_VERSION “0.7.0” Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST) ; Adafruit_BLEGatt gatt(ble) ; void error(const __FlashStringHelper * err) { Serial.println(err) ; while(1) ; } void setup() { Serial.begin(115200); // set parameters for the PulseSensor pulseSensor.analogInput(PULSE_INPUT); pulseSensor.setSerial(Serial); pulseSensor.setThreshold(THRESHOLD); pulseSensor.begin() ; // activate BLE Module ble.begin() ; // reset all parameters ble.factoryReset() ; // don't repeat any sent command in the terminal ble.echo(false) ; // check if version is enough to support consistant connexion if ( !ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) ) { error( F("Callback requires at least 0.7.0") ) ; } // Give a name to your device that will be seen on the network ble.sendCommandCheckOK(F("AT+GAPDEVNAME=BlePulseSensor")) ; // Clean any previous Service/Characteristic if (! ble.sendCommandCheckOK( F("AT+GATTCLEAR"))) { error(F("Could not clear services and characteristics")) ; } // add a custom service Serial.println(F("Adding the Heart Service definition (UUID = 0x180D): ")) ; customServiceId = gatt.addService(0x180D) ; if (customServiceId == 0) error(F("Could not add Heart service")) ; // add a heartrate characteristic with notification of an array of 1 value Serial.println(F("Adding the custom notifiable characteristic definition (UUID = 0x2a37): ")) ; customNotificationCharId = gatt.addCharacteristic(0x2a37, GATT_CHARS_PROPERTIES_NOTIFY, 1, 1, BLE_DATATYPE_BYTEARRAY, "Heart Rate") ; if (customNotificationCharId == 0) error(F("Could not add heartrate notification characteristic")) ; // add the heart service to the advertising data (needed for Nordic apps to detect the service) Serial.print(F("Adding Custom Service UUID to the advertising payload: ")); uint8_t advdata[] { 0x02, 0x01, 0x06, 0x03, 0x02, 0x0d, 0x18} ; ble.setAdvData( advdata, sizeof(advdata) ) ; // reset your BLE module ble.reset() ; } void loop() { if (pulseSensor.sawNewSample()) { // look if a pulse has been detected if (pulseSensor.sawStartOfBeat()) { // get value and send through gatt object uint8_t dataForNotification = pulseSensor.getBeatsPerMinute() ; gatt.setChar(customNotificationCharId, &dataForNotification, 1) ; } } }
Il est temps maintenant de brancher nos câbles et de vérifier la bonne exécution du code.

Tutoriel Good Vibes 03 – construire son capteur de fréquence cardiaque – les premières lignes de code
Mon capteur cardiaque : premières lignes de code
Tout est prêt désormais pour coder votre carte, afin qu’elle récupère la fréquence cardiaque et la stream par Bluetooth en respectant les protocoles GATT évoqués.
Nous allons ici utiliser une carte de développement Adafruit Feather M0 BLE, proche des cartes Arduino mais intégrant les fonctionnalités pour pouvoir utiliser les capacités Bluetooth simplement et rapidement.

Il est assez standard de décomposer son code Arduino en cinq parties. Nous verrons les trois premières dans cette section, puis les deux plus importantes dans la prochaine.
L’invocation des librairies externes
Tout en haut du code, vous allez copier les lignes suivantes :
#define USE_ARDUINO_INTERRUPTS false #include <Arduino.h> #include <PulseSensorPlayground.h> #include “BluefruitConfig.h” #include “Adafruit_BLE.h” #include “Adafruit_BluefruitLE_SPI.h” #include “Adafruit_BluefruitLE_UART.h” #include “Adafruit_BLEGatt.h”
La première ligne définit une variable que la librairie PulseSensorPlayground.h utilisera pour savoir si elle gère sa gestion du signal avec ou sans requête d’interruptions. Sans entrer dans les détails, l’utilisation des interruptions est en général une meilleure stratégie, mais elle n’est pas prise en charge facilement pour les cartes Feather qui fonctionnent différemment des Arduino classiques.
Les lignes suivantes correspondent à des bibliothèques de variables et fonctions dont nous aurons besoin ensuite pour développer notre capteur connecté.
Attention, l’une de ces bibliothèques doit être manuellement placée dans le même répertoire que notre fichier de code Arduino. Téléchargez le fichier suivant (TODO LIEN), trouvez où se trouve votre fonction (vous pouvez regarder dans les paramètres de Files / Preferences pour savoir où l’IDE enregistre vos fichiers), et copier ce fichier dans le même répertoire que votre fonction.
La définition des variables globales
Les variables globales sont des variables auxquelles toutes les fonctions pourront accéder.
En programmation, toutes les variables ont une portée. En général, les variables définies dans une fonction n’existent pas en dehors de cette fonction, et on les partage donc de différentes manières.
Les variables globales sont accessibles par toutes les fonctions.
Nous allons donc copier les lignes suivantes :
const int PULSE_INPUT = A0 ;
Il s’agit d’indiquer dans le code à quel PIN sera connecté notre capteur sur la carte Feather.
const int THRESHOLD = 550 ;
C’est une valeur qui servira de seuil dans le traitement des informations du capteur. En deçà de ce seuil, les données recueillies par le capteur ne sont pas traitées, ce qui évite par exemple certains bruits de données. Cette valeur est un peu arbitraire, libre à vous de jouer avec pour tester la robustesse de votre propre capteur et l’adapter.
int32_t customServiceId ; int32_t customNotificationCharId ;
Ces deux variables serviront à définir nos services et caractéristiques Bluetooth.
Nous définissons ensuite nos deux objets :
PulseSensorPlayground pulseSensor ;
Il s’agit du capteur PulseSensor
#define MINIMUM_FIRMWARE_VERSION “0.7.0” Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST) ; Adafruit_BLEGatt gatt(ble) ;
La première ligne signifie que le module Bluetooth de la carte devra avoir une version de son firmware (son code interne) au moins égale à 0.7.0.
Si ce n’est pas le cas, vous devrez mettre à jour votre puce Bluetooth.
Ensuite, il s’agit d’une variable “Objet” qui contient les informations permettant de gérer la puce Bluetooth.
La troisième ligne correspond à une troisième variable “objet” qui encapsule la première et simplifie la déclaration des comportements de communication Bluetooth, en accord avec le protocole GATT.
Mettre à jour son firmware :
Téléchargez l’application BluefruitConnexion. Activez votre bluetooth et votre localisation.
Dans la liste des objets bluetooth détectés, sélectionnez le vôtre (probablement Bluefruit quelque-chose), connectez-vous, descendez sur Updates, et installez la dernière version (0.8.1 à ce jour).
Les fonctions annexes
En plus des fonctions classiques de l’environnement Arduino, nous pourrions avoir besoin d’autres fonctions. Ici, nous n’en aurons qu’une, courte :
void error(const __FlashStringHelper * err) { Serial.println(err) ; while(1) ; }
Sans entrer dans les détails, c’est fonction qui permet d’afficher dans la console de l’IDE un message d’erreur, et de bloquer la carte à cette endroit.
L’instruction while(1) est en effet ce que l’on appelle une boucle infinie : elle s’exécute TANT QUE (while) 1 (donc tout le temps :D).
Nous sommes prêt.e.s désormais pour les dernières étapes du code, à découvrir dans la section suivante.

Tutoriel Good Vibes 02 – construire son capteur de fréquence cardiaque – installer son environnement de développement.
Mon capteur cardiaque : configurer l’IDE
Dans cette section, nous allons préparer notre environnement pour pouvoir développer sur des cartes compatibles arduino, afin de fabriquer une première version de notre propre capteur cardiaque.
Pour pouvoir utiliser les cartes compatibles Arduino, nous aurons besoin de l’environnement de développement (IDE) d’Arduino, téléchargeable ici.

Vous pourriez vouloir installer directement à partir des dépôts, par exemple en tapant si vous êtes utilisateur.rice d’Ubuntu :
> sudo apt install arduino
Je vous le déconseille, ayant expérimenté à chaque fois des problèmes de compatibilité dès que je souhaitais utiliser une bibliothèque externe.
Une fois installé, il vous faut modifier quelques paramètres, qui nous permettront par la suite d’utiliser d’une part les cartes fournies par Adafruit, dont la Feather M0 BLE qui permet une gestion simplifiée du bluetooth, et d’autres part les capteurs que nous allons tester, à savoir le PulseSensor dans un premier temps.
Pour ajouter la définition des cartes de développement distribuées par Adafruit, dans le menu Files, allez dans Preferences. Dans le champs Additional Boards Manager URLs, copiez le lien suivant : https://adafruit.github.io/arduino-board-index/package_adafruit_index.json, puis relancez l’IDE.

Ensuite, dans le menu Tools, le sous-menu Boards, sélectionnez Boards Manager, tapez Feather M0 dans le champs de recherche, et cliquez sur Install.

Maintenant, nous allons dans le menu Sketch, le sous-menu Include Library, et cliquez sur Manage Libraries. Cherchez “adafruit bluefruitLE”, et installez la librairie.

Vous êtes prêt.e.s désormais pour utiliser les cartes de développement Feather et leurs fonctionnalités de communication Bluetooth.
Nous utiliseront dans un premier temps le Pulse Sensor, bien connu de la communauté Arduino.

A nouveau, il faut télécharger la librairie correspondante. Dans Sketch / Include Library / Manage Libraries, sélectionnez maintenant PulseSensor Playground et installez la bibliothèque.

Tout est prêt désormais pour coder votre carte, afin qu’elle récupère la fréquence cardiaque et la stream par Bluetooth en respectant les protocoles GATT évoqués.

Tutoriel Good Vibes 01 – utiliser son bracelet, sa montre ou sa ceinture thoracique connectée
Mon propre capteur est-il compatible ?
Notre objectif est de construire une interface complète permettant de récupérer d’un côté la fréquence cardiaque d’une personne, et de l’autre de faire vibrer un coeur tangible à cette même fréquence.
Ainsi, nous pourrons « donner notre coeur » à quelqu’un, avoir les un.e.s et les autres « nos coeurs sur la main », mais surtout faire ensemble l’expérience aux frontières de l’intime de la manière dont nos corps réagissent durant nos interactions.
La connexion entre le capteur pourra être réalisée avec un Raspberry, ou une application mobile qui agira comme intermédiaire. Nous explorerons les deux approches.
Dans un premier temps, nous avons besoin d’obtenir la fréquence cardiaque.
Le plus simple est d’utiliser un capteur existant, tel que les montres ou bracelets connecté.e.s. Ils prennent et fournissent une donnée (plus ou moins) fiable que l’on peut récupérer par Bluetooth.
Toutefois, il existe des standards pour consulter ces données plus facilement, et tous les dispositifs du commerce ne sont pas égaux sur le respect de ces normes.
Chez Ullo, nous utilisons par exemple des bracelets Pulseon ou Mio qui respectent les règles de définition des services, caractéristiques et descripteurs correspondant aux spécifications GATT.
Pour savoir si votre dispositif respecte les protocoles GATT pour la diffusion des données cardiaques, vous pouvez procéder d’au moins deux manières.
L’application mobile Ble Scanner (Android & IOS)
- téléchargez l’application Ble Scanner, activez votre Bluetooth et la localisation (nécessaire pour scanner les périphériques Bluetooth autour de vous) :

- trouvez votre dispositif et connectez-vous :

- si dans la section Advertiment Data, vous voyez le service HeartRate, alors vous pouvez utiliser votre appareil.

- vous pouvez vérifier son fonctionnement en descendant dans les services et en sélection le service 0x180D :

- vous devriez voir la caractéristique HEART RATE MEASUREMENT (ou HRM), avec une propriété NOTIFY. Si c’est le cas, vous avez le matériel nécessaire. De plus, si votre dispositif est actif et streame les données, alors vous devriez avoir cette image sur votre écran, et voir les données se mettre à jour en temps réel.

Utiliser Gatttool en ligne de commande (Linux)
Une deuxième façon de valider la compatibilité de votre dispositif, plus geek, consiste à utiliser l’outil gatttool en ligne de commande.
Vous devez d’abord récupérer l’adresse MAC de votre dispositif, qui est un identifiant unique de celui-ci.
Pour cela, ouvrez un terminal et entrez la ligne suivante :
> bluetoothctl
Vous devriez arriver sur une invite de commande comme celle-ci :

Rentrez dans un premier temps la commande suivante :
> scan on
puis, pour interrompre le scan :
> scan off
Votre dispositif est apparu normalement avec son adresse mac, comme le mien sur cet écran :

Vous pouvez maintenant sortir de bluetoothctl en tapant soit Ctrl+d, soit
> exit
Maintenant, entrez dans votre terminal la commande suivante :
> gatttool -I -b MAC_ADDRESS -t random
en remplaçant MAC_ADDRESS par l’adresse MAC de votre capteur récupérée plus haut grâce à bluetoothctl.

Vous devriez arriver sur une nouvelle invite de commande dans laquelle vous entrerez
> connect
Il se peut que rien ne se passe. Si c’est le cas, sortez de gatttool (ctrl+d ou tapez exit), puis changez random pour public, soit :
> gatttool -I -b MAC_ADDRESS -t public
puis :
> connect
Si l’une ou l’autre des deux commandes a fonctionné, vous êtes connecté.e à votre dispositif bluetooth.
Tapez alors :
> primary
pour avoir une liste des services.
Par exemple, chez moi, sur mon bracelet cardiaque :

Vous devriez voir le service 0x180D qui correspond aux services cardiaques selon le protocole GATT.
Vous souhaitez maintenant lister les caractéristiques du service 0x180D. Vous devriez avoir sur la ligne deux valeurs, qui correspondent au “handle” de démarrage des caractéristiques liées au service, et le “handle” de fin (le handle correspond à une adresse qui permet d’accéder aux objets services, caractéristiques, etc).
Pour cela, tapez dans l’invite de commande :
> char-desc 0x1234 0x5678
où 1234 et 5678 correspondent à vos propres handles.
Par exemple, dans mon cas, on peut voir sur l’image plus haut que mes handle d’entrée et de sortie sont 0x000b et 0x0010.
Je tape donc :
> char-desc 0x000b 0x0010
Je vois alors apparaître une nouvelle liste d’adresses :

Si mon dispositif respecte les standards GATT, je dois voir une addresse commençant par 00002a37.
Juste en dessous, vous devriez avoir une caractéristique commençant par 00002902. Notez son handle. Elle est utilisée pour signifier à l’objet que l’on va écouter ses notifications.
Entrez :
> char-write-req 0xZZZZ 0100
avec 0xZZZZ votre handle (pour moi 0x000e)
Vous devriez alors voir les données cardiaques apparaîtrent, et peut-être même plus (certains dispositifs utilisent cette caractéristique par exemple pour communiquer une suite d’IBI, comme sur l’écran suivant).

Sur cette vidéo, nous voyons apparaître des lignes de longueurs inégales. Elles sont constituées de plusieurs valeurs hexadecimales.
La première est l’identification de la caractéristique dont on écoute les notifications, la seconde est la fréquence cardiaque (en hexadécimal : si vous lisez 40, votre fréquence est égale à 4×16 + 0 = 64). Les valeurs suivantes sont les IBI (Inter Beats Interval) que l’on peut utiliser par exemple pour calculer la fréquence instantanée, ou la variabilité cardiaque.
Si vous êtes satisfait.e.s de votre dispositif, vous pouvez aller maintenant :
- soit construire votre coeur tangible qui vous permettra de transférer votre activité cardiaque
- soit télécharger l’application dans le store et utiliser le vibreur de téléphone
- soit développer votre propre application
Si vous souhaitez développer votre premier capteur d’acquisition de l’activité cardiaque, rendez-vous sur ce tutoriel.

Tutoriel Good Vibes – Présentation
Présentation
Nos interactions sociales reposent en grande partie sur les signaux physiologiques que nous échangeons de manière explicite et/ou implicites. Qu’elles soient verbales ou non-verbales, nos conversations sont irriguées par des informations discrètes, qui échappent à la conscience immédiate, et qui pourtant structurent l’essentiel de nos échanges.
Nous faisons par exemple l’expérience de la difficulté d’une animation de parole en visio. Nous ne percevons en effet pas les respirations des un.e.s et des autres, alors que cette donnée est essentielle aux mécanismes de transmission de la parole [1][2].
Chez Ullo, nous travaillons depuis plusieurs années sur les mécaniques de synchronicités physiologiques et leur renforcement par la technologie. Savez-vous par exemple quand et pourquoi nos rythmes cardiaques peuvent se synchroniser ? De nombreuses études scientifiques analysent les liens entre synchronisation cardiaque et des sentiments de confiance, des situations de séduction, d’autorité consentie, de respect en d’empathie [3][4][5].
Plus étrange mais probablement plus récurrents, les mécaniques de couplages de l’activité cérébrale font aussi l’objet d’études poussées. On voudra citer en premier cette étude [6] sur le couplage de zones cérébrales au sein d’un couple se tenant la main et dont une des deux personnes est souffrante.
Quand la situation est telle que la relation physique et ces échanges d’informations sont rendus sinon impossible, du moins compliqués, la technologie peut être un moyen de transporter la physiologie et la cognition, d’abolir la contrainte spatiale, et redonner de la “chair” à notre communication.
Nous vous proposons ici une première expérience “transcommunicative”, qui permet à une personne de sentir les pulsations cardiaques d’une autre, à distance, et ainsi à chacun.e d’offrir son coeur à ses proches.
En Japonais, cela se dit Ishin Denshin, soit la possibilité de communiquer par le coeur ce que l’esprit ressent.
Nous proposons ici une série de tutoriels qui vous permettront de construire chez vous les composantes nécessaires. Nous couvrirons l’élaboration des capteurs (acquisition de la fréquence cardiaque) et actuateurs (petits coeurs tangibles), ainsi que d’une application mobile qui permettra la mise en relation de deux personnes éloignées.