A wooden box with a tic-tac-toe board set up. It has pressure sensors and LEDs on the top side. When the user presses against the sensor it lights up the LEDs: soft touches turn blue and hard ones turn red. As the users get three same-colored LEDs on the board all of the LEDs go out, signifying the end.
Initially I started with layouting the 9 fsrs in place. One to get an idea of how the interaction would feel and also to start with the basic code mapping of different LEDs with different sensors respectively.
Then I moved from a single LED strip to an LED strip and a neopixel led ring, as I imagined to set up the board in X and O pattern. For the same I used two different libraries in the code and so the problem I faced was the libraries were overlapping and giving me errors when I tried matching the same color. That's when I realized and understood that I could use the same library for the different types of LEDs.
Once I got the code figured out and I put all the led strips and rings together, the next challenge I came across was that there were too many wires which I could not avoid. I tried segregating them using different types of wires, I used silicon flexible wires for the fsrs and decided to use the solid stranded wires for the LEDS, this gave me some room for movement of the elements.
The idea being of a tic tac toe and having a very strong traditional relevance I wanted the proportion and size of the box to be well scaled. Further, I did some precise measurements to design the box. It was an interesting process going into the detail of the size of the wire and measuring exact distance between them.
Seeing everything come to live was a big milestone. I designed the box using fusion 360 and then laser cut the same in 6mm wood. Although fabricating was fun, I had to disconnect the wires from the system to place them on the box. The solid wires helped me differentiate in the system but it was a difficult task to squish them all and fit them in the box, making sure they cross or move.
The journey of creating the Illusionary Tic Tac Glow was as illuminating as the LEDs that adorn it. Conceptually, my endeavor was to bridge the familiar comfort of nostalgia with the thrill of innovation. At the outset, I believed that merging these elements would be seamless. After all, tic tac toe is a universally recognized game, and modernizing its mechanics with LEDs seemed straightforward. Yet, the challenges lay elsewhere.
One of the pivotal moments was choosing the pressure sensors. The tactile interaction was paramount, and I wanted the users to feel they were in a dialogue with the game. The gradient from blue to red was meant to mimic the varying intensities of our daily pressures. However, translating this vision into a tangible experience was challenging. Calibration and fine-tuning were essential to ensure that the sensors responded with precision to diverse pressures. There were instances when the LEDs responded unexpectedly, either too dimly or too brightly. Striking the right balance was a meticulous endeavor.
Retrospectively, a small change in my perception reshaped the project's trajectory entirely. The initial prototype aimed to determine a clear winner or loser. However, upon introspection, I realized that the very essence of the game I was trying to redefine was collaboration, shared experiences, and the subtle dance between pressure and outcome. Abandoning the conventional win-lose result in favor of a collective triumph emphasized the project's core philosophy.
As I reflect upon the entirety of the process, it becomes evident that this project wasn't just about creating an interactive game. It was a lesson in adaptation, in allowing one's vision to evolve, and in understanding the nuances of tactile interactions. I've grown not just technically, but also philosophically. And as I move forward, I intend to be more receptive to the organic evolution of ideas, ensuring that every project becomes a meaningful conversation between me, the creation, and its audience.
/*Project Title: Illusionary Tic Tac Glow
Author: Juhi Kedia
This code is for the "Illusionary Tic Tac Glow" project, an interactive game setup
that blends the nostalgia of tic tac toe with innovative tactile and visual feedback.
At its core, the code reads pressure values from FSR sensors and adjusts the LED colors
on strips and rings based on the intensity of the pressure applied. The colors vary from
blue (light pressure) to red (strong pressure). When any three strips or rings have the
same color, all the LEDs are turned off, indicating a collaborative triumph in the game.
Pin Mapping:
- Strips' Pins: 2, 3, 4, 5
- Rings' Pins: 7, 8, 9, 10, 11
- FSR Pins for Strips: A0, A3, A5, A9
- FSR Pins for Rings: A1, A2, A6, A7, A8
Credits:
The code leverages the Adafruit NeoPixel library for LED control.
*/
#include <Adafruit_NeoPixel.h>
// Define the pins for the LED strips
#define PIN_STRIP1 2
#define PIN_STRIP2 3
#define PIN_STRIP3 4
#define PIN_STRIP4 5
// Define the pins for the LED rings
#define PIN_RING1 7
#define PIN_RING2 8
#define PIN_RING3 9
#define PIN_RING4 10
#define PIN_RING5 11
// Define number of LEDs per strip and per ring
#define NUMPIXELS 6 // Number of NeoPixels per strip
#define NUMPIXELS_RING 16 // Number of LEDs per ring
// Define pins for pressure sensors (FSRs) associated with strips
#define FSR_PIN_STRIP1 A0
#define FSR_PIN_STRIP2 A3
#define FSR_PIN_STRIP3 A5
#define FSR_PIN_STRIP4 A9
// Define pins for pressure sensors (FSRs) associated with rings
#define FSR_PIN_RING1 A1
#define FSR_PIN_RING2 A2
#define FSR_PIN_RING3 A6
#define FSR_PIN_RING4 A7
#define FSR_PIN_RING5 A8
#define MIN_THRESHOLD 100 // Minimum pressure to register
#define MAX_READING 1023 // Max analog reading from FSR
// Create arrays of NeoPixel objects for strips and rings
Adafruit_NeoPixel strips[4] = {
Adafruit_NeoPixel(NUMPIXELS, PIN_STRIP1, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PIN_STRIP2, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PIN_STRIP3, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS, PIN_STRIP4, NEO_GRB + NEO_KHZ800)
};
Adafruit_NeoPixel rings[5] = {
Adafruit_NeoPixel(NUMPIXELS_RING, PIN_RING1, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS_RING, PIN_RING2, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS_RING, PIN_RING3, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS_RING, PIN_RING4, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUMPIXELS_RING, PIN_RING5, NEO_GRB + NEO_KHZ800)
};
void setup() {
// Initialize all LED strips and rings
for (int i = 0; i < 4; i++) {
strips[i].begin();
strips[i].show();
}
for (int i = 0; i < 5; i++) {
rings[i].begin();
rings[i].show();
}
// Set all FSR pins as INPUT
pinMode(FSR_PIN_STRIP1, INPUT);
pinMode(FSR_PIN_STRIP2, INPUT);
pinMode(FSR_PIN_STRIP3, INPUT);
pinMode(FSR_PIN_STRIP4, INPUT);
pinMode(FSR_PIN_RING1, INPUT);
pinMode(FSR_PIN_RING2, INPUT);
pinMode(FSR_PIN_RING3, INPUT);
pinMode(FSR_PIN_RING4, INPUT);
pinMode(FSR_PIN_RING5, INPUT);
}
void loop() {
// Check each FSR and adjust corresponding LEDs accordingly
checkFSRAndAdjustLight(FSR_PIN_STRIP1, strips[0]);
checkFSRAndAdjustLight(FSR_PIN_STRIP2, strips[1]);
checkFSRAndAdjustLight(FSR_PIN_STRIP3, strips[2]);
checkFSRAndAdjustLight(FSR_PIN_STRIP4, strips[3]);
checkFSRAndAdjustLight(FSR_PIN_RING1, rings[0]);
checkFSRAndAdjustLight(FSR_PIN_RING2, rings[1]);
checkFSRAndAdjustLight(FSR_PIN_RING3, rings[2]);
checkFSRAndAdjustLight(FSR_PIN_RING4, rings[3]);
checkFSRAndAdjustLight(FSR_PIN_RING5, rings[4]);
// Check if any three strips or any three rings have the same color
if (areThreeColorsSame(strips, 4) || areThreeColorsSame(rings, 5)) {
turnOffAllLEDs();
}
delay(50); // Small delay
}
// Function to check if three devices (strips/rings) have the same color
bool areThreeColorsSame(Adafruit_NeoPixel* devices, int count) {
for (int i = 0; i < count - 2; i++) {
for (int j = i + 1; j < count - 1; j++) {
for (int k = j + 1; k < count; k++) {
uint32_t color_i = devices[i].getPixelColor(0);
uint32_t color_j = devices[j].getPixelColor(0);
uint32_t color_k = devices[k].getPixelColor(0);
if (color_i != 0 && color_i == color_j && color_j == color_k) {
return true;
}
}
}
}
return false;
}
// Function to turn off all LEDs on all strips and rings
void turnOffAllLEDs() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < strips[i].numPixels(); j++) {
strips[i].setPixelColor(j, 0);
}
strips[i].show();
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < rings[i].numPixels(); j++) {
rings[i].setPixelColor(j, 0);
}
rings[i].show();
}
}
// Function to read the FSR value and adjust the LED colors accordingly
void checkFSRAndAdjustLight(int fsrPin, Adafruit_NeoPixel& neoPixel) {
int fsrValue = analogRead(fsrPin);
if (fsrValue > MIN_THRESHOLD) {
setLEDColorBasedOnPressure(neoPixel, fsrValue);
}
}
// Function to set LED color based on the pressure value read from FSR
void setLEDColorBasedOnPressure(Adafruit_NeoPixel& neoPixel, int pressure) {
int redIntensity = map(pressure, MIN_THRESHOLD, MAX_READING, 0, 255);
int blueIntensity = 255 - redIntensity;
for (int i = 0; i < neoPixel.numPixels(); i++) {
neoPixel.setPixelColor(i, neoPixel.Color(redIntensity, 0, blueIntensity));
}
neoPixel.show();
}