Project 1 – Switches & Analogs

Switch

The switch based portion of my project utilizes a toggle switch, push button, and LED light in order to create a device that allows a user to input a pattern that will then be repeated back via the light. When the switch is toggled to the “on” (high) position, the Arduino will begin to record when the button is pressed, how long it is pressed, and the time between its release and the next press. When the switch is then changed back to the “off” (low) position, it will then continually repeat the pattern that was entered. The switch can be turned on again in order to enter a new patter.

Both the switch and button are connected to the 5V rail on the breadboard for power, with a second wire connecting to pins 12 and 11, respectively, and a 10k resistor grounding them. The LED connects to pin 13 and is grounded with a 1k resistor.

My initial attempt to program the functionality of the device worked overall but doesn’t replicate the patter exactly. Because of how I recorded the time, the gap between when the switch is flipped and the button is first pressed is used as the initial time for the light to be on. Therefore, the entire pattern is off from there and the final button press is not recorded.

The original code that is mostly accurate to the pattern entered.

/*
 * Jordan Machalek
 * Project 1 switch code
 * Version 1
 */

// Pins
const int buttonPin = 11;
const int switchPin = 12;
const int redLedPin= 13;

unsigned long previousTime = 0;
unsigned long onTimes[100];
unsigned long offTimes[100];
int delayCount = 0;

int switchState = LOW; // value of the toggle switch
int prevSwitchState = LOW; // state that the switch was in prior to a new loop() iteration
int buttonState = LOW; // value of the push button
int prevButtonState = LOW; // state that the button was in prior to a new loop iteration

void setup() {
 pinMode(buttonPin, INPUT);
 pinMode(switchPin, INPUT);
 pinMode(redLedPin, OUTPUT);

 Serial.begin(9600);
}

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

  // record the time
  unsigned long currentTime = millis();

  // HIGH == record a pattern
  if(switchState == HIGH) {
    // if the switch was just flipped, clear data
    if(prevSwitchState == LOW) {
      // Clear the onTimes array
      for(int i = 0; i < 100; i++) {
        onTimes[i] = 0;
      }
      delayCount = 0;
      previousTime = currentTime;
      // set prevSwitchState to HIGH so this only happens once when the switch is flipped
      prevSwitchState = HIGH; 
    }
    
    // only get the button's state if it is being recorded
    buttonState = digitalRead(buttonPin);

    if(buttonState == HIGH && prevButtonState == LOW) {
      digitalWrite(redLedPin, HIGH); // Turn on the light to show the button was pressed
      // Save the elapsed time - the difference between the current time and the last time the button was pushed
      currentTime = millis();
      onTimes[delayCount] = (currentTime - previousTime);
      // set prevButtonState to HIGH so the next loop will record the time difference
      // between the button being depressed and being released
      prevButtonState = HIGH; 
    }
    else if(buttonState == LOW && prevButtonState == HIGH){
        offTimes[delayCount] = (currentTime - previousTime);
        delayCount++;
        previousTime = currentTime; // Update the previous time
        prevButtonState = LOW;
        digitalWrite(redLedPin, LOW);
    }
  } 
  else { // LOW == play the pattern back
    Serial.println("Loop start");
    for(int i = 0; i < delayCount; i++) {
      Serial.println(i);
      digitalWrite(redLedPin, HIGH);
      Serial.print("onTime: ");
      Serial.println(onTimes[i]);
      delay(onTimes[i]);
      digitalWrite(redLedPin, LOW);
      Serial.print("offTime: ");
      Serial.println(offTimes[i]);
      delay(offTimes[i]);
    }
    // Give a 4s buffer before restarting the pattern
    Serial.println("Wait 4s");
    delay(4000);
    // 
    prevSwitchState = LOW;
  }
}

A revised version that attempts to correct how the time between button presses and releases are recorded.

/*
 * Jordan Machalek
 * Project 1 switch code
 * Version 2
 */

// Pins
const int buttonPin = 11;
const int switchPin = 12;
const int redLedPin= 13;

unsigned long currentOnTime = 0;
unsigned long currentOffTime = 0;
unsigned long previousOnTime = 0;
unsigned long previousOffTime = 0;
unsigned long onTimes[100];
unsigned long offTimes[100];
int delayCount = 0;

int switchState = LOW; // value of the toggle switch
int prevSwitchState = LOW; // state that the switch was in prior to a new loop() iteration
int buttonState = LOW; // value of the push button
int prevButtonState = LOW; // state that the button was in prior to a new loop iteration

void setup() {
 pinMode(buttonPin, INPUT);
 pinMode(switchPin, INPUT);
 pinMode(redLedPin, OUTPUT);

 Serial.begin(9600);
}

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

