3. Dezember 2010
Der oTTomat, kurz, oTTo Kontext Arbeitsprozess Innert zwei Wochen wurde oTTo erschaffen, in der Ersten die Konzeptplanung und das Szenario, in der Zweiten, die physische Umsetzung, die Programmierung und Illustration. Für den Prototyp von oTTo wurden folgende Materialien verwendet: - 16 LED's, welche in der vertikalen in drei Sektoren aufgeteilt sind - 1 LED-Treiber (TLC5940) - 3 Bewegungssensoren, welche die LED-Sektoren aktivieren, deaktivieren und die Distanz messen, um die Intensität des Lichtes zu regeln - 1 Servomotor mit einem roten LED, welcher sich um 180° dreht, um die Umgebung zu scannen. - 2 Arduinos (vorläufig, siehe Programmierung) - 1 Styroporkugel Verschiedene Anordnungen der LED's wurden ausprobiert, um die drei Sektoren optimal zu nutzen. Aufgrund des geringen Platzes im Innern von oTTo kam die Verkabelung nur schleppend voran. Mit dieser Lichtintensität wurde nicht gerechnet, die Entwickler sind beinahe blind. Interaktion mit der Umgebung oTTo scannt mit seinem wachen Auge in raschen Abständen die Umgebung ab. Sobald physische Energie in Richtweite ist, verlangsamt sich die Scanfunktion und oTTo bejaht oTTo den Zustand, indem er die LED's in horizontaler Achse hinauf und herunter laufen lässt. In dieser Zeit erfasst der zuständige Bewegungssensor das Objekt und die LED's, welche diesem Sensor zugeteilt sind, beginnen die vorhandene Energie in Licht umzuwandeln. Je geringer die Distanz zwischen oTTo und der Energie quelle ist, desto heller und hochfrequenziger leuchten die LEDs. Somit wird dem Objekt sämltiche Energie entzogen und das Gebiet wird zur oTTomaren Zone erklärt. Sobald dieser Zustand erreicht ist, verneint oTTo, indem er die LED's in vertikaler Achse nach rechts, bzw. links kurz aufleuchten lässt. oTTonom verlässt oTTo die Zone und begibt sich auf die Suche nach vorhandener Energie. Programmierung Schwierigkeiten: Die Schwierigkeiten bei der Programmierung lagen beim Zusammenfügen der einzelnen Codeteile. So funktionierten die Servo- und LED-Steuerungen alleine einwandfrei, zusammen jedoch nicht mehr. Das lag daran, dass die Servo-Klasse gewisse Outputs des Arduino blockierte, welche für den LED-Treiber benötigt wurden. Wir probierten den Servo manuell mit PWM-Output-Spannungen oder mit einem Servo-Treiber zu steuern. Beides funktionierte nicht zuverlässig und die Zeit reichte nicht aus, um dem Problem auf den Grund zu gehen. Deshalb entschieden wir uns den Servo vorläufig mit einem zweiten Arduino zu steuern. Die Programmierung des LED-Treibers (TLC5940) funktionierte mit den vordefinierten Klassen und Funktion recht gut. Es brauchte jedoch einiges an Zeit, sie zu verstehen und für unser Projekt entsprechend zu nutzen. Vereinfachter Programmablauf als Flussdiagramm: Arduino Sourcecode:#include <Tlc5940.h> #include <tlc_fades.h> //inputs #define sensor1 A0 #define sensor2 A1 #define sensor3 A2 TLC_CHANNEL_TYPE channel; // variables int sensor1_state = false; int sensor2_state = false; int sensor3_state = false; int led_max = 2000; // maximum brightness of a led (0-4095) int led_min = 30; // minimum brightness (0-4095) int sensoren_aktiv = false; // led arrays int led_row1[] = {0,6,10}; int led_row2[] = {1,2,7,11,12}; int led_row3[] = {3,4,8,13,14}; int led_row4[] = {5,9,15}; void setup() { // define in-/outputs pinMode(sensor1, INPUT); pinMode(sensor2, INPUT); pinMode(sensor3, INPUT); // initialize tlc (led-driver) Tlc.init(); Serial.begin(9600); } void loop() { sensor_check(); } void sensor_check() { // if no sensor is active if (analogRead(sensor1) < 200 && analogRead(sensor2) < 200 && analogRead(sensor3) < 200) { // if at least one sensor has been active before if (sensoren_aktiv == true) { // say "no" nein(); } sensoren_aktiv = false; } // if all sensors are active at the same time switch to discomode if (analogRead(sensor1) > 200 && analogRead(sensor2) > 200 && analogRead(sensor3) > 200) { discomode(); } // if sensor 1 receives data input if (analogRead(sensor1) > 200) { // if at least one sensor has been active before turn led-sector 1 on if (sensoren_aktiv==true) { sensor1_state = 1; led1(); // if no sensor has been active before say "yes" } else { ja(); } // if sensor 1 receives no data input turn led-sector 1 off } else { sensor1_state = 0; led1_out(); } // if sensor 2 receives input data if (analogRead(sensor2) > 200) { // if at least one sensor has been active before turn led-sector 2 on if (sensoren_aktiv==true) { sensor2_state = 1; led2(); // if no sensor has been active before say "yes" } else { ja(); } // if sensor 2 receives no data input turn led-sector 2 off } else { sensor2_state = 0; led2_out(); } // if sensor 3 receives input data if (analogRead(sensor3) > 200) { // if at least one sensor has been active before turn led-sector 3 on if (sensoren_aktiv=true) { sensor3_state = 1; led3(); // if no sensor has been active before say "yes" } else { ja(); } // if sensor 3 receives no data input turn led-sector 3 off } else { sensor3_state = 0; led3_out(); } Serial.print(sensor1_state); Serial.print(" "); Serial.print(sensor2_state); Serial.print(" "); Serial.println(sensor3_state); Serial.print(analogRead(sensor1)); Serial.print(" "); Serial.print(analogRead(sensor2)); Serial.print(" "); Serial.println(analogRead(sensor3)); } // turn led sector 1 on void led1() { // sector 1 includes led 0-5 for (int channel=0; channel < 6; channel++) { if (tlc_fadeBufferSize < TLC_FADE_BUFFER_LENGTH - 2) { if (!tlc_isFading(channel)) { uint16_t duration = 200000 / analogRead(sensor1); int maxValue = pow(analogRead(sensor1), 3) * 0.00001; uint32_t startMillis = millis() + 50; uint32_t endMillis = startMillis + duration; tlc_addFade(channel, led_min, maxValue, startMillis, endMillis); tlc_addFade(channel, maxValue, led_min, endMillis, endMillis + duration); } } tlc_updateFades(); } } // turn led sector 1 off void led1_out() { for (int channel = 0; channel < 6; channel++) { Tlc.set(channel, 0); } Tlc.update(); } // turn led sector 2 on void led2() { // sector 2 includes led 6-9 for (int channel=6; channel < 10; channel++) { if (tlc_fadeBufferSize < TLC_FADE_BUFFER_LENGTH - 2) { if (!tlc_isFading(channel)) { uint16_t duration = 200000 / analogRead(sensor2); int maxValue = pow(analogRead(sensor2), 3) * 0.00001; uint32_t startMillis = millis() + 50; uint32_t endMillis = startMillis + duration; tlc_addFade(channel, led_min, maxValue, startMillis, endMillis); tlc_addFade(channel, maxValue, led_min, endMillis, endMillis + duration); } } tlc_updateFades(); } } // turn led sector 2 off void led2_out() { for (int channel = 6; channel < 10; channel++) { Tlc.set(channel, 0); } Tlc.update(); } // turn led sector 3 on void led3() { // sector 3 includes led 10-15 for (int channel=10; channel < 16; channel++) { if (tlc_fadeBufferSize < TLC_FADE_BUFFER_LENGTH - 2) { if (!tlc_isFading(channel)) { uint16_t duration = 200000 / analogRead(sensor3); int maxValue = pow(analogRead(sensor3), 3) * 0.00001; uint32_t startMillis = millis() + 50; uint32_t endMillis = startMillis + duration; tlc_addFade(channel, led_min, maxValue, startMillis, endMillis); tlc_addFade(channel, maxValue, led_min, endMillis, endMillis + duration); } } tlc_updateFades(); } } // turn led sector 3 off void led3_out() { for (int channel = 10; channel < 16; channel++) { Tlc.set(channel, 0); } Tlc.update(); } // turn on disco mode (knightrider led 0-15) void discomode() { for (int counter=0; counter<2; counter++) { int direction = 1; for (channel = 0; channel < 16; channel+=direction) { Tlc.clear(); Tlc.set(channel, led_max); Tlc.update(); delay(25); if(channel == 15) { direction = -1; } } } } // say "yes" (move led row from top to the bottom and back) void ja() { for (int counter=0; counter < 2; counter++) { for (int i=0; i<3; i++) { Tlc.set(led_row1[i], led_max); } Tlc.update(); delay(100); Tlc.clear(); for (int i=0; i<5; i++) { Tlc.set(led_row2[i], led_max); } Tlc.update(); delay(100); Tlc.clear(); for (int i=0; i<5; i++) { Tlc.set(led_row3[i], led_max); } Tlc.update(); delay(100); Tlc.clear(); for (int i=0; i<3; i++) { Tlc.set(led_row4[i], led_max); } Tlc.update(); delay(100); Tlc.clear(); for (int i=0; i<5; i++) { Tlc.set(led_row3[i], led_max); } Tlc.update(); delay(100); Tlc.clear(); for (int i=0; i<5; i++) { Tlc.set(led_row2[i], led_max); } Tlc.update(); delay(100); Tlc.clear(); } sensoren_aktiv=true; } // say "no" (move led col from left to right and back) void nein() { for (int counter=0; counter<2; counter++) { for (int i=0; i<6; i++) { Tlc.set(i, led_max); } Tlc.update(); delay(100); Tlc.clear(); for (int i=6; i<10; i++) { Tlc.set(i, led_max); } Tlc.update(); delay(100); Tlc.clear(); for (int i=10; i<15; i++) { Tlc.set(i, led_max); } Tlc.update(); delay(100); Tlc.clear(); for (int i=6; i<10; i++) { Tlc.set(i, led_max); } Tlc.update(); delay(100); Tlc.clear(); } }