Matérialité

Porteur(s) du projet : Lucile Dubrana

Date : 14/01/2019

Licence : libre !

Contexte : Évaluation des compétences de programmation des cartes Arduino et d’utilisation des différents capteurs.

Description du projet arduino

Dans la perspective du développement de mon mémoire de deuxième année, développement des objets graphiques/physiques interactifs basés sur l'utilisation d'une carte Arduino et d'un ou plusieurs capteurs. Dans le cadre de mon mémoire, j'aimerais travailler sur la notion de « matérialité » employé dans le métier du design: métier au sein duquel nous manipulons et transformons constamment la matière.

Description du sujet de mémoire

Au sein des métiers du design, la matière possède un rôle phare. Nous la manipulons et la transformons constamment. Cependant, la nature de cette matière change depuis quelques années et cela avec les avancées technologiques entraînant des changements de mode de production et de diffusion. En effet, ce mode se tourne de plus en plus vers la numérisation. La plupart du temps, on désigne le numérique comme immatériel pourtant il constitue une matière de nature et de l’ordre de l’«hypermatière ». L’Hypermatérialité est un terme qui tente de penser ce qui a été dénommé à tort l’immatériel.

Le fait est qu’on ne travaille plus forcement de la matière solide et que l’on se tourne donc vers une matière de moins en moins solide par cet emploi des technologies et du numérique. Pourtant lorsque l’on utilise le numérique et les technologies, on crée de l’informations pour créer. Ces informations font offices de matières. L’information est un processus ou se produisent des états de matière par l’intermédiaire de matériels, d’appareils, de dispositifs techno-logiques qui contrôlent ce processus aux échelles du nanomètre et de la nanoseconde - où ce n’est pas seulement ce qui duplique qui est matériel, mais aussi ce qui est dupliqué. On aperçoit un changement de la nature des informations : on passe d’une création basé sur des informations/des données analogiques ( opposé au numérique, ex: écrits/ machine manuel ) à une création basé sur des informations/ des données/ des valeurs numériques.

L'idée de ce projet est donc de prouver cette nouvelle matière

Enjeux du projet

Prouver cette nouvelle matière par le bug:Le Glitch Le Glitch est une corruption de code ou de données ou manipulations d'appareils électroniques. Il a pour effet de décaler les pixels constituant une image. La modulation des données prouvent qu'elles sont à l'origine de l'image: elles sont donc la matière qui constitue l'image. Pour construire ce projet, on va plus précisément générer du bug par du Pixel Sort Le Pixel Sort est un effet intéressant, se rapprochant du glitch, qui commande sélectivement les pixels dans les lignes / colonnes d'une image. Il a été popularisé par l'artiste Kim Asendorf. Ici, le programme de Pixel Sorting se présente sous la forme d'un programme Processing

Références

Le Glitch a été reconnu comme un art, alors que des artistes visuels comme Serge Uro (dès 2004 sur le site fotolog) ou Tony “Ant” Scott commencent à adopter le glitch comme une esthétique de l'ère numérique et à créer une maîtrise de ce qui se voulait être un bug à l'origine, c'est. l'artiste Ryoji Ikeda qui se dissocie dans son approche. Ryoji Ikeda est un artiste créant du glitch. Pour cela il créé des programmes capables de convertir n’importe quelles informations en motif visuel et sonore. Utilise des coordonnées géographique et des erreurs de disques dures pour composer des images abstraites et génère le bug de manière aléatoire comme le veut la nature propre du bug.

Liens: http://www.ryojiikeda.com

Matériaux

Carte seeduino

Processing:https://processing.org/download/?processing + librairie (dans exemple) Processing.serial

Arduino:https://www.arduino.cc

Potentiomètre:http://wiki.seeedstudio.com/Grove-Slide_Potentiometer/

Un potentiomètre est un type de résistance variable à trois bornes, dont une est reliée à un curseur se déplaçant sur une piste résistante terminée par les deux autres bornes. Ce système permet de recueillir, entre la borne reliée au curseur et une des deux autres bornes, une tension qui dépend de la position du curseur et de la tension à laquelle est soumise la résistance.

