CARTE DES SAVEURS

Porteur du projet : Alizée Cazeaux

Date : DSAA 2014-2015

Licence : libre !

Contexte : Mémoire DSAA

Lien : L'épicerie graphique

Description

Sur un principe de guide, je souhaiterais amener les gens à découvrir Marseille à travers une déambulation culturelle et culinaire dans la ville. Dans une idée de transmission de savoir et savoir-faire j'aimerais faire participer la population Marseillaise.

Projet 1

Avec l'arrivée de l'hyper industrie alimentaire les familles cuisinent de moins en moins et perdent donc peu à peu ce savoir-faire Français. A travers ce premier travail je souhaiterais faire prendre conscience aux gens à quel point le goût est un sens important auquel nous ne portons pas assez attention. Il est devenu de plus en plus difficile pour nous de décrire ce que nous ressentons en mangeant et donc avoir un avis critique fondé sur les plats que nous ingérons. Dans un premier temps je vais réaliser des sondages et collectes pour observer la manière donc les gens visualisent les goûts, saveur textures, etc...

La collecte d'images

Collecte en cours. Demande : illustrer abstraitement les termes, uniquement en noir et blanc, technique libre. Mon principe étant de me focaliser sur la forme j'ai insisté sur le noir et blanc. Lors de prochains travaux je demanderais de choisir des couleurs correspondant aux termes, ainsi que des textures. Une fois la collecte terminée (lorsque je possèderais une vingtaines d'images par termes) j'analyserais et m'approprierais les images produite pour créer à mon tour un langage visuel.

Les cartes des saveurs

Une fois le vocabulaire établi je mettrais à disposition un kit ou petits et grands décrierons graphiquement les plats auxquels ils goûtent. Ce kit pouvant être objet de communication entre clients/cuisiniers, parents/enfants, ...

Projet 2

Sur le même principe d'illustration des saveurs, j'aimerai créer un programme (ou une application) avec laquelle l'interlocuteur créerais un visuel à l'aide d'une interface. Ce visuel (selon des paramètres prédéfinis) correspondrais à une recette, qui est imprimable une fois le dessin terminé.

Schéma de montage

Le programme

Le but etant de creer un programme permettant d'illustrer nos perceptions du gout, voici une premiere version afin d'aprehender la maniere de gerer des potentiometres et des boutons avec Processing et Arduino.

