Week 9 – RGB Color Mixer and Potentiometer Intensity Scale

Concept

For this week’s assignment we were to utilize digital and analog read and write to control some LEDs. For the digital component, I built a circuit that utilizes three switches and an RGB LED to create a simple RGB color mixer. It was a pretty straightforward concept that utilized a component we had not talked about in detail during class.

Simple RGB Color Mixer

Implementation

To implement this circuit I used an RGB LED, three switches, resistors and wires and an Arduino. The circuit was pretty simple and utilized some knowledge on parallel connections which can be seen in the diagram below:

The RBG diode functions as a three-in-one diode and displays 7 colors (including white which I know might not be a color) when used for digital output. To run the switch, I wrote some code for the Arduino which can be bound below

// Diode output initialization
const int red_o = 9; 
const int green_o = 10;
const int blue_o = 11;

// Diode input initialization
const int red_i = 5; 
const int green_i = 4;
const int blue_i = 6;

// Diode counters initialization
int b_counter = 0;
int r_counter = 0;
int g_counter = 0;

void setup(){
  // Input pin modes for the diode inputs
  pinMode(red_i, INPUT);
  pinMode(blue_i, INPUT);
  pinMode(green_i, INPUT);

  // Output pin modes for the diode outputs
  pinMode(red_o, OUTPUT);
  pinMode(green_o, OUTPUT);
  pinMode(blue_o, OUTPUT);
  
  // Debugging
  Serial.begin(9600);
}


void loop(){
  // Button state initialization
  int redButtonState = digitalRead(red_i);
  int blueButtonState = digitalRead(blue_i);
  int greenButtonState = digitalRead(green_i);

  /* 
  Color mixing options:

  Red -> Red diode output
  Green -> Green diode output
  Blue -> Blue diode output

  Cyan -> Blue and green diode output
  Purple/Magenta -> Red and blue diode output
  Yellow -> Red and green diode output

  White -> All three diode output

  */
  
  if (blueButtonState == LOW) {
    b_counter++;
    delay(1000);
  }

  if (redButtonState == LOW) {
    r_counter++;
    delay(1000);
  }

  if (greenButtonState == LOW) {
    g_counter++;
    delay(1000);
    Serial.println(g_counter);
  }

  if (g_counter == 1 && b_counter == 1 && r_counter == 1) {
    digitalWrite(red_o, HIGH);
    digitalWrite(green_o, HIGH);
    digitalWrite(blue_o, HIGH);
  }
  else if (g_counter == 1 && b_counter == 1) {
    digitalWrite(red_o, LOW);
    digitalWrite(green_o, HIGH);
    digitalWrite(blue_o, HIGH);
  }

  else if (g_counter == 1 && r_counter == 1) {
    digitalWrite(red_o, HIGH);
    digitalWrite(green_o, HIGH);
    digitalWrite(blue_o, LOW);
  }

  else if (r_counter == 1 && b_counter == 1) {
    digitalWrite(red_o, HIGH);
    digitalWrite(green_o, LOW);
    digitalWrite(blue_o, HIGH);
  }
  
  else if (b_counter == 1) {
    digitalWrite(red_o, LOW);
    digitalWrite(green_o, LOW);
    digitalWrite(blue_o, HIGH);
  }
  
  else if (r_counter == 1) {
    digitalWrite(red_o, HIGH);
    digitalWrite(green_o, LOW);
    digitalWrite(blue_o, LOW);
  }
  
  else if (g_counter == 1) {
    digitalWrite(red_o, LOW);
    digitalWrite(green_o, HIGH);
    digitalWrite(blue_o, LOW);
  }

  else {
    digitalWrite(red_o, LOW);
    digitalWrite(green_o, LOW);
    digitalWrite(blue_o, LOW);
  }

  // Counters for diodes
  // Work on 1/0 basis
  if(b_counter >= 2){
    b_counter=0;
  }
  
  if(r_counter >= 2){
    r_counter=0;
  }

  if(g_counter >= 2){
    g_counter=0;
  }

  // Debugging
  // Serial.print(b_counter);
  // Serial.print(" ");
  // Serial.print(r_counter);
  // Serial.print(" ");
  // Serial.println(g_counter);
}

Challenges

In the beginning I hoped to join both the analog and digital components of the assignment, but after finishing the digital (RGB color mixer), I soon realized that I do not have enough power to put both on a breadboard as my computer was not allowing me to proceed onwards. The idea was to increase the intensity of the RGB colors, once selected through the switches by using a potentiometer. Unfortunately, since it did not work even though I tried adding more power to the circuit, I decided to recreate the concept on a separate breadboard.

Potentiometer Intensity Scale

Implementation

To implement this circuit, I used 6 LEDs, a potentiometer, resistors and wires, as well as an Arduino. The LEDs and the switch were connected in parallel to preserve the voltage across components. The LEDs and the switch were then connected to PWM outputs and analog input respectively. The diagram of the circuit is below:

To run the circuit I wrote some Arduino code which utilized the mapping function in order to sequentially light up the diodes according to the potentiometer reading.

// Potentiometer input initialization
const int p_meter = A0;

// Diode output initialization
const int p_1 = 3;
const int p_2 = 5;
const int p_3 = 6;
const int p_4 = 9;
const int p_5 = 10;
const int p_6 = 11;



void setup() {
  // Potentiometer input
  pinMode(p_meter, INPUT);

  // Diode output
  pinMode(p_1, OUTPUT);
  pinMode(p_2, OUTPUT);
  pinMode(p_3, OUTPUT);
  pinMode(p_4, OUTPUT);
  pinMode(p_5, OUTPUT);
  pinMode(p_6, OUTPUT);

  // Debugging
  Serial.begin(9600);
}

void loop() {
  // Getting reading from potentiometer
  int potentiometer = analogRead(p_meter);

  // Mapping the reading to a value between 0 and 60
  // since there are 6 diodes
  // The interwal of each diode is hence 10
  int map_p = map(potentiometer, 0, 1023, 0, 60);
  
  // The logic is the same for each diode
  // If the value of the map is in a range of 10
  // respectful to the diode's range, then map the 
  // range of 10 to an increase in brightness of the diode
  if(map_p > 0 && map_p <= 10){
    int value1 = map(map_p, 0, 10, -10, 255);
    analogWrite(p_1, value1);
  }
  // Otherwise, turn off the diode
  else if(map_p == 0){
    analogWrite(p_1, 0);
  }
  if(map_p > 10 && map_p <= 20){
    int value2 = map(map_p, 10, 20, -10, 255);
    Serial.println(value2);

    analogWrite(p_2, value2);
  }
  else if(map_p < 10){
    analogWrite(p_2, 0);
  }
  if(map_p > 20 && map_p <= 30){
    int value3 = map(map_p, 20, 30, -10, 255);
    analogWrite(p_3, value3);
  }
  else if(map_p < 20){
    analogWrite(p_3, 0);
  }
  if(map_p > 30 && map_p <= 40){
    int value4 = map(map_p, 30, 40, -10, 255);
    analogWrite(p_4, value4);
  }
  else if(map_p < 30){
    analogWrite(p_4, 0);
  }
  if(map_p > 40 && map_p <= 50){
    int value5 = map(map_p, 40, 50, -10, 255);
    analogWrite(p_5, value5);
  }
  else if(map_p < 40){
    analogWrite(p_5, 0);
  }
  if(map_p > 50 && map_p <= 60){
    int value6 = map(map_p, 50, 60, -10, 255);
    analogWrite(p_6, value6);
  }
  else if(map_p < 50){
    analogWrite(p_6, 0);
  }
}

Challenges

As stated above, I was displeased that the intensity factor was not visible within one circuit. For this circuit, the hardest part was the mapping of the values such that the code runs properly. It took some time to realize that some of the diodes were broken and were not lighting up. Since I worked a diode at a time, the fact that one would just not light up was very frustrating. It is important to check diodes before starting, which is something I will do from now on.

Reflection

This assignment was very interesting to me. Since I never worked individually on a circuit that involves code, deducing how the Arduino works in accordance to the circuit I built was a very enriching experience. The frustration over faulty components is inevitable while working with electronics but it goes to show that code is not the only thing that might mess up the end product. In the future, I wish to be able to work on a larger breadboard with a larger power input so that my laptop would not prevent me from adding as many components as I want.

Traffic Control with Photosensor.

 

Concept.

The concept for this project is pretty simple. How can traffic be regulated in a smart, optimized way such that when there are more cars and fewer pedestrians, the traffic light stays green for longer? In an advanced way, could we have sensors that could calculate traffic and find an optimized way to control them? That was how I came up with this project. The photoresist represents traffic: the light turns green when more cars are stuck in traffic. Pedestrians, on the other hand, can utilize the switch to inform the system of their intention to cross. When the switch is turned on, the traffic turns red.

 

Process.

The project features two LEDs, a photoresist to check the number of traffic, a switch, jumper wires, and four 10K ohms resistors. The photoresistor keeps track of the amount of traffic (the higher the traffic), the higher the resistance, which results in the traffic light turning green.

Challenges

One of the challenges I was faced with was designing a code that would ensure one of the lights stayed on until a condition was met. It took me a while to figure out that the “switch” statement in javascript would be the most convenient way forward. That aside, figuring out how to connect the photoresistor after appropriately connecting the LEDs and the switch proved difficult. I got to a point where I assumed the photoresistor was faulty. However, it started working after I dismantled everything and reconnected the circuit differently.

Overall, this project challenged me to think more creatively, and it also helped me gain a better understanding of coming up with appropriate Arduino circuits.

 

Week 9 – Ghost Detector

Concept

For this project, I decided to detect ghosts (or any other presence) using an ultrasonic sensor and a red “SOS” LED, and transmit a message saying “hi” using Morse code on a yellow LED. I looked up the Morse codes from this website. The circuit diagram for my ghost detector can be found below:

Implementation

I used 2 sensors for this project: an LDR and an ultrasonic sensor.
The LDR detects if the surroundings are dark enough and the ultrasonic sensor detects if there is “something” nearby 🙂

If the ultrasonic sensor detects something is near, and if the surroundings are dark, the red LED blinks an SOS signal in Morse code. While the red LED is flashing, you know something is nearby, that’s where the yellow switch comes in. When we press the yellow switch, the yellow LED starts blinking “hi” in Morse code to give a friendly message to whatever was detected by the ultrasonic sensor. While the yellow LED is flashing, the red LED doesn’t flash an SOS signal because we wish to portray a positive vibe to our new friend.

The digital part of the circuit consists of the switch that reads digital signals and turns the yellow LED on and the red LED off. The ultrasonic sensor feeds in pulse data through its ECHO pin, which is then converted into a float distance value using a simple equation. The analog part consists of an LDR which is used to detect whether it is dark enough for the red SOS to start blinking. I did an analog read to get lighting info from this sensor and used it inside the if condition for the red LED.

To implement the “SOS” and “hi” signals in the two LEDs, I made use of two functions. I utilized the idea we discussed in class where we made an LED blink. I used a simple for loop to make the LED blink the required number of times and adjusted the delays between blinks to make the LED blink fast or slow. This allowed me to depict any letter in the Morse code using my LEDs. Once this was done, I caught the readings from the sensors and the switch to make the LEDs blink accordingly.

The code for my project can be found below:

int pushButton = 4;    // for the push button switch
int red_ledPin = 11;   // Define the red LED pin number
int yellow_ledPin = 8; // Define the yellow LED pin number

const int TRIG_PIN = 10;           // Arduino pin connected to Ultrasonic Sensor's TRIG pin
const int ECHO_PIN = 12;           // Arduino pin connected to Ultrasonic Sensor's ECHO pin
const int DISTANCE_THRESHOLD = 50; // in centimeters

// distance calculation variables for ultrasonic sensor:
float duration_us, distance_cm;

// the setup routine runs once when you press reset:
void setup()
{
    pinMode(red_ledPin, OUTPUT);    // set the red LED to output mode
    pinMode(yellow_ledPin, OUTPUT); // set the yellow LED to output mode
    pinMode(TRIG_PIN, OUTPUT);      // set arduino pin to output mode
    pinMode(ECHO_PIN, INPUT);       // set arduino pin to input mode

    // initialize serial communication at 9600 bits per second:
    Serial.begin(9600);
    // make the pushbutton's pin an input:
    pinMode(pushButton, INPUT);
}

// the loop routine runs over and over again forever:
void loop()
{
    // send a 10us pulse to the ultrasonic sensor
    digitalWrite(TRIG_PIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIG_PIN, LOW);

    // measure duration of pulse from ECHO pin
    duration_us = pulseIn(ECHO_PIN, HIGH);
    // calculate the distance
    distance_cm = 0.017 * duration_us;

    // read the input pin:
    int buttonState = digitalRead(pushButton);
    int sensorValue = analogRead(A0);

    // if the button is not pressed, the distance is closer than 15cm, and it is dark enough, then blink SOS
    if (buttonState == HIGH && distance_cm < 15 && sensorValue > 800)
    {
        blinkSOS(red_ledPin);
    }
    // otherwise if the button is pressed, then blink "hi" on the yellow LED
    else if (buttonState == LOW)
    {
        digitalWrite(red_ledPin, LOW);
        blinkHi(yellow_ledPin);
    }

    // for debugging: 

    // // print out the state of the button:
    // Serial.println(buttonState);
    // delay(1); 

    // // print the value to Serial Monitor
    // Serial.print("distance: ");
    // Serial.print(distance_cm);
    // Serial.println(" cm");

    // delay(10);

    // Serial.println(sensorValue);
    // delay(1);
}

// Morse code for "SOS": ... --- ...
void blinkSOS(int ledNum)
{
    // fast blink thrice for "..."
    for (int i = 0; i < 3; i++)
    {
        digitalWrite(ledNum, HIGH); // turn the LED on (HIGH is the voltage level)
        delay(150);                 // wait for a second
        digitalWrite(ledNum, LOW);  // turn the LED off by making the voltage LOW
        delay(150);                 // wait for a second
    }
    // wait between pattern switch
    delay(500);
    // slow blink for "---"
    for (int i = 0; i < 3; i++)
    {
        digitalWrite(ledNum, HIGH); // turn the LED on (HIGH is the voltage level)
        delay(400);                 // wait for a second
        digitalWrite(ledNum, LOW);  // turn the LED off by making the voltage LOW
        delay(400);                 // wait for a second
    }
    // wait between pattern switch
    delay(500);
}

// Morse code for "hi": .... ..
void blinkHi(int ledNum)
{
    // blink 4 times for "...."
    for (int i = 0; i < 4; i++)
    {
        digitalWrite(ledNum, HIGH); // turn the LED on (HIGH is the voltage level)
        delay(150);                 // wait for a second
        digitalWrite(ledNum, LOW);  // turn the LED off by making the voltage LOW
        delay(150);                 // wait for a second
    }
    // wait between pattern switch
    delay(500);
    // blink twice for ".."
    for (int i = 0; i < 2; i++)
    {
        digitalWrite(ledNum, HIGH); // turn the LED on (HIGH is the voltage level)
        delay(150);                 // wait for a second
        digitalWrite(ledNum, LOW);  // turn the LED off by making the voltage LOW
        delay(150);                 // wait for a second
    }
    // wait between pattern switch
    delay(500);
}

Challenges

I spent a lot of time on this project playing around with wires and experimenting, especially when I was running into unusual results. The difficult part though, was that in order to test a simpler, shorter circuit to clear my confusion, I had to take apart the larger circuit I was working on since we only have one breadboard. At times I realized I was making a very small error which was almost impossible to notice in the larger circuit which had a ton of wires all over the board. Drawing the circuit diagram before implementing the physical circuit was helpful but at times I was confused as to which end a resistor would go to or if it would even make a difference. Whenever I was stuck somewhere, I tried looking at circuit diagrams for simpler, smaller circuits. For example, when I was stuck at implementing the yellow switch and was tired of trying out different connections to make it work, I looked up a simple basic circuit for a switch with an LED and tried to implement that into my larger circuit, and this proved very helpful.

The Ghost Detector

 

Sensors | Car Headlights

Concept

In this assignment, I implemented a circuit with an LDR sensor and a switch that were both used to replicate some basic functionality of car headlights.

I built an Arduino circuit that used an analog sensor and a digital sensor to control two LEDs – ‘car headlights’. Using a switch, I made two LEDs blink periodically as long as the switch is still pressed. By default state when the switch is released, two LEDs will have the brightness controlled by an LDR sensor. So, the idea was to reduce brightness when the LDR reading is high and increase it if it is low.

Demo

Code

If the switch is pressed, then 2 LEDs are blinking with some delay. If not, then the code uses the LDR value to set the brightness of LEDs to the appropriate value.

const int switchPin = 3; // the pin that the switch is connected to
const int ledPin1 = 6;   // the pin that the first LED is connected to
const int ledPin2 = 9;  // the pin that the second LED is connected to
const int ldrPin = A0;   // the pin that the LDR sensor is connected to

int switchState = 0;     // variable for reading the switch status
int ldrValue = 0;        // variable for storing the LDR sensor reading
int ledBrightness1 = 0;  // variable for storing the brightness of the first LED
int ledBrightness2 = 0;  

void setup() {
  pinMode(switchPin, INPUT);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // read the switch state
  switchState = digitalRead(switchPin);

  // blink the LEDs if the switch is pressed
  if (switchState == LOW) {
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
    delay(500);
    digitalWrite(ledPin1, HIGH);
    digitalWrite(ledPin2, HIGH);
    delay(500);
  } else {
    // read the LDR sensor value
    ldrValue = analogRead(ldrPin);

    // map the LDR sensor value to the LED brightness range (0-255)
    ledBrightness1 = map(ldrValue, 0, 1023, 255, 0);
    ledBrightness2 = map(ldrValue, 0, 1023, 255, 0);

    // adjust the LED brightness
    analogWrite(ledPin1, ledBrightness1);
    analogWrite(ledPin2, ledBrightness2);
  }

  // print the LDR sensor value to the Serial Monitor
  Serial.println(ldrValue);

  delay(100);
}

Future changes

I feel that there is a lot of room for improvement in setting the brightness using an LDR sensor. The LEDs actually keep being bright with high LDR values, and it is a bit hard to get LDR values to the low level. Yet, the LDR sensor does make them brighter when the LDR readings become low eventually.

Assignment 6: Speed-o-Meter! (Analog Input/Output)

Concept

Driving in Abu Dhabi is pretty smooth with the traffic conditions, however, the constant fear of speeding fines keeps me on my toes whenever I am out on the UAE roads. This is what exactly I thought of exploring, as soon as I found out about the presence of an Ultrasonic Sensor in our Introduction to Interactive Media kits. If it can measure distance, we can measure the time between the change in distance and it will give us speed. This speed can indicate us whether we are going too fast, borderline fast, or in the normal range.

Being inspired from this, I decided to use the newly learnt Adruino and Circuit building skills to explore this complex possibility, which seemed very simple in theory!

Overview

To give a very brief overview, the goal of this project was to use an analog and a digital to sensor the control at least two LEDs, creating various effects that can be programmed. The LDR is used as an analog sensor to control the brightness of all LEDs, while an Ultrasonic Sensor is used to calculate the speed of moving objects, which then appropriately triggers an LED – depending on the speed of the object.

Project Demonstration

Here is a brief video that shows the Speed-o-Meter in action!

As a guide, when the speed is in a decently slow range, the Green light gets switched on. As we increase it, the Yellow Light gets switched on, and when we are moving too fast, the Red Light gets switched on. The colors of these lights can intuitively indicate their intended meaning, however the exact value of speed, while not necessary to know, is beyond 40cm/s for Yellow and beyond 90 cm/s for Red.

Moreover, something that is difficult to demonstrate with the camera, is the usage of the LDR. The analog values, read in the range of 0 to 1023, from the Light Sensor, are mapped between 255 to 0, inversely! The reason for this is for a brighter light to be displayed when there is light because it is difficult to see a dim bulb during the day. This is particularly difficult to demonstrate in my circuit because of the momentarily opening nature of the lights with the speed.

Circuit Pictures

How it Works

While I have touched upon it previously, the logic was slightly complex to implement. To explain in simple terms, our Ultrasonic Sensor sends a signal and then waits for it to bounce back and then return – measuring the distance of a round trip from an object. Now let’s say, the object was moved very quickly. We send another signal, in the span of a very minute time, and then measure the distance again. This will allow us to calculate the distance that was changed, over time. Essentially, this gives us the distance travelled by an object, over a specific time. While this is not perfect, it is definitely an interesting way to calculate the speed of an object, and satisfies our use case.

This logic can be demonstrated with the following piece of code:

// Sends a Signal and waits for it to be received back by the Ultrasonic Sensor
digitalWrite(trigPin, LOW);  // Set trig pin low
delayMicroseconds(2);        // Wait for 2 microseconds
digitalWrite(trigPin, HIGH); // Set trig pin high
delayMicroseconds(10);       // Wait for 10 microseconds
digitalWrite(trigPin, LOW);  // Set trig pin low

float duration = pulseIn(echoPin, HIGH); // Measure the duration of the echo pulse
float distance = duration * 0.034 / 2;   // Calculate the distance in centimeters

