ARDUINO : COMMENT ENVOYER DES DONNÉES DE TYPE FLOAT, DOUBLE OU INT SUPÉRIEUR 255 VIA LE PORT SÉRIE

Porteur(s) du projet : Damien MUTI DESGROUAS

Date : 05/11/2020

Licence : libre !

Contexte : Apprentissage

introduction

Ce tutoriel permet d'étendre la notion d'affiche interactive à des objets quelconques comme par exemple des vêtements.

L'objectif est de lancer un média (son, vidéo, animation Processing) lorsque la distance détectée à l'aide d'un capteur de distance à ultrasons est inférieure à un seuil défini par l'utilisateur.

Un des enjeux est donc de lire les données issues du capteur de distance branchée sur la carte Arduino et d'envoyer ces données via le port série à l'application Processing. Ce problème est traité dans le tutoriel suivant :

Envoyer un nombre à virgule float ou double via le port Série de la carte Arduino - réception sur l'application Processing

Le programme qui suit est fortement inspiré de celui développé pour la gestion de l'interactivité des affiches interactives.

Algorithme

Si la distance détectée est inférieure à un seuil, alors lancer le média (son, vidéo, animation). Sinon arrêter le média.

Mise en œuvre

Montage

On utilise un capteur à ultrason Grove pour mesurer une distance. On envoie ensuite la distance mesurée à l'application Processing. Il convient de brancher le capteur Grove sur l'entrée digitale D7. Le montage est le suivant :

code Arduino

Le code Arduino est le suivant :

#include "Ultrasonic.h"
Ultrasonic ultrasonic(7);
void setup() {
Serial.begin(9600);
}
void loop() {
long distance;
distance = ultrasonic.MeasureInCentimeters(); // two measurements should keep an interval
Serial.print(distance);//0~400cm
//Serial.println(" cm");
delay(250);
}

Le code est disponible sur le lien suivant : ultrasonic_envoie_donn_es_port_serie.ino.zip

code Processing

Le code Processing est le suivant :

/** Affiche tactile interactive -
* Quand on appuie sur une touche (UP, DOWN, RIGHT, LEFT et espace ' '), cela lance une image, une vidéo, une annim, un son, etc...
*/
/// librairies
import processing.sound.*;
import processing.video.*;
import processing.serial.*;
// variables globales
PImage im; // une image
SoundFile son; // un son - un seul lecteur CD audio
Movie vid; // une vidéo - un seul lecteur DVD vidéo
// bouton image active ? // est-ce que l'image est active ? Si oui, on affiche l'image
boolean animation_active = false; // true ou false (2 valleurs possibles) => 1 bit (0 ou 1)
// bouton son actif ?
boolean son_actif = false;
float tempsDebutSon = 0; // temps du début de la musique a été joué
// bouton video active ?
boolean video_active = false;
/// dialogue avec la carte Arduino
Serial myPort; // Create object from Serial class
String inBuffer; // Data received from the serial port
int donneePortSerie; // entier converti de la chaine de caractère reçue sur le port série
// seuil de détection
float seuil = 25;
// compteur boucle draw()
//int nbLoopDraw = 0;
void setup() { // initialisation des paramètres d'affichage & chargement des sons, vidéos, etc.
size(500, 500);
noStroke();
background(0);
// initialisation des variables globales
im = loadImage("images/chien.jpg");
// chargement du son
son = new SoundFile(this, "sons/beat.aiff");
//println(son.duration());
// chargement de la video
vid = new Movie(this, "videos/affiche.mp4");
/// Port série
// Print a list of the serial ports, for debugging purposes:
printArray(Serial.list());
String portName = Serial.list()[32];
myPort = new Serial(this, portName, 9600);
}
void draw() {
// lecture des données sur le port série :
lectureDonneePortSerie();
// test des données lues sur le port série et choix de l'interactivité (vidéo, son, animation)
// choisir le média à lancer :
// son
//gestionSon("sons/beat.aiff");
// video
gestionVideo("videos/ArmstrongAlunissage.mp4"); // "videos/affiche.mp4"
// animation
gestionAnimation();
// affichage de la vidéo ////////////////////////////////////////
if (video_active) {
image(vid, 0, 0, width, height);
} else {
background(0); // fond noir
}
// affichage de l'animation//////////////////////////////////////
if (animation_active) {
lancerAnimation();
}
}
//////////////////////////////////// Méthodes ////////////////////////
void movieEvent(Movie movie) { //// gestion de la vidéo
vid.read();
}
void lectureDonneePortSerie() { //////////// lecture et conversion des données issues du port série
//String inBuffer="";
// lecture des données sur le port série
if ( myPort.available() > 0) { // si une donnée est disponible sur le port série
inBuffer = myPort.readString(); // lire la donnée et la stoquer dans inBuffer (chaine de caractères - String)
}
//conversion des données String -> int
if (inBuffer != null) { // si la chaine de caractère n'est pas nulle
//println("inBuffer="+inBuffer +"(String)"); //afficher la chaine de caractère inBuffer
donneePortSerie=int(inBuffer); // convertir la chaine de caractère en un entier
// affichage de la distance en cm
println("Distance = "+donneePortSerie+" cm"); // afficher l'entier correcpondant
}
}
/////////////////////////////////////////////// Son ///////////////////////////////////////////////////
void gestionSon(String nomDuSon) {
if (donneePortSerie < seuil && donneePortSerie>0 && !son.isPlaying()) { // son
// jouer le son SSI la distance est inférieur à un seuil, strictement supérieure à 0 et si le son ne joue pas déjà
//affichage de la distance lue
println("Distance = "+donneePortSerie+" cm");
// lancement du son
lancerSon(nomDuSon);
} else if (donneePortSerie > seuil && son.isPlaying()) { //si la distance est supérieure au seuil ET que le son joue : arrêter le son
son.stop();
}
}
void lancerSon(String nomDuSon) {
if (!son.isPlaying()) { // le son ne joue pas
// chargement du son 1
son = new SoundFile(this, nomDuSon);
// jouer le son 1
son.loop();
}
}
//////////////////////////////////////////////// Video ///////////////////////////////////////////////////
void gestionVideo(String nomVideo) {
if (donneePortSerie < seuil && donneePortSerie>0 && !video_active) { // video
// jouer le son SSI la distance est inférieur à un seuil, strictement supérieure à 0 et si la vidéo ne joue pas déjà
//affichage de la distance lue
println("Distance = "+donneePortSerie+" cm");
// lancement du son
lancerVideo(nomVideo);
} else if (donneePortSerie > seuil && video_active) { //si la distance est supérieure au seuil ET que la video joue : arrêter la video
vid.stop();
clear();
video_active = false;
}
}
void lancerVideo(String nomVideo) {
if (video_active == false) { // la vidéo 1 ne tourne pas
// chargement de la video 1
vid = new Movie(this, nomVideo );
vid.loop();
video_active = true;
}
}
//////////////////////////////////////////////// animation ///////////////////////////////////////////////////
void gestionAnimation() {
if (donneePortSerie > 100) { // on appuie sur la touche "espace" => lancer l'animation "image"
animation_active = true;
} else {
animation_active = false;
}
}
void lancerAnimation() {
float x = 30 + random(-20, 20); // random sur la position
float y = 30 + random(-20, 20);
image(im, x, y, 200, 200);
}

Le code est disponible sur le lien suivant : lecture_donnees_port_serie.pde.zip

Discussion : mesure d'une autre grandeur que la distance

La grandeur physique mesurée dans cette étude est la distance.

Le programmes Arduino précédent peut être aisément modifié si le capteur utilisé mesure une autre grandeur physique telle que la température (capteur CTN), la force de pression (capteur piézo-électrique), la flexion (capteur “flexo”), etc...

En revanche le programme Processing peut être utilisé tel-quel en prenant simplement soin de bien définir la valeur du seuil de détection associée à la grandeur physique choisie.