A. Theatre of Shadows_Emily Cui_Inmi Lee
B. Context and Significance
Our midterm project drew inspiration from Chinese traditional shadow play, which is an an ancient form of storytelling in which folk characters cut out of leather are held between a source of light and a translucent screen, and controlled by wooden sticks attached to their body. We recreated this existing cultural heritage by making adjustments to the ways of interaction.
To be more specific, given that most audience have no former experience engaging with shadow play, we decided to make the steps that they could possibly take simple and intuitive so that they won’t feel overburdened. This served as a practical guide and design principle for the following phases.
In addition, based on our previous definition of interaction, the conversation feature stood out the most, which led us to reflect on ways to maximize effective feedback that our project could render for the audience. Thus we thought of incorporating sensors into a wearable, which not only enables the user to mimic the movements of a professional artist, but also allows them to stand in front of the screen, being a creator and audience at the same time.
Last but not least, there is no singular objective of our project, i.e. it is not a matter of winning or losing, which implies that the experience is highly tailored to each individual, which could potentially enhance interactivity.
C. Conception and Design
Gloves, buttons, and a slide bar were the main interfaces for the users to interact with our project. which implies that we had to make the gloves both comfortable and visually appealing, while the buttons and slide bar(initially a digital sensor) should be obvious and indicative in terms of their functions.
key components and materials involved:
flex sensor– The choice of sensors practically determines how the puppets are manipulated. Though we struggled to overcome the unstability and uncertainties of it, we didn’t think of finding a substitute, as flex sensors(which meant bending fingers) could simulate the original shadow play experience at large.
servo motor– When building the kinetic wearable during recitation, we have already experimented with servo motors by connecting them with a string to create diverse effects. In the case of our project, we approached it by making simple pulley structures out of cardboard, which could trigger the movement of limbs.
stepper motor– Compared to other motors, it generates stronger force and could potentially rotate 0-360 to pull the curtains open. The choice to incorporate it into our project was inspired by a recitation prompt(the cardboard mechanism that enabled back and forth linear movement). We made some modifications by replacing the circular wheel with a linear arm, while keeping the rotating link.
curtains– The curtain is undeniably an indispensable segment of our project. It responds to the user who slides the bar that they have successfully activated the play by opening up and revealing the puppets. This design aligns with our understanding of an interactive project, which suggests intentions rather than directly giving instructions.
red cloth– Compared to having the cardboard painted in red, pieces of cloth not only makes the project neat and inviting as a whole, but also enhances fluidity and creates an immersive, theatrical atmosphere.
lighting– As we envisioned an unconventional form of shadow play, we opted for colored plastic, a LED light, and another stepper motor to make variations in lighting possible.
D. Fabrication and Production
We went through several stages of production, starting off from cutting out cardboard and framing the stage.
Delving into the most crucial step, we refined the curtains multiple times in order to make it function as planned. While Kitty focused on modifying the rotating link and linear arm to maximize the furthest distance it could allow, I did some sewing on the cloth to make a straw fit in and created prototypes. We subsequently dedicated countless hours to brainstorm a feasible way to form a solid connection between the two. Finally, we found that sewing a vertically positioned straw onto the edge of the curtains and gluing the other end to the arm helped us achieve a satisfactory result.
Moving on to its code, which was likewise troublesome, we intended to make the two sides simultaneously. Yet the stepper motor rotated successively, which confoundingly went against our expectations. Thus, we had to fit the wires that connected the two stepper motors into one single hole and execute the same code, which implied that rebuilding parts of the frame to make them face opposite directions was also necessary.
The following phase was making the puppets move according to the values read from the servo motor. We cut out a groove on top of the stage, where the wheels could fit in and smoothly rotate.
Here I must emphasize the complexity of reading, mapping, and constrain values of the eight flex sensors, as things never went as what we had expected. Their maximum and minimum values changed when we opened analogRead once in a while, and the servos malfunctioned if the constrain range was too small. The last few steps were gluing on the screen and making light related artifacts. We stuck several pieces of colored plastic on a stepper motor and wrote a code for it to rotate 90 degrees(50 steps). Every time the button is pressed, a new combination of colors will be masked over the light source, casting a different shadow on the screen.
During the user testing session, we observed a notable deficiency of our design, which was the material and size of the gloves. The cardboard was stiff, and the tape made it hard to put on, resulting in both inconvenience and inaccurate values(because the sensors weren’t exactly fixed against fingers). The users suggested that we could practically make use of a pair of one-size-fit-all gloves, which proved to be extremely helpful.
(initial cardboard version)
Additionally, we only had one main function available at that point, but the red button that was supposed to control the lighting stood out strikingly, which made users feel confusing in terms of its functions. We made adaptations accordingly by switching the button to a smaller one and arranging it in a less evident corner. The slide bar in our final production was initially two touch sensors attached to the gloves, which could theoretically sense activation and control the curtains. In practice, however, we couldn’t guarantee that the sensor will remain tightly pressed against the user’s palms throughout the entire process, which meant that the curtains might move in an unexpected manner. A majority of users also mentioned how the excessively sensitive servo motors might be problematic, as certain body parts of our puppets failed to move from time to time, which made it hard for them to learn what exactly did each finger control. This indicated our prominent task throughout the upcoming production process. In general, this session mainly served as a chance for us to make adjustments in order to create a user-friendly interface that caters to a diverse audience.
Though we did all the work together without a rigid distribution of tasks, I focused more on cardboard related components and details to make our project fulfill its technical and aesthetic goal, while Kitty took on a significant role in coding and modifying the sketches. This division of responsibilities allowed us to leverage our individual strengths effectively.
E. Conclusions
The overall objective of this project was to make shadow play more accessible by creating a context for the audience to create their own narrative and experiment with an expanded scope of functions. In retrospect, I believe that this project aligns with my definition of interaction, as it involves mutual conversations in which users trigger a response from a product, while the latter provides effective feedback(the opening and closing curtains when the bar is slid to opposite positions; the shifting color of the light when the button is pressed; the animated puppets that moves along with the bending fingers). A highly individualized and personalized experience significantly elevates its “interactivity”.
Given more time, there are several aspects that we would make improvements in. First and foremost, we would definitely figure out a way to make the curtains open wider and close smoother without obstruction. Besides, we might want to make our project more informative and entertaining by putting up the sketches of some classical plots in shadow plays and inviting the audience to try if they could make the figures move in a similar manner, with a tune or beep indicating their triumph.
One major setback we encountered was attempting to make all sensors work at the same time, so that the puppet could be smoothly manipulated. To solve this issue, we used a soldering iron to reinforce the connection between the tip of the flex sensor and the F/M wire, in case the sensor falls out of the loose, female end. Moreover, we removed the sensor to the back of the hands after brief research and testing, which enabled easier operation and more precise values.
Regardless of all the obstacles and failures, we developed proficiency in wiring, coding, as well as crafting. We also gained a more comprehensive understanding of how the motors and mechanisms functioned through hands-on experience. Although we managed to plan ahead, it was almost impossible to stick to the original plan, as things are usually more complicated than we imagine. Fortunately, we were both patient and dedicated to our project, meticulously fixing each problem and optimizing until reaching perfection. Apart from that, we also realized the importance of seeking help from others, which turned out to be of tremendous help for keeping us on the right track. In general, it was rewarding and satisfying to see how the ideas we conceived were brought to life step by step.
Finally, I would like to express gratitude to all the professors, learning assistants, and fellows who offered unconditional help and great pieces of advice. Thanks to my lovely and supportive partner Kitty and our friend Chenhan Xu, or we couldn’t have settled the obstacles and finished this project with success. My sincere gratitude is beyond any words description!
F. Disassembly
G. Appendix
curtain&light code:
// based on ConstantSpeed example
// stepper 1 controls the light
// stepper 2 and stepper 3 control the curtain
#include <AccelStepper.h>
// Stepper motor 1
int DIR_PIN1 = 2;
int STEP_PIN1 = 3;
int EN_PIN1 = 4;
int val1; //big button
int pos;
AccelStepper stepper1(AccelStepper::DRIVER, STEP_PIN1, DIR_PIN1);
// Stepper motor 2 (left)
int DIR_PIN2 = 8;
int STEP_PIN2 = 9;
int EN_PIN2 = 10;
AccelStepper stepper2(AccelStepper::DRIVER, STEP_PIN2, DIR_PIN2);
void setup() {
Serial.begin(9600);
// Stepper motor 1
pinMode(EN_PIN1, OUTPUT);
digitalWrite(EN_PIN1, LOW);
stepper1.setMaxSpeed(10000);
stepper1.setAcceleration(5000);
// Stepper Motor 2
pinMode(EN_PIN2, OUTPUT);
digitalWrite(EN_PIN2, LOW);
stepper2.setMaxSpeed(1000);
stepper2.setAcceleration(5000);
}
void loop() {
// read the big button
val1 = digitalRead(7);
Serial.println(val1);
// Stepper Motor 1
if (val1 == 1) {
pos+=50;
stepper1.runToNewPosition(pos);
delay(10);
}
int val2 = analogRead(A0);
Serial.println(val2);
// Stepper Motor 2 & 3
if (0< val2 && val2 < 400) {
stepper2.runToNewPosition(800);
} else {
stepper2.runToNewPosition(0);
}
}
puppet code1:
#include <Servo.h>
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
int val1;
int val2;
int val3;
int val4;
void setup() {
servo1.attach(9);
servo2.attach(10);
servo3.attach(11);
servo4.attach(12);
Serial.begin(9600);
}
void loop() {
val1 = analogRead(A0);
delay(10);
val1 = map(val1, 170, 300, 0, 180);
val1 = constrain(val1, 0, 180);
servo1.write(val1);
Serial.println(val1);
val2 = analogRead(A1);
delay(10);
val2 = map(val2, 270, 310, 0, 180);
val2 = constrain(val2, 0, 180);
servo2.write(val2);
Serial.println(val2);
val3 = analogRead(A2);
delay(10);
val3 = map(val3, 230, 290 , 0, 180);
val3 = constrain(val3, 0, 180);
servo3.write(val3);
Serial.println(val3);
val4 = analogRead(A3);
delay(10);
val4 = map(val4, 260, 300, 0, 180);
val4 = constrain(val4, 0, 180);
servo4.write(val4);
Serial.println(val4);
}
puppet code2:
#include <Servo.h>
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
int val1;
int val2;
int val3;
int val4;
void setup() {
servo1.attach(9);
servo2.attach(10);
servo3.attach(11);
servo4.attach(12);
Serial.begin(9600);
}
void loop() {
val1 = analogRead(A0);
delay(10);
val1 = map(val1, 50, 100, 0, 180);
val1 = constrain(val1, 0, 180);
servo1.write(val1);
Serial.println(val1);
val2 = analogRead(A1);
delay(10);
val2 = map(val2, 170, 230, 0, 90);
val2 = constrain(val2, 0, 90);
servo2.write(val2);
Serial.println(val2);
val3 = analogRead(A2);
delay(10);
val3 = map(val3, 30, 40, 0, 90);
val3 = constrain(val3, 0, 90);
servo3.write(val3);
Serial.println(val3);
val4 = analogRead(A3);
delay(10);
val4 = map(val4, 130, 190, 0, 180);
val4 = constrain(val4, 0, 180);
servo4.write(val4);
Serial.println(val4);
}