Link to sketch: https://editor.p5js.org/Hazpaz/full/1zy63dQBC
Concept
The finals week is here and stress is something that comes along with it. To soothe everyone’s nerves, I have come up with this project through which anyone can unleash their stress. Simple yet powerful. Inspired by one of the previous works related to stress done by previous students, I’ve decided to take advantage of the stress and anger of the students to create beautiful patterns. The idea is to use a stress ball to measure stress levels. When you squeeze the ball, it tells you how much stress you’re letting out. The project then shows a spiral pattern in action according to the pressure applied.
Images
User testing Video
How does the implementation work
Materials Used
- Arduino Uno
- Breadboard
- flex sensor
- jumper wires
- 330 ohms resistors
- Cardboards
Description of interaction design
When you squeeze the the stress ball, the spiral pattern in p5 starts animating and when the pressure applied on the stress ball increases, the Arduino reads it using the flex sensor and the speed of the spiral animation increases and the color changes to a dark red from a soft color, thus making it feel intense.
Arduino code
const int flexPin = A0; // Analog pin for the flex sensor int flexValue = 0; // Variable to store flex sensor value int pressure = 0; // Variable to store pressure level (mapped from flex sensor value) int pressureMin = 10; // Minimum pressure value int pressureMax = 1023; // Maximum pressure value void setup() { Serial.begin(9600); } void loop() { // Read flex sensor value flexValue = analogRead(flexPin); // Map flex sensor value to pressure scale (0-100) pressure = map(flexValue, pressureMin, pressureMax, 0, 100); // Send pressure value to p5.js Serial.println(pressure); delay(100); // Adjust delay as needed }
The A0 pin is used as the analog pin for the flex sensor.
// Map flex sensor value to pressure scale (0-100) pressure = map(flexValue, pressureMin, pressureMax, 0, 100);
This code maps the flex sensor reading to a range between 0-100.
// Send pressure value to p5.js Serial.println(pressure);
the above code is the communication from Arduino to p5.
p5.js code
function draw() { if (!patternsPage) { // Display starting page image(startingPage, 0, 0, windowWidth, windowHeight); } else { // Display patterns page image(bg, 0, 0, windowWidth, windowHeight); // Background image // Update and draw circles for (let i = 0; i < cols; i++) { for (let j = 0; j < rows; j++) { circles[i][j].display(); circles[i][j].move(circleSpeed * pressure); // Update speed based on pressure } } // Draw pressure scales pressureMeterLeft.draw(pressure); pressureMeterRight.draw(pressure); // Draw texts fill('#704402'); // Set text color textAlign(CENTER, CENTER); // Align text to center text("Pressure: " + pressure, width / 2, 30); // Display pressure value // Display connection status if (!serialActive) { // If serial connection is not active fill('red'); // Set text color to red text("Press Space Bar to select Serial Port", windowWidth / 2, windowHeight - 20); // Display message to select serial port } else { // If serial connection is active fill(0, 255, 0); // Set text color to green text("Connected", windowWidth / 2, windowHeight - 20); // Display connected message } } }
This function controls the visualization and text elements. If on the starting page, it displays the `startingPage` image, and if on the patterns page, it shows the `bg` image. It updates and draws stress-relief circles, adjusting their movement speed according to the pressure level. Pressure scales are drawn on the left and right sides using `pressureMeterLeft` and `pressureMeterRight`, representing the pressure level visually. The pressure value is displayed at the top center, and a message about the status of the serial port connection is shown at the bottom center. If the serial connection is inactive, it prompts the user to press the space bar to select the serial port; otherwise, it indicates that the connection is established.
// Circle class for moving circles class Circle { constructor(cx, cy, angle) { this.angle = angle; this.cx = cx; this.cy = cy; this.baseColor = color('#F0D6B0'); // Green color for low pressure this.highPressureColor = color('rgb(179,1,1)'); // Red color for high pressure/ } display() { push(); translate(this.cx, this.cy); noFill(); let c = map(abs(this.angle % TWO_PI), 0, TWO_PI, 0, 255); c -= map(pressure, 0, maxPressure, 0, 100); // Darken color based on pressure c = constrain(c, 0, 255); let currentColor = lerpColor(this.baseColor, this.highPressureColor, pressure / maxPressure); // Interpolate between green and red based on pressure noStroke(); fill(currentColor); let x = r * cos(this.angle); let y = r * sin(this.angle); arc(x, y, size, size, this.angle, this.angle + PI / 2); pop(); } move(speed) { this.angle -= speed; } }
The `Circle` class defines the behavior and appearance of the patterns. Each circle is constructed with parameters for its center position (`cx` and `cy`) and its starting angle (`angle`). It has properties for colors representing low and high pressure, where green indicates low pressure and red indicates high pressure. The `display()` method draws the circle, adjusting its color based on the current pressure level. The circle’s position is translated to its center, and its color is determined by interpolating between the base color and high pressure color. The `move()` method updates the angle of the circle, causing it to rotate at a speed determined by the pressure level.
// PressureMeter class for the pressure scale class PressureMeter { constructor(x, y, width, height) { this.x = x; // X position this.y = y; // Y position this.width = width; // Width this.height = height; // Height } draw(pressure) { // Draw pressure scale box noFill(); stroke(10); rect(this.x, this.y, this.width, this.height); // Draw the rectangle outline\ // Fill the pressure scale rectangle based on pressure let fillAmount = map(pressure, 0, maxPressure, 0, this.height); // Map pressure to the height of the rectangle fill('#985B00'); // Set fill color to brown noStroke(); rect(this.x, this.y + this.height - fillAmount, this.width, fillAmount); // Draw the filled rectangle } }
The `PressureMeter` class contains the visual representation of the pressure scale. It is initialized with parameters for its position (`x` and `y`), as well as its width and height. The `draw()` method is responsible for rendering the pressure scale on the canvas. It first draws the outline of the pressure scale box using the provided position, width, and height. Then, it calculates the fill amount based on the current pressure level, mapping it to the height of the rectangle. The fill color is set to brown, and a filled rectangle is drawn inside the outline, representing the current pressure level.
Embedded sketch
Description of communication between Arduino and p5.js
A stress ball is connected to a flex sensor, which is connected to A0 pin in Arduino Uno. The Arduino is connected to p5 using serial connection. When the stress ball is squeezed, the Arduino reads it with the help of the flex sensor and then maps the sensor reading between 0-100. The Arduino sends this mapped sensor readings to p5 through serial connection and the p5 uses this sensor readings to adjust the speed and color of the animation of the spiral pattern.
// Send pressure value to p5.js Serial.println(pressure);
the above code is the communication from Arduino to p5.
Aspects of the project I’m proud of
resources used
Challenges faced and overcoming them
I’ve faced a number of challenges with this project.