Rebellious Chairs ENSAD + MIT 2012

Group 6 – Lucien

LUCIEN :


Martin Le Tiec and Ludovic Leger

Lucien is a chair which follows a close cycle of getting energy from sun and using his energy to follow it continiously and again and again. To be “sitable”, the chair must be rotate face to face with sun, and user must accept chair orientation.

Vidéo prototyping :

Fonctionnement :

 

Nous avons placé deux capteurs de lumière (photorésistences) symétriquement de part et d’autre du dossier

Nous demandons ensuite au moteur de toujours s’ajuster afin que les deux capteurs reçoivent la même quantité de lumière :

Si le capteur de gauche reçoit plus de lumière que celui de droite, le moteur se tourne vers la droite et inversement

 

 

 

Montage électronique :

Code arduino :

// Code Lucien : faire tourner un servomoteur dans la directin d'une source de lumière
// Workshop Rebellious Chairs MIT/EnsAD 2012

#include

int leftEyePin = A1; // pin d'entrée analogique de la photorésistence de gauche
int rightEyePin = A2; // pin d'entrée analogique de la photorésistence de droite
int threshold = 20; // seuil de tolérence afin d'avoir une réaction uniquement au dela d'un certain différenciel, pour éviter que le moteur bouge au moidre changement de lumière
int servoValue; // valeur en degré du servomoteur

// Variables pour la calibration des photorésistences
// Code de calibration des photorésitence d'origine : http://arduino.cc/en/Tutorial/Calibration by David Mellis

int rightSensorValue = 0;
int rightSensorMin = 1023;
int rightSensorMax = 0;

int leftSensorValue = 0;
int leftSensorMin = 1023;
int leftSensorMax = 0;

Servo lucien; // nom du servomoteur

void setup() {
   Serial.begin(9600);
   lucien.attach(9);
   pinMode(A1, INPUT);
   pinMode(A2, INPUT);
   servoValue=90; // centre le moteur au démarrage du code
   calibrateEyes(); // lance le code de calibration avant le tracking
   }

void loop() {

   int rightEye = analogRead(rightEyePin); // lit la valeur de la photorésistence de droite
   int leftEyeBrut = analogRead(leftEyePin); // lit la valeur de la photorésistence de gauche

// Les photorésistences ne captant rarement exactement les mêmes valeurs pour un même éclairage,
// On map les valeurs de la photorésistence de droite sur les valeurs de la photorésistence de gauche
// Pour cela on utilise les valeur min et max des photorésistence définies dans la calibration.

   int leftEye = map(leftEyeBrut, leftSensorMin, leftSensorMax, rightSensorMin, rightSensorMax);

   Serial.print("Right Eye");
   Serial.println(rightEye);

   Serial.print("left Eye brut");
   Serial.println(leftEyeBrut);

   Serial.print("Left Eye");
   Serial.println(leftEye);

// Si la valeur de la photorésistence de droite moins celle de la photorésistence de gauche est supérieur au seuil de tolérence
// c'est que la résistence de droite capte plus de lumière que celle de gauche

   if(rightEye - leftEye > threshold) {
      if(lucien.read()<120) {   // empêche le moteur d'aller entre 170° et 180°
// on demande donc au moteur de s'orienter vers la gauche
      Serial.println("<----------------- got to LEFT");      
      servoValue+=2;
      }
   }   

// et inversement ...   

      else if (leftEye - rightEye > threshold) {

         if(lucien.read()>10){   // empêche le moteur d'aller entre 0° et 10°
         Serial.println("got to RIGHT ------------->");
         servoValue-=2;
         }
      }

// dans tout les autre cas c'est que le différentiel des deux photorésistence est en dessous du seuil de tolérence

          else {
          Serial.println("don't move");
// on lit donc la valeur actuel du moteur et on l'applique à la valeur cible
          servoValue = lucien.read();
          }
   delay(200); // un delay pour contrôler la vitesse de réaction
   lucien.write(servoValue); // on applique au moteur la valeur d'orientation

}

// foncton calibration (inspiré par le code de D. Mellis)

void calibrateEyes() {

// calibrate RIGHT EYE during the first 10 seconds

   pinMode(13, OUTPUT);
   digitalWrite(13, HIGH);

   while (millis() < 10000) {
      rightSensorValue = analogRead(rightEyePin);        

      if (rightSensorValue > rightSensorMax) {
         rightSensorMax = rightSensorValue;  // record the maximum sensor value
         }

      if (rightSensorValue < rightSensorMin) {
         rightSensorMin = rightSensorValue; // record the minimum sensor value
         }
      }

// signal the end of the calibration period
   digitalWrite(13, LOW);

// signal the interval between calibration of right eye and left eye
   blinkFast(13);

// calibrate LEFT EYE during the first 10 seconds

   digitalWrite(13, HIGH);
   int currentTime=millis();

   while (millis() < currentTime+10000) {
      leftSensorValue = analogRead(leftEyePin);   

      if (leftSensorValue > leftSensorMax) {
         leftSensorMax = leftSensorValue; // record the maximum sensor value
         }

      if (leftSensorValue <  leftSensorMin) {
         leftSensorMin = leftSensorValue; // record the minimum sensor value
      }
   }

   digitalWrite(13, LOW);
// signal the end of the calibration period
}

void blinkFast(int ledPin) {

   for(int i = 0; i< 20; i++) {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
   }
}