Ce programme constiste a creer un visuel jouant sur la taille et la transparence de cercles : un potentiometre fera varier la taille des cerles, un autre fera varier la transparence des cercles, et un bouton permetra de faire apparaitre un texte, figer l'image et l'enregistrer. (le texte variera selon la valeur d'un des potentiometres)

Pour cela il faut dans un premier temps faire la connection entre Arduino et processing en parametrant les ports utilises par les potentiometres et le bouton. Dans un second temps il faut entrer les parametres permettant de faire apparaitre les cercles et de les modifier, dans un troisieme temps il faut parametrer le moyen de faire apparaitre le texte, pour ensuite figer l'image, et l'enregistrer.

1/ LA CONNECTION PROCESSING/ARDUINO

Pour etablir la connection entre Processing et Arduino, il suffit d'utiliser le programme deja existant “SerialCallResponse” et de le modifier.

2/ LES CERLCES

Afin de creer les cercles je suis partie d'un programme permettant de reproduire une image a la maniere des pointillistes. Cette partie du programme selectionne au hasard un pixel sur une image et le redessine sous forme de cercle sur processing. Il suffit donc de charger une image, parametrer la taille des cercles ainsi que leur opacite. J'ai donc etabli un lien entre les valeurs des potentiometres et les parametres des cercles.

3/ APPARITION DES TEXTES

Dans un premier temps il faut charger une typo. Ensuite il suffit tout simplement de regler l'opacite du texte. Ainsi le texte est transparent jusqu'a ce que l'on appui sur le bouton. Je voulais que les textes varient selon la valeur de l'un des potentiometres, j'ai donc cree une condition disant que : si la valeur du potentiometre est inferieur a 100 le texte “CREME DE CITRON” apparaitra, si la valeur du potentiometre est superieur a 100 le texte “POULET AU CURRY” apparaitra.

4/ FIGER L'IMAGE

Pour figer l'image, j'ai en realite utilise une fonction permettant d'arreter le programme. Cette fonction est donc a placer a la fin du programme. Afin de pouvoir enregistrer l'image et realiser toutes les fonctions avant d'arreter le programme.

5/ ENREGISTRER L'IMAGE

Afin d'enregistrer l'image je suis partie d'un programme deja existant permettant de nommer l'image et de l'envoyer dans le dossier du programme. Il suffit ensuite de l'initialiser puis de l'articuler avec l'etat du bouton.

Pour pouvoir realiser autant de fonctions (faire apparaitre le texte, figer l'image et l'enregistrer) avec un simple bouton, j'ai du jouer sur l'etat du bouton (haut/bas) ainsi que sur son ancien etat. J'ai donc attribue certains parametres lorsque le bouton est inactif (en position haute) lorsque l'on appui dessus, lorsque l'on reste appuye (un court instant) et l'orsqu'on l'a relache.

Programmes utilises :

SerialCallResponse dans Arduino : Fichier > Exemples > Communication > SerialCallResponse dans Processing : File > Examples > Librairies > serial > SerialCallResponse

Poitillism dans Fichier > Exemples > Basics > Image > Pointillism

Save Image http://wiki.processing.org/index.php/Incrementing_numerical_filenames

ARDUINO

//// DECLARATION DES ENTIERS
int inByte = 0; // entrée d'une série de Byte
int firstSensor = 0; // premier capteur analogique
int secondSensor = 0; // deuxième capteur analogique
// Variables pour la gestion du bouton
const int BOUTON = 2; // la patte 2 du microcontroleur se nomme maintenant BOUTON
int etatBouton = 0; // la variable "etatBouton" mémorise l'état HIGH ou LOW de la pate d'entrée
int ancienEtatBouton = 0; // la variable "ancienEtatBouton" mémorise l'ancien état HIGH ou LOW de la pate d'entré
//// INSTRUCTIONS D'INITIALISATION DES RESSOURCES
void setup() {
Serial.begin(9600); // initialisation de la vitesse de transfert à 9600bps
while(!Serial) { // attendre la connection du port serie
;
}
pinMode(BOUTON, INPUT); // la patte n°2 (BOUTON) est une broche d'entrée
establishContact(); // envoyer un Byte pour etablir le contact jusqu'a ce que le recepteur reponde
}
//// INSTRUCTIONS A REPETER INFINIMENT TANT QUE LA CARTE EST SOUS TENSION
void loop() {
if (Serial.available() > 0) { // si nous obtenons un Byte valide, lire les branches analogiques
inByte = Serial.read(); // lire les Bytes entrant
firstSensor = analogRead(A0)/4; // lire la premiere entree analogique, divise par quatre pour rendre la gamme 0-255:
delay(10); // patienter 10ms
secondSensor = analogRead(1)/4; // lire la deuxieme entree analogique
etatBouton = digitalRead(BOUTON); // lire et memoriser l'etat en entree de la patte 2 (BOUTON)
// Parametrages de l'etatBouton
if(etatBouton == HIGH) { // si BOUTON est a l'etat HIGH (bouton releve, c'est a dire inactif)
etatBouton=1; // faire correspondre la valeur de l'etat HIGH a 1
}
else { // si BOUTON n'est pas a l'etat HIGH, il est a LOW
etatBouton=0; // faire correspondre la valeur de l'etat LOW a 0
}
// Envoyer les valeurs
Serial.write(firstSensor);
Serial.write(secondSensor);
Serial.write(etatBouton);
}
}
//// PARAMETRAGES POUR ETABLIR LE CONTACT
void establishContact() {
while (Serial.available() <= 0) { //instructions a executer dans la boucle tant que la condition finale n'est pas atteinte
Serial.print('A'); // envoyer la lettre A
delay(300); //patienter 300ms
}
}

PROCESSING

//// DECLARATION DES ENTIERS
// Parametrage du lien entre Arduino et Processing
import processing.serial.*; // importer de la librairie
Serial myPort;
int [] serialInArray = new int[3]; // tableau d'entree de 3 elements
int serialCount = 0;
boolean firstContact = false;
// Annoncer l'utilisation d'une image et d'une font
PImage img;
PFont font;
int smallPoint, largePoint;
int t; // t = taille des cercles
float o; // o = opacite des couleurs
int etatBouton = 1;
int ancienEtatBouton = 1;
int value = 0;
boolean doSave=false;
//// INSTRUCTIONS D'INITIALISATION DES RESSOURCES
void setup() {
size(1200, 700); // taille de la zone de travail
img = loadImage("123.jpg"); // initialisation de l'image
imageMode(CENTER); // l'image chargee se placera au centre
font = loadFont("Porto-60.vlw"); // initialisation de la fonte
smallPoint = 20; // le plus petit point mesurera 20
largePoint = 150; // le plus grand point mesurera 150
noStroke(); // les cercles n'aurons pas de contour
background(255); // le fond sera blanc
// Initialisation des ports serie
printArray(Serial.list());
println("portname");
String portName = Serial.list()[9];
myPort = new Serial(this, portName, 9600);
}
//// DESSIN D'APRES LES RESSOURCES INITIALISEES
void draw() {
String name;
// Parametrages pour les cercles
float var = map(o,250,14,20,380); // la variable var, qui agis sur la valeur o, prend les valeurs qui vont de 250 a 14 pour les transformer en valeur allant de 20 a 380
float pointillize = map(t, 0, width, smallPoint, largePoint);
int x = int(random(img.width)); // l'entier x (que l'on utilisera plus tard) ira chercher un point au hasard dans la largeur de l'image
int y = int(random(img.height)); // l'entier y (que l'on utilisera plus tard) ira chercher un point au hasard dans la hauteur de l'image
color pix = img.get(x, y); // la fonction color pix indique que la couleur dependra du x et y parametre precedemment
fill(pix, var); // remplir les cercles de la couleur du pixel selectionne au hasard sur l'image, avec une transparence variable selon le potentiometre
ellipse(x, y, pointillize, pointillize); // les cercles se placerons d'apres les points x et y releves precedemment et respecterons la map pointillize etablie
// Parametrages pour les textes
textAlign(CENTER); // aligner le texte au centre
if((var>=0) && (var<100)){ // si la valeur du potentiometre est comprise entre 0 et 100
text("TARTE AU CITRON",width/2,height/2); // ecrire "TARTE AU CITRON"
textFont(font); // Utiliser la typo initialisee precedemment
fill(0,value); // Texte en noir, la transparence sera geree par l'activitee du bouton
}
if((var>=100) && (var<380)){ // si la valeur du potentiometre est comprise entre 100 et 380
text("POULET AU CURRY",width/2,height/2); // ecrire "POULET AU CURRY"
textFont(font);
fill(0,value);
}
// Parametrages pour enregistrer l'image
if(doSave) {
name=getIncrementalFilename("sketch-####.tga"); // parametrage du nom d'enregistrement
saveFrame(name);
println("Saved "+name); // informer que l'enregistrement a ete fait
doSave=false;
}
// Parametrages du bouton
if (etatBouton ==1 && ancienEtatBouton ==1) { // si le bouton ne recoit aucun signal
value = 0; // laisser le texte transparent
}
if(etatBouton ==0 && ancienEtatBouton ==1){ // si l'on clique sur le bouton
value = 380; // modifier l'opacite du texte
ancienEtatBouton = 0; // changer l'etat de l'ancien bouton
}
if (etatBouton ==0 && ancienEtatBouton ==0) { // si on reste appuye sur le bouton(peu de temps)
doSave=true; // sauvegarder l'image
value = 380; // garder l'opacite du texte
etatBouton = 1; // changer l'etat du bouton
}
if (etatBouton ==1 && ancienEtatBouton ==0) { // si on reache le bouton
noLoop(); // arreter le programme
ancienEtatBouton = 1; // changer l'etat de l'ancien bouton
}
}
}
//// PARAMETRAGES POUR ENREGISTRER L'IMAGE PRESENTE SUR LA ZONE DE TRAVAIL
public String getIncrementalFilename(String what) {
String s="",prefix,suffix,padstr,numstr;
int index=0,first,last,count;
File f;
boolean ok;
first=what.indexOf('#');
last=what.lastIndexOf('#');
count=last-first+1;
if( (first!=-1)&& (last-first>0)) {
prefix=what.substring(0, first);
suffix=what.substring(last+1);
if(sketchPath!=null) prefix=savePath(prefix);
index=0;
ok=false;
do {
padstr="";
numstr=""+index;
for(int i=0; i<count-numstr.length(); i++) padstr+="0";
s=prefix+padstr+numstr+suffix;
f=new File(s);
ok=!f.exists();
index++;
if(index>10000) ok=true;
}
while(!ok);
if(index>10000) {
println("getIncrementalFilename thinks there is a problem - Is there "+
" more than 10000 files already in the sequence or is the filename invalid?");
return prefix+"ERR"+suffix;
}
}
return s;
}
//// PARAMETRAGES DE LA CONNECTION A ARDUINO
void serialEvent(Serial myPort) {
int inByte = myPort.read(); // lire les Bytes entrant
if (firstContact == false) { // parametre entres pour verifier le bon fonctionnement du programme
println("debut first contact");
if (inByte == 'A') { // si le premier Byte recu est un "A"
myPort.clear(); // vider la memoire tampon serie
firstContact = true; // noter que le premier contact du microcontroleur s'est effectue
println("ecriture sur le port serie de la lettre A");
myPort.write('A');
println("fin first contact");
}
}
else { // sinon ajouter le Byte entrant au tableau
serialInArray[serialCount] = inByte;
serialCount++;
if (serialCount > 2 ) { // si on a 3 Bytes, que serialCount est superieur a 2
t = serialInArray[0]; // envoyer la valeur t au premier serialInArray
o = serialInArray[1]; // envoyer la valeur o au second serialInArray
etatBouton = serialInArray[2]; // envoyer la valeur etatBouton au troisieme serialInArray
println(o + "\t" + t + "\t" + etatBouton + "\t"); // afficher les valeurs de o, t et etatBouton
myPort.write('A'); // envoyer un "A" pour demander de nouvelles captures du lecteur
serialCount = 0; // remettre a zero le serialCount
}
}
}