PROCESS¶
Workflow
QUESTIONNAIRE¶
I developed a questionnaire that explores a person’s feelings of belonging, identity, and relationships. The responses are translated into parameters that shape the design of a personalized mold for growing roots. The questionnaire was shared with people in my surroundings who wished to participate in the project and grow roots themselves within their individually generated mold. 10 persons were participating in Amsterdam, Leiden and Hamburg.
PARAMETRIC DESIGN¶
Questionnaire to parametric design¶
First, I needed to determine which parameters from my questionnaire should correspond to specific aspects of the design in Rhino.
I found that working with Voronoi cells provided an effective way to incorporate multiple parameters. Since I had already explored this approach during Computational Couture Week, I was able to build on my prior experience.
Nonetheless, Asli supported me in setting up the design and assessing what was feasible without making the process overly complex. As a result, I arrived at the following mapping.
Grasshopper¶
At the beginning of the project, I decided that the general shape of the molds should be rectangular, each measuring 20 by 20 cm. This format allows the different pieces to fit together neatly and creates a visual effect similar to a quilted blanket.
To set up the design, I first created a rectangle in Rhino that served as reference geometry. I then defined it as a bounding box, ensuring that all transformations and design variations would occur within these fixed boundaries. This approach helped keep the design organized and consistent across all modules.
For the questionnaire, I linked each question to a slider in Grasshopper. Every slider controlled a specific design parameter, meaning that the values gathered from the questionnaire directly influenced the geometric outcomes in the model.
Remapping A crucial step in the process was remapping the parameter values. It wasn’t practical to simply use slider values ranging from 1 to 10, as defined in the questionnaire, because many of the design parameters required different numerical ranges. Therefore, I had to translate or “remap” the values so that they worked correctly within the design logic.
For example, a range from –20 to 50 in Grasshopper needed to be scaled to correspond to the 1–10 range of the questionnaire responses. This ensured that the relationship between the user’s input and the resulting geometry remained meaningful and consistent.
Shape Diver¶
To make both the questionnaire and the Grasshopper file accessible to everyone, I decided to upload the project to ShapeDiver. ShapeDiver converts a Grasshopper file into a user-friendly, web-based interface, allowing anyone to interact with the sliders, respond to the questionnaire directly, and immediately see how the design changes in real time.
The uploading process itself is quite straightforward. However, there are a few important steps to prepare the file before uploading to ensure everything functions smoothly.
Important steps before uploading to ShapeDiver
-
Internalize all geometry: Any geometry referenced from Rhino must be internalized within the Grasshopper file. This ensures that the model is complete and independent of any external links.
-
Check the plugins: ShapeDiver does not support all Grasshopper plugins. It’s important to review and, if necessary, replace unsupported components before uploading.
From questionnaire to an individual mold
Click here to create you own mold in ShapeDiver
Collection of participants moldes
MOLDES¶
When I started designing the molds, I had a quilted blanket in mind to connect the pieces of all participants. That’s why I chose a rectangular shape
Types of moldes¶
Comparisson of moldes
Assembling the moldes
Here you can see the first test of moldes. I would recommend to laser cut the double sided tape before laser cutting, so it is way easier to fixate the parts. The solution using sand to make the tape non-sticky didn't work out as the roots grew through the sand and got stuck onto the glue.
ROOTS¶
Seeds¶
I worked with what grass and barley. They both worked but wheat gras is chaper and worked a bit better as it was sprouting faster then the barley. So I would recommend using wheat grass.
Growing Roots¶
FROM SEEDS TO A ROOTS BLANKET
How to grow roots
The seeds need to be soaked in vinegar for 20 minutes, then rinsed and soaked again in water for about 8 hours or overnight. After that, place them in a sprouting container with a transparent lid. This worked best for me because it kept the seeds moist (solving my main issue of dryness) while allowing airflow thanks to the 10 cm gap between the seeds and the lid. Using cling film didn’t work as well—it encouraged mold.
The container should be placed in a bright spot; a windowsill worked perfectly. The seeds sprouted in about 2–3 days, during which I rinsed them twice daily.
Once sprouted, I transferred them into the molds. Ideally, they should be sprayed 2–3 times per day, but when that wasn’t possible, I fully rinsed them once or twice daily to keep moisture levels high.
Main Difficulties
-
Drying out—especially over weekends or during the day, where I couldn't access the lab
-
Insufficient light
-
Mold caused by excessive moisture or poor airflow (it spreads easily between molds) - A small amount of mold doesn’t affect root growth, but roots should be autoclaved then after harvesting.
-
Room temperature fluctuations
Growing Light and Box
The best results came without using a growing box or artificial light—sunlight alone was sufficient. Even multiple growing lights didn’t encourage better growth. I’d recommend placing molds near a window and using grow lights only additionally on cloudy days.
Harvesting¶
I harvested when the roots appeared long enough. Initially, I used two layers of tulle to cut between roots and seeds, but the fabric tore and made cutting difficult. Switching to aluminum mesh worked much better—it’s durable. Or if growing inside a sprout box cutting if off the plastic sieve works very well.
Drying¶
After harvesting the roots have to dry. I let them air dry for 2 day or to speed up to process put it inside a dehydrater. But I feel drying in a dehydrater makes them more brittle then air drying.
Application¶
After drying the roots are ready to be used. For my application it was not needed to coat them or make them more flexible but for a garment they would have to be coated or made more flexible as they tend to brittel apart a lot when touching.
Circularity & Perspective¶
To keep the process circular and waste-free, I autoclaved the leftover seeds after harvesting and combined them with wheat starch to create a biomaterial. The result became very sticky, and due to time constraints I wasn’t able to continue developing it further. However, it shows promising potential as a way to repurpose leftover seeds. The harvested grass itself was passed on to my colleague Amber, who used it to make paper.
Biomaterial
Recipie
I used the recipie form the Bioplastic Cookbook by Margaret Dunne
-
160ml water
-
20ml glycerin
-
3,2 Starch wheat
-
30ml white vinagar
As a next step, I would like to explore whether autoclaved seeds could serve as an effective substrate for mycelium growth.
SENSOR & VIDEO PROJECTION¶
Video projection¶
For the projection I recorded the seeds in timelaps and roots while growing and edited the video via DaVinci Resolve.
Recording was very difficult as the set-up had to fulfill many requirements:
- the camera had to be positioned stable and connected to power
- there had to be constant lighting - like a foto booth would be best
- the seeds have to be watered but should not be too wet. But rinsing is not possible as they should not be moved
- the seeds should be covered with a lid for keeping them moist but the lid gets foggy which influences the video quality.
I would recommend using a foot booth, placing the camera on top - so the seeds are acceseble from the side. I would do the recording in a big box, which is easiert to keep the moist without a lid and can be sprayed twice a day.
Interaction via Sensor¶
For the roots blanket, I wanted a sensor that activates a video projection when approaching the roots.
Equipment Used:
- Arduino Uno
- 10kΩ resistor
- Ultrasonic sensor
- Wires
To understand the Arduino ↔ TouchDesigner connection and wiring, I followed this tutorial: YouTube (watch until 6:00)
Wiring Setup
Code
After uplaoding the code the sensor values should be visible in the serial monitor of IDE. I got values between 1 and 14. The closer the hand is to the sensor the lower the number.
// ULTRASONIC SENSOR WITH TOUCHDESIGNER - OPTIMIZED 20Hz
int TRIG = 3; // Trigger pin connected to Arduino pin 3
int ECHO = 2; // Echo pin connected to Arduino pin 2
int DURATION; // Stores echo pulse duration in microseconds
float DISTANCE; // Distance in cm (float for decimal precision)
void setup() {
// Configure ultrasonic sensor pins
pinMode(TRIG, OUTPUT); // TRIG sends ultrasonic pulse
pinMode(ECHO, INPUT); // ECHO receives reflected pulse
// Initialize serial communication at 9600 baud (matches TouchDesigner)
Serial.begin(9600);
}
void loop() {
// CORRECT TRIGGER SEQUENCE for HC-SR04 sensor
digitalWrite(TRIG, LOW); // Ensure trigger is low first
delayMicroseconds(2); // 2μs LOW pulse (datasheet requirement)
digitalWrite(TRIG, HIGH); // Send trigger pulse
delayMicroseconds(10); // 10μs HIGH pulse (triggers 8 ultrasonic bursts)
digitalWrite(TRIG, LOW); // End trigger pulse
// Measure echo pulse duration (timeout prevents hanging)
DURATION = pulseIn(ECHO, HIGH, 25000); // 25ms timeout = max ~4m range
// Convert duration to distance: speed of sound = 340m/s
// Distance = (duration * 0.034) / 2 = duration / 58.2
DISTANCE = DURATION / 58.2;
// ALWAYS send data to TouchDesigner (even invalid readings)
Serial.println(DISTANCE, 1); // Send with 1 decimal place
delay(50); // 50ms delay = 20 measurements per second
}
TouchDesigner & Arduino
I uplaoded the code on the arduino in IDE, checked the serial monitor to receive the data form the sensor. Before opening TouchDesinger the Serial Monitor of IDE has to be closed otherwise Touch Designer will not receive any data.
Components Chain
textserial1 → select1 → datto1 → logic1 → null1 → math1 → moviefilein1 → out1 -> window1
- serial1: Receives sensor data from Arduino via serial port
- select1: Filters input data
- datto1: Converts to Table DAT format
- logic1: Applies logic conditions - play video if value lower than 4, else stop
- null1: Data passthrough
- math1: Math operations
- moviefilein1: Video loader/player
- out1: Render output
- window1: Output for full screen projection
You can find all files here
Adjusting Sensor Value
Here the value for the sensor can be adjusted. If serial data is lower than 4 -> Play, else stop.
Connect math1 to moviefilein1
math1 and moviefilein1 are different components, so they can not be connected via drag and drop wire. To connect following steps have to be done:
- Right-click math1 → "View Export Page" (cross icon appears on right edge)
- Right-click moviefilein1 → "View Parameter Page"
- Drag from math1 cross icon → moviefilein1 "play" parameter
Fullscreen Display
I follwedthis video.
Connect out1 to window1:
- Right-click out1 → "View Export Page" (cross icon)
- Right-click window1 → "View Parameter Page"
- Drag from out1 cross → window1 parameters
Sensor Testing
ROOT SOUND¶
I decided to leave this part out of my final project, as there wasn’t enough time to fully develop it. Nevertheless, I would still like to share some of my results.
Materials
- FabriXiao ESP32-S3
- PAM...
- copper wires
- jumper wires
- resistor
- roots
- 3 Ohm speaker
I measured the electrochemical signals and experimented with amplifying them into sound. While this worked, the result resembled an unpleasant, computer game–like noise rather than something atmospheric or pleasing. Despite my efforts, I wasn’t able to achieve a more refined sound. Based on my research, it seems that the current hardware setup limits the quality of the output, and a different type of speaker would likely be needed to produce more appealing results
Code:
// -------- Pins --------
const int sensorPin = A0;
const int speakerPin = 6; // connecting to D5
// -------- Audio Setup --------
const int pwmChannel = 0;
const int pwmResolution = 8;
float baseline = 0;
float smooth = 0;
void setup() {
Serial.begin(115200);
delay(2000);
analogReadResolution(12); // 0–4095
// NEW Core 3.x syntax
ledcAttach(speakerPin, 1000, pwmResolution);
}
void loop() {
long sum = 0;
for(int i=0; i<32; i++){
sum += analogRead(sensorPin);
delay(2);
}
float raw = sum / 32.0;
float voltage = raw * (3.3 / 4095.0);
baseline = baseline * 0.999 + raw * 0.001;
float filtered = raw - baseline;
smooth = smooth * 0.9 + filtered * 0.1;
float amplified = smooth * 6.0;
int freq = abs(amplified);
if(freq < 100) freq = 100;
if(freq > 3000) freq = 3000;
// Core 3.x version uses PIN, not channel
ledcWriteTone(speakerPin, freq);
Serial.print("Freq: ");
Serial.println(freq);
delay(40);
}