//  currentOnTime = millis();
//  currentOffTime = millis();
  
  // HIGH == record a pattern
  if(switchState == HIGH) {
    // if the switch was just flipped, clear data
    if(prevSwitchState == LOW) {
      // Clear the onTimes array
      for(int i = 0; i < 100; i++) {
        onTimes[i] = 0;
      }
      delayCount = 0;
      currentOnTime = 0;
      currentOffTime = 0;
      previousOnTime = 0;
      previousOffTime = 0;
      
      // set prevSwitchState to HIGH so this only happens once when the switch is flipped
      prevSwitchState = HIGH; 
    }
    
    // only get the button's state if it is being recorded
    buttonState = digitalRead(buttonPin);

    if(buttonState == HIGH && prevButtonState == LOW) { // Button was just pressed
      
      // Save the time that the button was pressed at
      // On the first iteration, the prevOnTime will be 0. So: current - prev = current
      currentOnTime = millis();
      previousOffTime = currentOffTime;

      // set prevButtonState to HIGH so the next loop will record the time difference
      // between the button being depressed and being released
      prevButtonState = HIGH; // record that the button was pressed
      digitalWrite(redLedPin, HIGH); // Turn on the light to show the button was pressed
    }
    else if(buttonState == HIGH && prevButtonState == HIGH) { // Button is being held
      // Update the time
      currentOnTime = millis();
    }
    else if(buttonState == LOW && prevButtonState == HIGH){ // Button button was just released
        // Save the duration that the button was pressed
        onTimes[delayCount] = (currentOnTime - previousOnTime);
        
        previousOnTime = currentOnTime; // Update the previous on time
        
        delayCount++;
        prevButtonState = LOW; // record that the button was released
        digitalWrite(redLedPin, LOW); // Turn off the light to show the button was released
    }
    else if (buttonState == LOW && prevButtonState == LOW) { // Button has not been pressed
      // Update the time
      currentOffTime = millis();

      // Save the duration that the button was not pressed
      offTimes[delayCount] = (currentOffTime - previousOffTime);     
    }
  } 
  else { // LOW == play the pattern back
    Serial.println("Loop start");
    for(int i = 0; i < delayCount; i++) {
      Serial.println(i);
      
      // Turn on
      digitalWrite(redLedPin, HIGH);
      Serial.print("onTime: ");
      Serial.println(onTimes[i]);
      delay(onTimes[i]);
      
      // Turn off
      digitalWrite(redLedPin, LOW);
      Serial.print("offTime: ");
      Serial.println(offTimes[i]);
      delay(offTimes[i]);
    }
    
    // Give a 4s buffer before restarting the pattern
    Serial.println("Wait 4s");
    delay(4000);
    
    // Note that the switch has been turned off
    prevSwitchState = LOW;
  }
}

Analog

For my analog device, I utilized a combination of photocells and an RGB LED. These components are set up in such a way that the value recorded from the first through third cells will be analogous to the red, green, and blue diodes of the light.

The three short pins of the LED are wired into PWM slots 9-11 on the board, with a 1k resistor included in the circuit. Because the LED I am using is of the common anode type, the long pin is connected to the 5V power rail on the breadboard. If it were a common anode LED, it would instead connect to the ground rail. As for the photocells, each is connected between the 5V rail an a rail of its own. A 10k resistor grounds each cell while a wire attaches back to analog pins A0-A2.

In the code, constant variables are used for each of the three digital and three analog pins. A further three variables hold the values of recorded from each of the photocells. Each iteration of the loop the value from the cells will first be recorded using analogRead(). These values are then mapped from the range of 0 – 1024 to the range of 0 – 255 to correspond with the values that can be passed to each of the pins of the RGB LED. Finally, the mapped values are applied to the light using three calls of analogWrite() within the function setLED().

/*
 * Jordan Machalek
 * Project 1 analog sensor code
 */

// Pins
const int redLightPin= 11;
const int greenLightPin = 10;
const int blueLightPin = 9;
const int redSensorPin = A0;
const int greenSensorPin = A1;
const int blueSensorPin = A2;

// Analog sensor values
int redSensorVal = 0;
int greenSensorVal = 0;
int blueSensorVal = 0;

void setup() {
  pinMode(redLightPin, OUTPUT);
  pinMode(greenLightPin, OUTPUT);
  pinMode(blueLightPin, OUTPUT);
}

void loop() {  
  // Get values from the photocells
  redSensorVal = analogRead(redSensorPin);
  greenSensorVal = analogRead(greenSensorPin);
  blueSensorVal = analogRead(blueSensorPin);

  // Map sensor values to LED values
  int redMap = map(redSensorVal, 0, 1024, 0, 255);
  int greenMap = map(greenSensorVal, 0, 1024, 0, 255);
  int blueMap = map(blueSensorVal, 0, 1024, 0, 255);

  // Apply color to light
  setLED(redMap, greenMap, blueMap);

  // Keep the same color for 2 seconds
  delay(2000);
}

void setLED(int redVal, int greenVal, int blueVal)
 {
  analogWrite(redLightPin, 255 - redVal);
  analogWrite(greenLightPin, 255 - greenVal);
  analogWrite(blueLightPin, 255 - blueVal);
}

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create your website at WordPress.com
Get started
%d bloggers like this: