I created an alarm system that allows users to toggle the alarm on and off using a button. When activated, signified by the green LED, the alarm, represented by a red LED, responds to the surrounding light conditions. Specifically, the red LED turns on when the environment is well-lit and remains off in darkness.
How the Alarm Works
Alarm Setting:
– The user sets the alarm by pressing the blue button.
– The green LED, confirms whether the alarm is actively set (green LED on).
Light Sensing:
– Once the alarm is set, the system relies on a Light-Dependent Resistor (LDR) to detect ambient light levels.
Alarm Activation:
– In a well-lit environment, the red LED, representing the alarm, activates, turns on and off.
Alarm Deactivation:
– In darkness, the red LED remains turned off.
Components Used:
– LEDs: One red and one green
– Light-Dependent Resistor (LDR): Detects changes in ambient light conditions.
– Push-button Switch (Digital Sensor): Enables user interaction to set and unset the alarm.
Reflection
Working on this project I better understand the Arduino programming syntax, and analog input & output. Later when we learn to use sounds and music, I could include a sound for the alarm for better user experience.
The concept of this circuit is pretty straightforward, it’s a stopwatch! You specify the number of seconds you want the stopwatch to count by setting the potentiometer to a number on a scale of 1-60. Then you press on the red button. The LEDs start lighting in an alternating pattern that represents the seconds passed. When the time specified has passed both LEDs turn off.
Process & Highlights:
The potentiometer is connected in series with the analog input and is used to set the countdown time. The switch is connected in parallel and is used to start the countdown. The LEDs are connected in parallel with resistors and are used to display the countdown time. One LED indicates even seconds, and the other indicates odd seconds and it varies each time depending on the previous state.
Here is a video demo of the switch:
Code:
const int potentiometerPin = A0;
const int switchPin = 2;
const int ledPin1 = 3;
const int ledPin2 = 4;
int countdownTime = 0;
bool countdownStarted = false;
void setup() {
pinMode(potentiometerPin, INPUT);
pinMode(switchPin, INPUT_PULLUP);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
Serial.begin(9600);
}
void loop() {
if (!countdownStarted) {
countdownTime = map(analogRead(potentiometerPin), 0, 1023, 1, 60); // Set countdown time based on potentiometer
Serial.println(countdownTime);
}
if (digitalRead(switchPin) == LOW) {
countdownStarted = true;
}
if (countdownStarted && countdownTime > 0) {
countdownTime--;
displayCountdown();
delay(1000); // One-second delay
} else if (countdownTime == 0) {
// Countdown finished
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
countdownStarted = false;
}
}
void displayCountdown() {
int ledState = (countdownTime % 2 == 0) ? HIGH : LOW; // Toggle LED state
digitalWrite(ledPin1, ledState);
digitalWrite(ledPin2, !ledState);
}
Reflections:
I found this exercise a bit harder than the first one but it was fun to implement. If I could change one thing about my circuit, it would be to maybe have a screen display the seconds that have elapsed as well. I would love to create more advanced circuits in the future and find a way to incorporate more creativity within.
For this assignment, I decided to make a simple circuit using three LEDS, a switch and a potentiometer.
The idea is that it functions as a way to communicate three moods: anger, sadness and happiness. The mood is decided through the potentiometer, which maps the analog reading to a number within the range 0 – 90. If it’s in between 0-30, the green LED lights up, if it’s between 30 – 60, the blue LED lights up, and anything after 60 up till 90 makes the red LED light up. The LEDs blink in morse code – the red LED spells ANGRY, the blue LED spells SAD, and the green LED spells HAPPY. The digital switch in the circuit is used to turn the circuit on or off, with the LEDs only blinking if the switch is pressed.
code highlights:
const int greenLED = 12;
const int redLED = 11;
const int blueLED = 10;
const int btn = A2;
const int pot = A1;
int value;
int currLED = 0;
void flashDot() {
digitalWrite(currLED, HIGH);
delay(250);
digitalWrite(currLED, LOW);
delay(250);
}
void flashDash() {
digitalWrite(currLED, HIGH);
delay(1000);
digitalWrite(currLED, LOW);
delay(250);
}
void setup() {
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(blueLED, OUTPUT);
Serial.begin(9600);
}
void loop() {
int btnState = digitalRead(btn);
int potVal = analogRead(pot);
value = map(potVal, 0, 1023, 0, 90);
Serial.println(currLED);
Serial.println(value);
if (btnState == LOW) {
digitalWrite(greenLED, LOW);
digitalWrite(redLED, LOW);
digitalWrite(blueLED, LOW);
// currLED = 0;
}
if (value <= 30) {
currLED = greenLED;
// digitalWrite(redLED, LOW);
// digitalWrite(blueLED, LOW);
} else if (value > 30 && value <= 60) {
currLED = blueLED;
// digitalWrite(greenLED, LOW);
// digitalWrite(redLED, LOW);
} else {
currLED = redLED;
// digitalWrite(greenLED, LOW);
// digitalWrite(blueLED, LOW);
}
if (btnState == HIGH) {
// digitalWrite(greenLED, LOW);
// digitalWrite(redLED, LOW);
// digitalWrite(blueLED, LOW);
// } else if (btnState == LOW) {
if (currLED == greenLED) {
digitalWrite(blueLED, LOW);
digitalWrite(redLED, LOW);
flashDot(); // H
flashDot();
flashDot();
flashDot();
delay(1000); // Gap between letters
flashDot(); // A
flashDash();
delay(1000); // Gap between letters
flashDot(); // P
flashDash();
flashDot();
flashDot();
delay(1000); // Gap between letters
flashDot(); // P
flashDash();
flashDot();
flashDot();
delay(1000); // Gap between letters
flashDash(); // Y
flashDot();
flashDash();
flashDash();
delay(1000); // Gap between words
} else if (currLED == blueLED) {
digitalWrite(greenLED, LOW);
digitalWrite(redLED, LOW);
flashDot(); // S
flashDot();
flashDot();
delay(1000); // Gap between letters
flashDot(); // A
flashDash();
delay(1000); // Gap between letters
flashDash(); // D
flashDot();
flashDot();
delay(1000); // Gap between words
} else if (currLED == redLED) {
digitalWrite(blueLED, LOW);
digitalWrite(greenLED, LOW);
flashDot(); // A
flashDash();
delay(1000); // Gap between letters
flashDash(); // N
flashDot();
delay(1000); // Gap between letters
flashDash(); // G
flashDot();
flashDot();
delay(1000); // Gap between letters
flashDot(); // R
flashDash();
flashDot();
delay(1000); // Gap between letters
flashDash(); // Y
flashDash();
delay(1000); // Gap between words
}
}
}
The code is pretty simple and straightforward. One thing I like about my code is using the functions flashDash and flashDot, as it made it much easier to translate the morse code into blinking.
reflections:
One thing I struggled with and couldn’t really fix and/or understand why it was happening was the delayed transition between states, i.e. it takes a while to go from green to red etc., or even to turn off (as seen in the video). In the future, I’d want to be able to assess the root cause of this issue as it could be very problematic in other sorts of circuits where timing is very necessary.
I like the guidebook on commonly-made physical computing projects in class. I’ve thought about what it must be like to be a professor for an intro project-based class, like Intro to CS or Intro to IM, as there must be ideas that are constantly recycled each semester and the professor will have to pretend that they’re novel even when they’ve seen it a million times before. I assume a platformer game will always show up in Processing/P5.js class. Perhaps a paint/drawing program too, a particle system/ pattern animation, recreations of classic games like Pong or Snake. That’s not to say that they’re boring, as the reading also talks about how the cliches can sometimes be used as a base for something more interesting, but it’s fun to think about ideas that are strangely common.
Despite them being constantly recycled, it is possible to make interesting, unique projects out of them. I can think of a visual novel-esque game being one that is likely technically similar across most games of it’s genre, yet the deciding factor between a good and bad visual novel is the story being told, not the implementation of ‘click to see the next line of text’. Perhaps one of the best ways of being creative is to mix-up an existing overused form of media instead of trying to be both novel and interesting at the same time, as then you might be limited by your technical capabilities rather than your creative ones. In the case of the reading, video mirrors have been done. A Lot. Yet, this means that it is relatively easy to implement one thanks to the wealth of documentation and existing implementations on the internet, and you can focus instead on the ‘what’ you want to convey through your project, instead of the ‘how’.
The other reading compliments Don Norman’s chapters from the past few weeks really well. Show, don’t tell, in your projects. Students learn better when they make the intuition between two objects, rather than memorizing the two objects. Likewise, I assume that viewers of an art piece will enjoy it more when they come to their own conclusions about it, than being told what to feel. Of course, artists are always trying to convey something, and to have every viewer of their piece think wildly differently from their intent is probably not the artist’s intention. Through the design process itself, artists can guide viewers to their intent, to gently nudge them in the right direction without having to hold their hand. I like to think about Escape Rooms in this example. The goal of an Escape Room is to escape from it, yet players will find it unfun if the lock and key are both on the same table as they might feel it is too easy. Yet, if the puzzle is too difficult, players will feel frustrated and will not enjoy it either. The designers of Escape Rooms must strike a delicate balance between making a puzzle that is not easily solvable, yet guiding users delicately to their goal. For example, the usage of a padlock vs a combination lock will intuitively guide the players on what they should look for ( a key or a code ).
Concept
With what we currently know about Arduino, there were many things I am technically incapable of making yet, such as using the servo/motors or the LCD screen. Given the lax requirements for this week’s project of having 1 analog and 1 digital button, and 2 LEDs, I wasn’t sure what I could do with it what I currently have ( momentary switches, light detecting diodes ) while still being creative, so I thought of making a game of sorts and I came up with a memory game with the buttons.
Implementation
The light detecting diode ( analog ) is used to start/restart the game. When the LDR is covered and it becomes dark, the game is started. The momentary buttons are used to play the game.
Once the game is started, the LEDs will blink in sequence, and you have to replicate the sequence with the aptly-colored buttons to light up the same LEDs in the same order. There are multiple rounds, starting with 1 LED, all the way up to 8 LEDs. The sequence will blink again at the start of each round, with the addition of a new LED in the sequence. The player will have to rely on their memory to press the 8 LEDs in the right order.
The LEDs also double both as the game mechanism, and information mechanism. I use the LEDs to display game state information too. When the user has lost ( pressed an LED in the wrong order) , the LEDs will all blink twice before turning off. When the user has won, the LEDs will blink in a fun pattern on repeat until a new game is started.
Video demo : In the first attempt, I made a mistake and the ‘loss sequence’ plays. The second attempt, I complete the challenge and the ‘victory sequence’ plays.
Expansion
It would be fun to use other forms of inputs other than buttons for this game! I was thinking of using the ultrasonic detector as a challenge too, e.g player has to remember the distance they have to trigger the ultrasonic detector. Perhaps once I learn about more sensors and inputs, I could think about implementing them into this game so there’s more variety rather than just a sequence of LEDs.
My Concept: I wanted to create a circuit in which the push button turns LED1 on and off and the photoresistor regulates the LED2 by turning on, making it blink and turning off based on the value of the photoresistor.
//initializing the pins to push button and photoresistor
const int BUTTON1 = 2;
const int PHOTOSENSOR = A0;
//initializing the pins to LED1 and LED2
const int LED1 = 8;
const int LED2 = 12;
int BUTTONstate1 = 0;
int PHOTOSENSORvalue = 0;
void setup()
{
//defining the button (digital) and photoresistor (analog) as input pins
pinMode(BUTTON1, INPUT);
pinMode(PHOTOSENSOR, INPUT);
//defining LEDs as output pins
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
}
void loop()
{
//the conditional to turn on the LED1 if the button is pushed
BUTTONstate1 = digitalRead(BUTTON1);
if (BUTTONstate1 == LOW)
{
digitalWrite(LED1, HIGH);
}
else
{
digitalWrite(LED1, LOW);
}
//the conditional to turn on the LED2, make it blink and turn off based on the value on photoresistor
PHOTOSENSORvalue = analogRead(PHOTOSENSOR);
if (PHOTOSENSORvalue < 500)
{
// Low light condition which turns LED2 on
digitalWrite(LED2, HIGH);
}
else if (PHOTOSENSORvalue >= 500 && PHOTOSENSORvalue < 1000)
{
// Medium light condition which makes the LED2 blink
digitalWrite(LED2, HIGH);
delay(500);
digitalWrite(LED2, LOW);
delay(500);
}
else
{
// High light condition which turns LED2 off
digitalWrite(LED2, LOW);
}
}
I am particularly proud of the code with reads the value of the photoresistor and gives the LED outputs accordingly (turn on, blink, turn off).
Reflections: This work might seem easy, but took lots of research and understanding of the concept. Initially, my idea was to control the brightness of LED2 based on the resistance value on the photoresistor to show that the LED2 is an analog output. However, strangely, LED1 was affected by the value of the photoresistor and LED2 did not react. Then, I changed the code to make the LED2 turn on when the value of the photoresistor is less than 500 ohms, blink when it is in the range of [500, 10000) and turn off when these conditions are not met. As this one worked well, I used this code. Nevertheless, I would like to solve the mystery of the first outcome.
Making Interactive Art: Set the Stage, Then Shut Up and Listen reads like meta commentary for this class. For all the work that we have done in the past weeks, we’ve produced supporting documentation backing our inspiration, thought process, methodology, and everything in between. The author speaks of such artists with disdain. “They pre-script what will happen. When you do that, you’re telling the participant what to think, and by extension, how to act. Is that what you wanted?” That is actually not what I want, and for my final project, I would like to work on this author’s terms. I don’t have an idea for my final project yet, but I think I want to create something expansive; something that houses at least the potential for serendipity. The projects that I am making right now are rather limited in functionality, so essentially I have already defined the scope for interactivity before the first interaction with my projects can even happen. But my goal for my final project is to design, for each individual user, unique experiences which exist in a larger permutative space.
The other reading offers some good ideas for thinking in this direction. Furthermore, even though most of the works listed are popular project ideas in the interactive art community, I liked how the author addressed this at the get-go. “So if you’re new to physical computing and thinking to yourself “I don’t want do to that, it’s already done,” stop thinking that way! There’s a lot you can add to these themes through your variation on them.” Usually, when I’m looking for inspiration on the blog for my weekly projects, I look at other people’s work and immediately close off ideas pertaining to the use of similar tools or methods. But looking at projects that use “body-as-cursor” or “hand-as-cursor”, it seems I don’t have to be that restrictive in my thinking. Everyone used Javascript to create all these cool projects in the first half of the semester — but every project came out so unique and with the emblem of each person’s individuality. So, if I see someone using an LDR for their project, I don’t think I should turn away from using LDRs in my project altogether. I can also probably make something cool with the same tools.
Tigoe delves into a range of ‘physical computing’ projects in his article, “Physical Computing’s Greatest Hits (and misses).” I found this piece to be particularly beneficial, treating it as a brainstorming session for ideas on my final project. Exploring the diverse examples of projects was not only interesting but also provided inspiration for potential directions in my own work. One particularly noteworthy aspect of Tigoe’s perspective is his emphasis on the intrinsic beauty of recurring themes in physical computing. Rather than viewing the repetition of certain ideas as a deterrent, Tigoe encourages a nuanced perspective. He suggests that newcomers should recognize the vast potential for injecting individuality and creativity into these themes. What resonates with me is Tigoe’s assertion that repetition need not be perceived as a limiting factor. Instead, he reframes it as an open invitation to innovate — an opportunity to build upon existing concepts, introduce new elements and refine established ones. This perspective fosters a dynamic and progressive approach to physical computing projects, emphasizing the continuous evolution and enrichment of the field through creative contributions.
Making Interactive Art: Set the Stage, Then Shut Up and Listen
In “Making Interactive Art: Set the Stage, Then Shut Up and Listen” interactive art, is described as, is nothing short of orchestrating a living conversation. It’s not just a canvas where an artist dumps their thoughts; it’s a dynamic exchange where both creator and audience actively contribute. What struck me the most in this article is the call to resist the temptation to over explain. It’s an invitation for artists to step back after crafting the initial experience and allowing people the space to unravel its layers on their own. I used to think that you had to know how to interpret a piece of art to fully enjoy it. But over time, I’ve come to realize that not knowing is sometimes better than knowing. There’s no one right way to perceive an experience, and by trying to dictate it to the audience, you limit their perspective. This approach to interactive art feels really freeing. It’s all about breaking away from a fixed narrative and embracing the unpredictable beauty of individual interpretations. It’s not about telling people what the art means; it’s about co-creating an experience that’s as diverse and dynamic as the people engaging with it.
For this week’s assignment, I drew inspiration from traffic lights. I aimed to replicate their functionality using a potentiometer for analog input and a button for digital input. The potentiometer serves to control the transition of the LED lights, mimicking the sequence of a traffic light as it turns from red to yellow and then to green. Additionally, pressing the button initiates a special state where all three lights blink simultaneously.
The code uses the concepts of analog reading, digital input, LED control, and mapping to create a dynamic and interactive traffic light simulation.
const int analogSensorPin = A0;
const int digitalSensorPin = 2;
const int redLEDPin = 6;
const int yellowLEDPin = 9;
const int greenLEDPin = 11;
//variables to store sensor readings
int analogSensorValue;
int digitalSensorState;
int trafficLightState = 0; // 0: red, 1: yellow, 2: green
void setup() {
pinMode(analogSensorPin, INPUT);
pinMode(digitalSensorPin, INPUT);
pinMode(redLEDPin, OUTPUT);
pinMode(yellowLEDPin, OUTPUT);
pinMode(greenLEDPin, OUTPUT);
}
void loop() {
analogSensorValue = analogRead(analogSensorPin);
digitalSensorState = digitalRead(digitalSensorPin);
//toggle traffic light state on button press
if (digitalSensorState == HIGH) {
// Blink all lights together
digitalWrite(redLEDPin, HIGH);
digitalWrite(yellowLEDPin, HIGH);
digitalWrite(greenLEDPin, HIGH);
delay(500); // Blink duration
digitalWrite(redLEDPin, LOW);
digitalWrite(yellowLEDPin, LOW);
digitalWrite(greenLEDPin, LOW);
delay(200); // Debouncing
} else {
//map potentiometer value to traffic light state
trafficLightState = map(analogSensorValue, 0, 1023, 0, 2);
//control traffic light LEDs based on state
if (trafficLightState == 0) {
//red light
digitalWrite(redLEDPin, HIGH);
digitalWrite(yellowLEDPin, LOW);
digitalWrite(greenLEDPin, LOW);
} else if (trafficLightState == 1) {
//yellow light
digitalWrite(redLEDPin, LOW);
digitalWrite(yellowLEDPin, HIGH);
digitalWrite(greenLEDPin, LOW);
} else if (trafficLightState == 2) {
// green light
digitalWrite(redLEDPin, LOW);
digitalWrite(yellowLEDPin, LOW);
digitalWrite(greenLEDPin, HIGH);
}
}
delay(50);
}
I enjoyed working on this assignment since there were numerous ways to modify the LEDs’ behavior. The only challenging aspect was recording the video, as the potentiometer is a bit tough to turn, and it ends up rotating the entire breadboard with it :/
Making Interactive Art: Set the Stage, Then Shut Up and Listen:
The author points out that people often mix up the real idea behind interactive media and art. Art usually constitutes people expressing their own feelings and emotions whereas interactive media installations usually urge the viewer to come up with their own interpretation, part of the installation is the viewer coming up with a creative interpretation based on their own observations. In my opinion, this concept can be applied to all sorts of art to create a more interesting and captivating experience for the viewers as they unconsciously start relating the art piece to what they want to see. I took a class last year that discussed the idea of close-viewing paintings with zero context. We were not allowed to know who the artist was, when the painting was drawn, in which country it was drawn, the title, nothing. Our final project was to go to the Louvre and each choose a painting and close-view it for an hour and take notes of what we believed was the story behind the painting and the message the painter wanted to send through the painting, before actually reading the description of the painting. During the presentations, I remember that everyone had come up with these amazing and extreme interpretations of their piece that actually had no correlation at all to the description written by the painter. I was surprised by how different everyone’s interpretation can be depending on what their background is, what they currently have on their mind, what their hobbies and interests are, etc. I believe that giving your viewer the space to come up with their own interpretation makes the art experience more enjoyable and relatable to them.
Physical Computing’s Greatest Hits (and misses):
This author lists and describes the most recurring themes in physical computing as of 2008. I have to be honest most of these themes I have seen before, but nevertheless some of them were new to me. I realize that sometimes the best projects stem from the simplest of ideas that incorporate user engagement. I agree that physical computing may seem limited but it is a very broad area and even using creativity to enhance an already existing idea would take it to another level, turning it into an impressive project. I wonder how the rapid evolution of artificial intelligence and machine learning models since this article has affected physical computing projects and installations and how it has enhanced the accessibility of the projects. The article leaves me wondering what new ideas of human interaction could be employed using artificial intelligence and what other possibilities lie ahead in a future of ever evolving technology.