Montage

Le montage est très simple, il suffit de brancher à l'aide d'un port usb la carte seeeduino à ton ordinateur et de brancher sur une sortie analogique choisit et précisé sur Arduino le potentiomètre Ici la sortie est la A0

Tutoriels

Méthode1

Télécharger processing+ Script ASDFPixelSort pour Processing asdfpixelsort2.zip

Décompresser le dossier ASDFPixelSort.zip

Ouvrir le fichier ASDFPixelSort.pde

Choisir l'image voulue, la glisser dans le dossier ASDFPixelSort( attention le programme est assez long pour des raisons pratiques je recommande de l'organiser)

De retour dans ASDFPixelSort.pde, Pour indiquer au programme quelle image doit être utilisée, insérer le nom de l'image (ici test) entre les guillemets dans la ligne StringimgFileName =

Indiquer l'extension (ici jpg) de l'image choisie entre les guillemets, dans la ligne suivante

Indiquer la taille de l'image a traiter plus bas, dans la ligne Size située un peu plus bas. Ici l'image choisie ou adapté l'image à l'écran.

Liste numérotéeChoisir le mode de rendu de l'image. Le mode 0 travail sur les noirs, le mode 1 sur les lumières intermédiaires et le mode 2 sur le blanc.

Pour lancer le programme, cliquer sur l'icône play

Voici les différents types de résultats obtenus selon les 3 modes de rendements.

MODE 0

MODE 1

MODE 2

Le rôle et l'utilisation du potentiomètre

Ici, le potentiomètre intervient afin de varier entre ces 3 modes définis. Pour faire intervenir le potentiomètre, il faut télécharger la librairies Processing.serial

Processing

( actuellement non fonctionnel pour le raccord Arduino)