float speed = 0.0;
if (distance > 0.0) {
  // Stores the Previous Distance 
  prevDistance = distance;
  delay(500); // Wait for 500 milliseconds to measure the distance again

  // Then goes for measuring the distance again!
  digitalWrite(trigPin, LOW);  // Set trig pin low
  delayMicroseconds(2);        // Wait for 2 microseconds
  digitalWrite(trigPin, HIGH); // Set trig pin high
  delayMicroseconds(10);       // Wait for 10 microseconds
  digitalWrite(trigPin, LOW);  // Set trig pin low
  duration = pulseIn(echoPin, HIGH); // Measure the duration of the echo pulse again
  distance = duration * 0.034 / 2;   // Calculate the distance in centimeters again

  // Just for debugging
  Serial.print("Previous Distance: ");
  Serial.print(prevDistance);
  Serial.print(".  New Distance:  ");
  Serial.println(distance);

  // Then measures the change in distance, over time. 
  speed = (prevDistance - distance) / 0.1; // Calculate the speed in centimeters per second

Following this, once we have the speed, I used somewhat of a State Machine to trigger the different LEDs depending on the speed. I reached the optimum speed values in the condition through trial and error, and not by some particular calculation in mind:

  Serial.print("Object Moving at Speed: ");
  Serial.print(speed);
  Serial.println(" cm/s");

if((abs(speed)<40) && abs(speed)>=5){
  analogWrite(PIN_GREEN, brightness);
  analogWrite(PIN_YELLOW, 0);
  analogWrite(PIN_RED, 0);
}
else if (abs(speed)>=40 && abs(speed)<90){
  analogWrite(PIN_YELLOW, brightness);
  analogWrite(PIN_GREEN, 0);
  analogWrite(PIN_RED, 0);
}
else if (abs(speed)>=90){
  analogWrite(PIN_RED, brightness);
  analogWrite(PIN_YELLOW, 0);
  analogWrite(PIN_GREEN, 0);
}
else{
  analogWrite(PIN_YELLOW, 0);
  analogWrite(PIN_GREEN, 0);
  analogWrite(PIN_RED, 0);
}

The LDR is incorporated by obtaining the Analog Value, and mapping it to the range of possible brightness.  This brightness is then stored in a variable and has been used appropriately to trigger our LEDs (as seen in the above code).

ldrValue = analogRead(LDR_PIN); // read the input on analog pin
brightness = map(ldrValue, 0,1023, 0, 255);
Serial.print("Brightness: ");
Serial.println(brightness);

Difficulties

Being new to circuits, this was definitely a struggle. While the flow seems simple, if I look at it now, but the process threw multiple problems at me to cater to. The one to start off is the impossible measuring of the Distance, or more like the change in distance, from the Ultrasonic Sensor. This was because I had not added a delay, and spending some time and thinking through, alongside some trial and error helped with that.

Moreover, one particular challenge, which was a dumb mistake from my end, was using the pins 13,12, and 2 for the Green, Yellow, and Red LEDs. The issue with this was nothing other than not being able to vary the brightness in correspondence with the LDR values. It was only going through online resources, and reading the notes taken in class, which helped me figure out that I should instead use pins that have ~ (like 11~, 10~, and 3~) if I want to vary the brightness.

Full Code

Though I have explained sections of code above, I am adding the entire code to this documentation since, unlike p5JS, we do not have a link to it. I’m sure this will give a good overview of how everything was put together!

const int trigPin = 8;  // Trig pin of the ultrasonic sensor
const int echoPin = 7; // Echo pin of the ultrasonic sensor
const int PIN_GREEN = 11; //Green LED connected on pin 13
const int PIN_YELLOW = 10; //Yellow LED connected on pin 12
const int PIN_RED = 3; //Yellow LED connected on pin 12
const int LDR_PIN = A0;
float prevDistance;
int ldrValue;
int brightness = 255;;

void setup() {
  Serial.begin(9600);   // Initialize serial communication
  pinMode(trigPin, OUTPUT); // Set trig pin as output
  pinMode(echoPin, INPUT);  // Set echo pin as input
  pinMode(PIN_GREEN, OUTPUT);
  pinMode(PIN_YELLOW, OUTPUT);
  pinMode(PIN_RED, OUTPUT);
}

void loop() {
  // Gets the Analog Value from the LDR Sensor
  ldrValue = analogRead(LDR_PIN); // read the input on analog pin
  brightness = map(ldrValue, 0,1023, 0, 255);
  Serial.print("Brightness: ");
  Serial.println(brightness);

  // Sends a Signal and waits for it to be received back by the Ultrasonic Sensor
  digitalWrite(trigPin, LOW);  // Set trig pin low
  delayMicroseconds(2);        // Wait for 2 microseconds
  digitalWrite(trigPin, HIGH); // Set trig pin high
  delayMicroseconds(10);       // Wait for 10 microseconds
  digitalWrite(trigPin, LOW);  // Set trig pin low
  
  float duration = pulseIn(echoPin, HIGH); // Measure the duration of the echo pulse
  float distance = duration * 0.034 / 2;   // Calculate the distance in centimeters
  
  float speed = 0.0;
  if (distance > 0.0) {
    // Stores the Previous Distance 
    prevDistance = distance;
    delay(500); // Wait for 100 milliseconds to measure the distance again

    // Then goes for measuring the distance again!
    digitalWrite(trigPin, LOW);  // Set trig pin low
    delayMicroseconds(2);        // Wait for 2 microseconds
    digitalWrite(trigPin, HIGH); // Set trig pin high
    delayMicroseconds(10);       // Wait for 10 microseconds
    digitalWrite(trigPin, LOW);  // Set trig pin low
    duration = pulseIn(echoPin, HIGH); // Measure the duration of the echo pulse again
    distance = duration * 0.034 / 2;   // Calculate the distance in centimeters again

    // Just for debugging
    Serial.print("Previous Distance: ");
    Serial.print(prevDistance);
    Serial.print(".  New Distance:  ");
    Serial.println(distance);

    // Then measures the change in distance, over time. 
    speed = (prevDistance - distance) / 0.1; // Calculate the speed in centimeters per second
  }

    Serial.print("Object Moving at Speed: ");
    Serial.print(speed);
    Serial.println(" cm/s");
  
  if((abs(speed)<40) && abs(speed)>=5){
    analogWrite(PIN_GREEN, brightness);
    analogWrite(PIN_YELLOW, 0);
    analogWrite(PIN_RED, 0);
  }
  else if (abs(speed)>=40 && abs(speed)<90){
    analogWrite(PIN_YELLOW, brightness);
    analogWrite(PIN_GREEN, 0);
    analogWrite(PIN_RED, 0);
  }
  else if (abs(speed)>=90){
    analogWrite(PIN_RED, brightness);
    analogWrite(PIN_YELLOW, 0);
    analogWrite(PIN_GREEN, 0);
  }
  else{
    analogWrite(PIN_YELLOW, 0);
    analogWrite(PIN_GREEN, 0);
    analogWrite(PIN_RED, 0);
  }

  prevDistance = 0;
  speed=0;
  distance = 0;
  
  delay(500); // Wait for 500 milliseconds before measuring again
}

 

HW6: Analog and Digital, Input & Output – “code name: Purple”

CONCEPT

For this assignment, I have made a game called “code name: Purple”. The player is presented with an RGB LED that changes color based on the reading from a photosensor. The goal of the game is to press a button when the RGB LED turns the right shade of purple, which may be not discernable to the eye, so the only way for the player to find out is to play around with the photosensor and check by pressing the button. If the button is pressed at the right photoresistor value, a green LED lights up, indicating that the player has won. If the button is pressed at the wrong photoresistor value, a red LED lights up, indicating that the player has lost.

IMPLEMENTATION

I faced several challenges while setting up the circuit. Initially, I had difficulty understanding the pin mapping for the RGB LED and the photosensor. I had to refer to the documentation and online resources to understand how to wire these components to the Arduino. After some trial and error, I was able to successfully wire the components and read the analog values from the photosensor.

Another challenge was in getting the timing of the button press just right. Initially, I had set a fixed delay between the LED turning purple and the button press is registered. However, this did not work well as the timing varied depending on the ambient light level. I had to modify my code to dynamically adjust the timing of the button press based on the current color value of the LED. After some experimentation and tweaking, I was able to get the timing of the button press just right, and the game was fully functional.

schematic used

Below is the full code.

// define pins
int redLED = 9;
int greenLED = 5;
int rgbRed = 11;
int rgbGreen = 10;
int rgbBlue = 6;
int btnPin = 7;
int photoPin = A0;

// variables
int redVal = 0;
int greenVal = 0;
int blueVal = 0;
int photoVal = 0;
int btnState = 0;

void setup() {
  // set pins
  pinMode(redLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
  pinMode(rgbRed, OUTPUT);
  pinMode(rgbGreen, OUTPUT);
  pinMode(rgbBlue, OUTPUT);
  pinMode(btnPin, INPUT);

  // initialize serial communication
  Serial.begin(9600);
}

void loop() {
  // read the photoresistor value
  photoVal = analogRead(photoPin);

  // map the photoresistor value to RGB LED color values
  redVal = map(photoVal, 0, 1023, 0, 255);
  greenVal = 0;
  blueVal = map(photoVal, 0, 1023, 255, 0);

  // set RGB LED color
  analogWrite(rgbRed, redVal);
  analogWrite(rgbGreen, greenVal);
  analogWrite(rgbBlue, blueVal);

  // read the button state
  btnState = digitalRead(btnPin);

  // WIN CONDITION
  // if RGB LED is the right shade of purple
  // ranges: 210 < red value < 220, 40 < blue value < 50
  if ((redVal >= 210 && redVal <= 220) && (blueVal >= 40 && blueVal <= 50)) {
    // if button is pressed when correct -> light the green LED
    if (btnState == 1) {
      digitalWrite(greenLED, HIGH);
      digitalWrite(redLED, LOW);
    }
    // if button not pressed
    else {
      digitalWrite(greenLED, LOW);
      digitalWrite(redLED, LOW);
    }
  }
  // LOSE CONDITION
  // if RGB LED is not the right shade of purple
  else {
    // if button is pressed when wrong -> light the red LED
    if (btnState == 1) {
      digitalWrite(greenLED, LOW);
      digitalWrite(redLED, HIGH);      
    }
    // if button is not pressed
    else {
      digitalWrite(greenLED, LOW);
      digitalWrite(redLED, LOW);
    }
  }

  // print values to serial monitor
  Serial.print("Photoresistor Value: ");
  Serial.print(photoVal);
  Serial.print("\t Red Value: ");
  Serial.print(redVal);
  Serial.print("\t Green Value: ");
  Serial.print(greenVal);
  Serial.print("\t Blue Value: ");
  Serial.print(blueVal);
  Serial.print("\t Button State: ");
  Serial.println(btnState);

  delay(100);
}

VIDEO DEMO

If the video window doesn’t show, use this link to see the demo of the game.

REFLECTION

Moving forward, there are a few things that I would add to improve the game. I would add a display that shows the player’s score and progress, to add a bit more feedback and motivation. Some audio feedback, such as a sound effect for when the button is pressed at the right time, would have been nice. I would also consider adding some power-ups that would make the game easier or more difficult. One example of such is a power-up that would make the RGB blue and red value ranges wider, allowing for less precise button presses.

Light Crystals – Digital/Analog I/O

Concept

I really wanted to play around with ultrasonic sensors and RGB Led, so for this project, I built two glowing crystals that change brightness based on how close an object is and can change colors when a button is pressed.

Final Product

Process/Challenges

I started off by first playing around with ultrasonic sensors with a tutorial I found here. Once I had that working, I slowly added more parts starting with a blue LED, then the RGB LED, and finally the switch. I wanted to present the LED in a cute and pretty way (instead of it just being there) but had a hard time finding something I could use to cover up the LEDs (I was going for a tennis ball but was not able to get one in time). When I added the LEDs, I temporarily covered them up with caps of my lip liners and since I liked the way they looked like crystals from the side I decided to keep them.

The circuit
Circuit diagram

I have already built a very similar circuit in class so this project was challenging in terms of creativity rather than technicality. I spent a lot of time trying to find a way to present my circuit without over-complicating things, and I was able to achieve that through trial and error.

 

Week 9 – Analog and Digital Input and LEDs

Concept

For the purpose of this Assignment we had to get information from at least one analog sensor and at least one digital sensor, and use this information to control at least two LEDs, one in a digital fashion and the other in an analog fashion, in some creative way. What can be more creative than a game?! So I decided to create a mini game using photoresistor, button and three different LEDs. The aim of the game is to try to get all the three LEDs on and catching that moment by clicking the button. If you would be able to simultaneously light up all three LEDs and press the button you won the game which will be indicated by mini disco show at the end. This game is not easy as the gamer should predict the distance of his finger from the photoresistor and find that sweet spot where all the three LED conditions for turning on are satisfied. Furthermore, player needs to use his/her reflexes to immediately click on the button.

Circuit

Implementation

The Arduino board has three LED lights, with three of them being regulated by an analog input device called a photoresistor. The photoresistor will determine the intensity of the red, blue, and yellow lights. I created a sensor value variable which is

sensorValue = analogRead(LDR);
depending on its value the different LEDs are on if the conditions are satisfies. In the case when the 700 < sensorValue < 800 and if all other if conditions are not satisfied the analogWrite is 0 for all three colors.  See the code below:
sensorValue = analogRead(LDR);
  
  if(sensorValue < 620){
    analogWrite(blue, 255);
    analogWrite(green, 0);
    
  }
  else if(sensorValue > 520 and sensorValue < 610){
    analogWrite(blue, 255);
    analogWrite(green, 255);
    analogWrite(yellow,255);
   
  }
  else if(sensorValue > 520 and sensorValue < 650){
    analogWrite(blue, 0);
    analogWrite(green, 255);
    
  }

For the digital interaction the led lights will be controlled by digital input, the button, and under very specific circumstances when the all three LEDs are on and the player was able to successfully catch that second and click the button the mini discoteca show at the end will depict their win. The code below if for this function:

void discoteca(){
  digitalWrite(yellow, HIGH);
  delay(100);
  digitalWrite(yellow, LOW);
  
  digitalWrite(green, HIGH);
  delay(100);
  digitalWrite(green, LOW);
  
  digitalWrite(blue, HIGH);
  delay(100);
  digitalWrite(blue, LOW);

  delay(200);
  
}

if( digitalRead(yellow)==1 and digitalRead(blue)==1 and digitalRead(green)==1 and digitalRead(SWITCH)==HIGH) {
    digitalWrite(yellow, HIGH);
    delay(400);
    disoteca();
    disoteca();
    disoteca();
  }

Schematic Diagram

Video Demo

 

Reflection & Future Improvements

Developing this Arduino project was an exciting and challenging experience for me. It allowed me to combine my knowledge of analog and digital sensors, LED lights, and programming to create an entertaining mini game. there are several areas where I can improve it in the future. For instance, I could incorporate a timer that counts down the seconds before the LEDs turn off, which would add an additional level of difficulty to the game. Another possible improvement would be to incorporate different levels of difficulty, such as changing the optimal distance of the player’s finger from the photoresistor or increasing the number of LEDs required to win the game. Overall, this project was a great learning experience for me, and I look forward to implementing these improvements and exploring other creative Arduino projects in the future.

Assignment 6: Analog Input & Output (Mood Lamp!)

Concept & Inspiration

As part of the 6th Assignment of Intro to IM, we were tasked with the objective of reading input from at least one analog sensor, and at least one digital sensor (switch). This data would then be used to control at least two LEDs, one in a digital fashion and the other in an analog fashion, in some creative way.

I have always had a great emphasis on the ‘lighting’ around me, and therefore am fond of purchasing different lamps and setting them up to have a good ambiance. This brings me to an interesting lamp I saw once at the convenience store, called Mood Lamp. If you are not aware of what those are, the following video should help you get an idea of it:

Therefore, being inspired from the concept of a ‘switching’ light and wanting to add some additional functionality to it, I decided to test my Arduino and Circuit Making skills to implement a model Mood Lamp. The concept was to use the button or switch as the digital sensor and the light sensor as the analog sensor (controlled by another button) which modifies the brightness of the light. The primary button would be used to modify the color modes of the LED, and a secondary button would toggle the brightness functionality of the light sensor.

Implementation

Pictures of Circuit

With this, I produced the following circuit:

Demo Video

A demo video, in detail, can be seen here:

The implementation of the Mood Lamp on the breadboard can be seen above. To make it clear, since the quality of Video did not allow the RGB LED Bulb to be captured to perfection, the Switch on the right, Yellow colored, is used to switch between the different modes of light. In our case, the modes are: Switched Off, Rainbow (Fading), Blue, Green, and Red. Alongside this, the blue button on the left, toggles the brightness adjustment option by making use of the light sensor. The meaning of this is, if the light in the room is brighter, the bulb will glow brighter, and if the light is less, it will grow lighter. Since it is a mood lamp, usually used at night, the purpose of it is to adapt with the light. At night, it should automatically adapt to the surrounding light to make its own light visible.

Code

Since the Code cannot be linked with Arduino, unlike P5js, I will be pasting the entire code here for anyone’s reference!

// Declaration of Constants
const int BUTTON_PIN_LIGHT = 7;  // Connecting the Light Button to Pin 7
const int BUTTON_PIN_LDR = 8;  // Connecting the Photoresistor Button to Pin 7
const int PIN_RED   = 9; //Red LED connected on pin 9
const int PIN_GREEN = 10; //Green LED connected on pin 10
const int PIN_BLUE  = 11; //Blue LED connected on Pin 11
const int LIGHT_SENSOR_PIN = A0; // Connecting the Photoresistor to Pin A0
   
//Color intensities and direction
//Initial Values for the Fading Rainbow Color Mode
int red             = 254;
int green           = 1;
int blue            = 117;
int red_direction   = -1;
int green_direction = 1;
int blue_direction  = -1;
  
// Function to set the color of the RGB LED
void setColor(int R, int G, int B) {
  analogWrite(PIN_RED,   R);
  analogWrite(PIN_GREEN, G);
  analogWrite(PIN_BLUE,  B);
}

// Declaration of changing variables
int ledState = 1; // tracks the current state of LED
int ldrState = 1; // tracks the current state of LED
int lastlightButtonState; // the previous state of the light button
int currentlightButtonState; // the current state of the light button
int lastLDRButtonState; // the previous state of the ldr button
int currentLDRButtonState; // the current state of the ldr button
int analogValue; // tracks the light intensity from the LDR
int brightness; // tracks the brightness extracted from the analog Input
  
void setup() {
  Serial.begin(9600);
  // Settings the Inputs and Outputs of the previously specified pins
  pinMode(BUTTON_PIN_LIGHT, INPUT);
  pinMode(PIN_RED,   OUTPUT);
  pinMode(PIN_GREEN, OUTPUT);
  pinMode(PIN_BLUE,  OUTPUT);
  // Detect initial values of the buttons
  currentlightButtonState = digitalRead(BUTTON_PIN_LIGHT);
  currentLDRButtonState = digitalRead(BUTTON_PIN_LDR);
}
  
void loop() {
  lastlightButtonState  = currentlightButtonState; // Store Previous State of the light button
  currentlightButtonState = digitalRead(BUTTON_PIN_LIGHT); // Get new state of the light button
  // Same for the LDR Button
  lastLDRButtonState  = currentLDRButtonState;
  currentLDRButtonState = digitalRead(BUTTON_PIN_LDR);

  // Gets the Analog Value from the LDR Sensor
  Serial.print("Light Sensor Value: ");
  analogValue = analogRead(LIGHT_SENSOR_PIN); // read the input on analog pin
  Serial.println(analogValue);

  // Detects if there has been a change in the state of the switch - if it has been pressed
  if(lastLDRButtonState == HIGH && currentLDRButtonState == LOW) {
    Serial.println("LDR (Blue) Button is pressed: ");
    // Change state of LDR Switch
    if(ldrState == LOW) {
       ldrState = HIGH;  
       Serial.println("Turning Brightness Variation on");
    }
    else {
      ldrState = LOW;
      Serial.println("Turning Brightness Variation off");
    }
  }

  if (ldrState==HIGH){  // If the Brightness option has been switched on
    brightness = map(analogValue, 0,1023, 0, 255);
  }
  else{ // Otherwise
    brightness = 255;
  }

  // If the light button has been toggled
  if(lastlightButtonState == HIGH && currentlightButtonState == LOW) {
    Serial.print("Light (Yellow) Button is pressed: ");

    Serial.println(ledState);
  
    // Change the state of LED
    if(ledState == 0) {
       ledState = 1;  
       setColor(0, 0, 0); //set LED to Off
    }
    else if (ledState == 1){
      ledState = 2;
      Serial.println("Turning LED Rainbow");
    }
    else if (ledState == 2){
      ledState = 3;
      Serial.println("Turning LED Blue");
    }
    else if (ledState == 3){
      ledState = 4;
      Serial.println("Turning LED Green");
    }
    else{
      ledState = 0;
      Serial.println("Turning LED Red");
    } 
  }
  // Changing the colors of the LEDs depending on the State they should be in
  if (ledState == 2){
      red = red + red_direction;
      green = green + green_direction;
      blue = blue + blue_direction;
        
      // Change direction for each color if it reaches 255
      if (red >= brightness || red <= 0)
      {
        red_direction = red_direction * -1;
      }
      if (green >= brightness || green <= 0)
      {
        green_direction = green_direction * -1;
      }
      if (blue >= brightness || blue <= 0)
      {
        blue_direction = blue_direction * -1;
      }
      setColor(red, green, blue);
  }
  else if (ledState == 3){
    setColor(0, 0, brightness); //set LED to Blue
  }
  else if (ledState == 4){
    setColor(0, brightness, 0); //set LED to Green
  }
  else if (ledState == 0){
    setColor(brightness, 0, 0); //set LED to Red
  }
}

// References taken from:
// https://www.thegeekpub.com/277872/arduino-rgb-led-tutorial/
// https://www.thegeekpub.com/275412/use-a-button-to-toggle-an-led-arduino-tutorial/
// https://www.thegeekpub.com/275412/use-a-button-to-toggle-an-led-arduino-tutorial/

 

The code is making use of complex state machines, particularly the ledState, and even the ldrState. These states are toggled with the pressing of buttons, and then ultimately control the modifications to other values

Difficulties & Improvements

As I am controlling the brightness, in the RGB LED, I was able to control the brightness when each individual light was switched on only itself with some discrete value. However, as the values fluctuated for the Rainbow mode, the implementation of the Brightness option did not go as planned:

if (ledState == 2){
    red = red + red_direction;
    green = green + green_direction;
    blue = blue + blue_direction;
      
    // Change direction for each color if it reaches 255
    if (red >= brightness || red <= 0)
    {
      red_direction = red_direction * -1;
    }
    if (green >= brightness || green <= 0)
    {
      green_direction = green_direction * -1;
    }
    if (blue >= brightness || blue <= 0)
    {
      blue_direction = blue_direction * -1;
    }
    setColor(red, green, blue);
}

As shown above, I have tried to set the maximum values as the brightness, however, since the values are changing very fast, there is some issue with the brightness not being adjusted with the above code. I have tried to implement the usage of MOD, like red%brightness, but that has resulted in no effort either!

Visual Distance Detector

The idea of this work was inspired by the car parking sensor. While parking your car starts playing a sound that gets louder the closer you get to an object. Likewise in my Arduino the close you get to the object the “Redder” the RGB LED light becomes. The farther you are from the object, the sensor becomes a blueish color. This way you can visually measure the distance between you and an object.

The ultrasonic sensor measures the time taken to get the response back from the object, which I later converted into the distance. RGB LED light displays the color based on the distance calculated before. A switch turns on the whole program when pressed. To display, the program works a green LED light lights on when the switch is pressed.

 

 

This snippet of the code is the main logic of the program. Quite simple. If the button is pressed then display the distance by showing Red and Blue colors. Otherwise, turn them to zero, and the green Led light to Low value.

rgb_color_value= constrain(distance, 0, 255);
  if (digitalRead(BUTTON_PIN) == HIGH) {
    digitalWrite(LED_PIN, HIGH);
    analogWrite(PIN_RED, max(0, 255 - 2 * rgb_color_value));
    analogWrite(PIN_BLUE, rgb_color_value);
  }
  else {
    digitalWrite(LED_PIN, LOW);
    analogWrite(PIN_RED, 0);
    analogWrite(PIN_BLUE, 0);
  }

In the future, I would like to add the sound just like in the car. This will allow measuring distance without looking anywhere. Also, a cool idea would be added to connect a projector to Arduino that displays an image stating “Stop! Too close” or “It’s ok. Go farther”. It would definitely look cool 🙂