//// librairies
import processing.serial.*;
Serial myPort; // appel à la class processing.serial
int mode = 0;
// variables globales
// nom et type image
String imgFileName = "test";
String fileType = "png";
int loops = 1;
// variable Le mode 0 travail sur les noirs, le mode 1 sur les lumières intermédiaires et le mode 2 sur le blanc.
int blackValue = -16000000;
int brightnessValue = 60;
int whiteValue = -13000000;
// pour déterminer des coordonnées
int row = 0;
int column = 0;
boolean saved = false;
// communication série
Serial myPort; // Create object from Serial class
float val; // Data received from the serial port
void setup() {
//chargement image
img = loadImage(imgFileName+"."+fileType);
size(1, 1);
// redimensionnement accordé ( true) et mettre à jour la surface aux dimensions de l'image
surface.setResizable(true);
surface.setSize(img.width, img.height);
// load image onto surface - scale to the available width,height for display
image(img, 0, 0, width, height);
// initialisation du port série
printArray(Serial.list());// liste de tous les ports séries disponibles
String portName = Serial.list()[0];// sortie 0
myPort = new Serial(this, portName, 9600);// unité de fréquence / rapidité généralement à 9600 (en baud)
}
void draw() {
// faire une boucle dans les colonnes
while (column < img.width-1) {
println("Sorting Column " + column);
img.loadPixels();
sortColumn();
column++;
img.updatePixels();
}
// faire une boucle dans les rangés
while (row < img.height-1) {
println("Sorting Row " + column);
img.loadPixels();
sortRow();
row++;
img.updatePixels();
}
// ajustement à la largeur et à la hauteur de l'écran
image(img, 0, 0, width, height);
if (!saved && frameCount >= loops) {
// sauvegarde
img.save(imgFileName+"_"+mode+".png");
saved = true;
println("Saved "+frameCount+" Frame(s)");
// exiting here can interrupt file save, wait for user to trigger exit
println("Click or press any key to exit...");
}
}
void sortColumn() {
// current column
int x = column;
// emplacement du début du sorting
int y = 0;
// emplacement de fin du sorting
int yend = 0;
while (yend < img.height-1) {
switch(mode) {
case 0:// case correspond aux modes et définit des coordonnées
// les modes sont assimilés à Y qui varient selon if
y = getFirstNotBlackY(x, y);
yend = getNextBlackY(x, y);
break;
case 1:
y = getFirstBrightY(x, y);
yend = getNextDarkY(x, y);
break;
case 2:
y = getFirstNotWhiteY(x, y);
yend = getNextWhiteY(x, y);
break;
default:
break;
}
if (y < 0) break;
int sortLength = yend-y;
color[] unsorted = new color[sortLength];
color[] sorted = new color[sortLength];
for (int i=0; i<sortLength; i++) {
unsorted[i] = img.pixels[x + (y+i) * img.width];
}
sorted = sort(unsorted);
for (int i=0; i<sortLength; i++) {
img.pixels[x + (y+i) * img.width] = sorted[i];
}
y = yend+1;
}
}
// black x
int getFirstNotBlackX(int x, int y) {
while (img.pixels[x + y * img.width] < blackValue) {
x++;
if (x >= img.width)
return -1;
/// affichage des images
if (val>0 && val<255) { // valeur avec potentiomètre
image( getFirstNotBlackX,0,0); //afficher image taille et position
}
return x;
}
int getNextBlackX(int x, int y) {
x++;
while (img.pixels[x + y * img.width] > blackValue) {
x++;
if (x >= img.width)
return img.width-1;
}
return x-1;
}
// brightness x white x mode 0
int getFirstBrightX(int x, int y) {
while (brightness(img.pixels[x + y * img.width]) < brightnessValue) {
x++;
if (x >= img.width)
return -1;
/// affichage des images
if (val>0 && val<255) { // valeur avec potentiomètre
image( getFirstBrightX,0,0); //afficher image taille et position
}
return x;
}
int getNextDarkX(int _x, int _y) {
int x = _x+1;
int y = _y;
while (brightness(img.pixels[x + y * img.width]) > brightnessValue) {
x++;
if (x >= img.width) return img.width-1;
}
return x-1;
}
// white x mode 1
int getFirstNotWhiteX(int x, int y) {
while (img.pixels[x + y * img.width] > whiteValue) {
x++;
if (x >= img.width)
return -1;
}
return x;
}
int getNextWhiteX(int x, int y) {
x++;
while (img.pixels[x + y * img.width] < whiteValue) {
x++;
if (x >= img.width)
return img.width-1;
}
return x-1;
}
// black y
int getFirstNotBlackY(int x, int y) {
if (y < img.height) {
while (img.pixels[x + y * img.width] < blackValue) {
y++;
if (y >= img.height)
return -1;
}
}
return y;
}
int getNextBlackY(int x, int y) {
y++;
if (y < img.height) {
while (img.pixels[x + y * img.width] > blackValue) {
y++;
if (y >= img.height)
return img.height-1;
}
}
return y-1;
}
// brightness y
int getFirstBrightY(int x, int y) {
if (y < img.height) {
while (brightness(img.pixels[x + y * img.width]) < brightnessValue) {
y++;
if (y >= img.height)
return -1;
}
}
return y;
}
int getNextDarkY(int x, int y) {
y++;
if (y < img.height) {
while (brightness(img.pixels[x + y * img.width]) > brightnessValue) {
y++;
if (y >= img.height)
return img.height-1;
}
}
return y-1;
}
// white y
int getFirstNotWhiteY(int x, int y) {
if (y < img.height) {
while (img.pixels[x + y * img.width] > whiteValue) {
y++;
if (y >= img.height)
return -1;
/// affichage des images
if (val>0 && val<255) { // valeur avec potentiomètre
image( getFirstBrightX,0,0); //afficher image taille et position
}
}
return y;
}
int getNextWhiteY(int x, int y) {
y++;
if (y < img.height) {
while (img.pixels[x + y * img.width] < whiteValue) {
y++;
if (y >= img.height)
return img.height-1;
}
}
return y-1;
}

Arduino

#define POTENTIOMETRE A0// la sortie
int sensorValue = 0; // variable to store the value coming from the sensor
void setup() {
//init du port serie
Serial.begin(9600);
}
void loop() {
// lire une valeur relative au potentiomtre4
sensorValue = analogRead(POTENTIOMETRE); // valeurv entre 0 et 1023
// écriture de la valeur sur le port série
Serial.println(sensorValue); // valeur entière donnée par floor() entre 0 et 255
}

Méthode2

La méthode 2 demande au préalable de “glitcher”les images et de les afficher à l'aide du potentiomètre. De ce fait, on se retrouve à manipuler uniquement des images et non des pixels.

Pour cela, il suffit d'enregistrer les photos construisent via le programme processing, soit de construire les images avec photoshop mais pour bien comprendre le propos de ce projet qui repose sur la manipulation de l'informations, il est également intéressant de modifier direction le code source de l'image avec un éditeur de texte ce que laissera place à une nouvelle image.

Exemple

Ici j'ai changé au hasard le code source de l'image test. J'ai ainsi modifié sa structure en effaçant quelques lignes. }}

Evolution

Processing

// librairies
import processing.serial.*;
// variables globales
int x;
int y;
int a;
int b; // attributs des images
PImage photo; //créer la classe de l'image 1
PImage photo1; //créer la classe de l'image 2
PImage photo2; //créer la classe de l'image 2
PImage photo3;
// communication série
Serial myPort; // Create object from Serial class
float val; // Data received from the serial port
void setup() {
size (1000, 1000);
noStroke () ;
photo = loadImage("test.png"); // image "1.jpg"
photo1 = loadImage("test2.png"); // image "2.jpg"
photo2 = loadImage("test3.png");
photo3 = loadImage("test4.png");
x = 1;
y = 1;
a = 1 ;
b = 1 ;
// initialisation du port série
printArray(Serial.list());// liste de tous les ports séries disponibles
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
}
void draw () {
//// lecture des données issues de la carte Arduino
if ( myPort.available() > 0) { // If data is available,
String inString = myPort.readStringUntil('\n');
if (inString != null) {
inString = trim(inString); // trim off whitespaces.
val = float(inString); // convert to a number.
}
// code de nous
// val = myPort.read(); // read it and store it in val
// affichage de la valeur lue sur le port
println(val);
}
/// affichage des images
if (val>0 && val<255) { // valeur avec potentiomètre
image(photo, O, 0, 429, 597) ; //afficher image taille et position
}
if (val>511 && val<765) { // valeur avec potentiomètre
image(photo1, O, 0, 429, 597); //afficher image taille et position
}
if (val>766 && val<1021) { // valeur avec potentiomètre
image(photo2, 230, O, 0, 429, 597); //afficher image taille et position
}
if (val>58) { // valeur avec potentiomètre
image(photo3, O, 0, 429, 597); //afficher image taille et position
}
}

====Arduino====
#define POTENTIOMETRE A0
int sensorValue = 0; // variable to store the value coming from the sensor
void setup() {
//init du port serie
Serial.begin(9600);
}
void loop() {
// lire une valeur relative au potentiomtre4
sensorValue = analogRead(POTENTIOMETRE); // valeurv entre 0 et 1023
// écriture de la valeur sur le port série
Serial.println(sensorValue); // valeur entière donnée par floor() entre 0 et 255
}

A tout problème sa solution!

Des problèmes avec la carte ? Pour utiliser la carte seeeduino on peut régler le type de carte sur Arduino genuine uno si la lecture se veut être difficile, selon la version d'arduino on peut télécharger le type de carte propre à Seeeduino ici: http://wiki.seeedstudio.com/Seeed_Arduino_Boards/?fbclid=IwAR3tEpM0W87C4-mUmbBwKBDZp7yxQhi-cvS-zMyPBymwlTA8ogwv78TG9hM

Si ton ordinateur à une sortie en USB C et qu'il faut un adaptateur pour brancher la structure..cependant le port n'est pas détecté.. solution ?