Tuesday, February 3, 2015

Deluxe arduino Lights & Sensors


Okay, so this is my deluxe project: a custom circuit board with buttons for controlling different patterns displayed with LED lights, plus a two-channel light meter function and a dial for making adjustments.




Here are the functions (not exactly in the order of the code):

      1. Fade (alternating) of lights 2-3 on each side; this choice corresponds to pins that support Pulse Code Modulation to get the dimming effect, not all pins can do it and this is the only combination that would be symmetrical for my light meter configuration. This function is the default, it's the last "else" statement, so "if" none of the buttons have been pushed, then it just does this. The potentiometer dial affects the speed of the dimming.

      2. Static Fade test: this sets all "dimmable" pins to dim according to the potentiometer dial, all the other lights are on full blast for comparison.

      3. NightRider (up-and-down) effect. (speed affected by potentiometer dial).

      4. Reverse NightRider: one column goes up while the other goes down. (speed affected by potentiometer dial).

      5. Ambulance effect: a blinking pattern (speed affected by potentiometer dial).

      6. Dual-Channel Light Sensor Display (My Fav!): this displays the results of two photo-resistors each on one of the LED columns. Pointing this in a few directions can give a pretty good idea which way to travel toward or away from the light... it could part of some sort of line-following vehicle. You can see in the setup of the code that I manually set the amount of light to cause each LED to illuminate. I also wrote a few lines to calibrate each of the five levels, to match the two photo-resistors that have small variations. In a room of typical brightness, I was getting readings in the 700-800s (out of 1023 levels), and could get in the 900s by shining light directly on the sensor... In a dark room, I was getting readings down closer 400 and even below. Converted to percentages for my own visualization, the levels to activate the LEDs are currently set to brightness measurements of 35%, 50%, 65%, 89%, and 90%. I think a fun addition to the code would be to allow the dial to adjust sensitivity, or to run a function to automatically set sensitivity according to the history of the sensor... basically so that at any brightness, the display could be more sensitive and show smaller differences.

Video: https://www.youtube.com/watch?v=Lkc7C2bI9zM
Here's a schematic drawing of the circuit. The Arduino is the box in the middle:

 
And next you can see some very messy practice... It took me some experimentation to figure out where to orient the symbols in order to have a clean drawing... in the end, I think that process helped me to better understand the circuits.



Code:

  /*
  Light Meter - AnalogReadSerial
  Nic Hansen - 20150201
 
  Reads analog and digital inputs and prints the result to the serial monitor.
  This example code is in the public domain.
  */

//============================================================
//=======================VARIABLES============================
//============================================================
// set names for pins and variables
  int button1 = 0;
  int button2 = 1;
  int button3 = 2;
  int button4 = 3;
// set names for LED lights 1-5 are left column, 6-10 are right column, low numbers at bottom.
  int led1 = 4;
  int led2 = 5;
  int led3 = 6;
  int led4 = 7;
  int led5 = 8;
  int led6 = 9;
  int led7 = 10;
  int led8 = 11;
  int led9 = 12;
  int led10 = 13;
// Light Meter Sensitivity.
  int light1 = 35; // % of light sensor to make first indicator illuminate.
  int light2 = 50; // % of light sensor to make second indicator illuminate.
  int light3 = 65; // % of light sensor to make third indicator illuminate.
  int light4 = 80; // % of light sensor to make fourth indicator illuminate.
  int light5 = 90; // % of light sensor to make fifth indicator illuminate.
  int lightCal1 = 9; // % to calibrate mismatched sensors; this reduces effect of one sensor.
  int lightCal2 = 17; // % to calibrate mismatched sensors; this reduces effect of one sensor.
  int lightCal3 = 14; // % to calibrate mismatched sensors; this reduces effect of one sensor.
  int lightCal4 = 7; // % to calibrate mismatched sensors; this reduces effect of one sensor.
  int lightCal5 = 4; // % to calibrate mismatched sensors; this reduces effect of one sensor.
// set other variables...
  int potPercent1 = 777;    // % of position of potentiometer.
  int sensorPercent1 = 777; // % of light sensed by photoresistor.
  int sensorPercent2 = 777; // % of light sensed by photoresistor.
  int brightness1 = 250;     //how bright the LED is out of 255.
  int brightness2 = 30;       //how bright the LED is out of 255.
  int fadeAmt1 = -20;        // the number of units of adjustment per cycle (on scale of 255).
  int fadeAmt2 = 20;         // the number of units of adjustment per cycle (on scale of 255).
  int fadeDelay = 30;       // milliseconds between fade adjustments (higher = slower).


//============================================================
//========================SETUP===============================
//============================================================
// the setup routine runs once when you press reset:
void setup()
{
// initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
// set first 4 pins to input buttons, using internal Pullup resistor so LOW will indicate push.
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(button3, INPUT_PULLUP);
  pinMode(button4, INPUT_PULLUP);
// set last 10 pins for LED lights
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led8, OUTPUT);
  pinMode(led9, OUTPUT);
  pinMode(led10, OUTPUT);
}


//============================================================
//=========================LOOP===============================
//============================================================
// the loop routine runs over and over again forever:
void loop()
{
  //............................................................
  //....................Read Sensors............................
  //............................................................
  // read the input on analog pins 0,1,2, and digital pints 0-4:
    int potValue1 = analogRead(A0);
    int sensorValue1 = analogRead(A1);
    int sensorValue2 = analogRead(A2);
    int buttonValue1 = digitalRead(button1);
    int buttonValue2 = digitalRead(button2);
    int buttonValue3 = digitalRead(button3);
    int buttonValue4 = digitalRead(button4);
  // print out the value you read:
    Serial.println("Values");
    Serial.println(potValue1);
    Serial.println(sensorValue1);
    Serial.println(sensorValue2);
    Serial.println(buttonValue1);
    Serial.println(buttonValue2);
    Serial.println(buttonValue3);
    Serial.println(buttonValue4);
    delay(1); // delay in between reads for stability
  // equations
    potPercent1 = ( 100 * ((float)potValue1 / 1023) );
    sensorPercent1 = ( 100 * ((float)sensorValue1 / 1023) );
    sensorPercent2 = ( 100 * ((float)sensorValue2 / 1023) );
  // print out the results of equations:
    Serial.println("percents");
    Serial.println(potPercent1);
    Serial.println(sensorPercent1);
    Serial.println(sensorPercent2);
    delay(1); // delay in between reads for stability

 
//............................................................
//..................Ambulance Effect..........................
//............................................................
    if ( ( buttonValue1 == 0 ) && ( buttonValue4 == 0 ) )
    {
        // first set of lights on/off
        digitalWrite(led1, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led3, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led5, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led7, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led9, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led2, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led4, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led6, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led8, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led10, LOW);   // turn the LED off by making the voltage LOW
        delay( potPercent1 * 5 );         // wait
        // second set of lights on/off
        digitalWrite(led2, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led4, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led6, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led8, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led10, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led1, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led3, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led5, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led7, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led9, LOW);   // turn the LED off by making the voltage LOW
        delay( potPercent1 * 5 );         // wait
    }
   

//............................................................
//....................Dimmed Lights...........................
//............................................................ 
    else
    {
    if ( ( buttonValue1 == 0 ) && ( buttonValue3 == 0 ) )
    {
        // first set of lights on/off
        digitalWrite(led1, HIGH);   // turn the LED on (HIGH is the voltage level)
        analogWrite(led2, ( ( 1023 - potValue1 ) / 4 ) );   // turn the LED on according to dial
        analogWrite(led3, ( ( 1023 - potValue1 ) / 4 ) );   // turn the LED on according to dial
        digitalWrite(led4, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led5, HIGH);   // turn the LED on (HIGH is the voltage level)
        analogWrite(led6, ( ( 1023 - potValue1 ) / 4 ) );    // turn the LED on according to dial
        analogWrite(led7, ( ( 1023 - potValue1 ) / 4 ) );    // turn the LED on according to dial
        analogWrite(led8, ( ( 1023 - potValue1 ) / 4 ) );    // turn the LED on according to dial
        digitalWrite(led9, HIGH);    // turn the LED on (HIGH is the voltage level)
        digitalWrite(led10, HIGH);   // turn the LED on (HIGH is the voltage level)
    }


//............................................................
//....................Night Rider.............................
//............................................................
    else
    {
    if ( buttonValue3 == 0 )
    {
        // LED motion
        digitalWrite(led1, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led6, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led2, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led7, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led1, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led6, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led3, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led8, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led2, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led7, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led4, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led9, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led3, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led8, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led5, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led10, HIGH);  // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led4, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led9, LOW);    // turn the LED off by making the voltage LOW
        delay(potPercent1 / 10);    // wait
        digitalWrite(led5, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led10, LOW);   // turn the LED off by making the voltage LOW
   
        // read inputs
        potValue1 = analogRead(A0);
        sensorValue1 = analogRead(A1);
        sensorValue2 = analogRead(A2);
        buttonValue1 = digitalRead(button1);
        buttonValue2 = digitalRead(button2);
        buttonValue3 = digitalRead(button3);
        buttonValue4 = digitalRead(button4);
        // print out the value you read:
        Serial.println("Values");
        Serial.println(potValue1);
        Serial.println(sensorValue1);
        Serial.println(sensorValue2);
        Serial.println(buttonValue1);
        Serial.println(buttonValue2);
        Serial.println(buttonValue3);
        Serial.println(buttonValue4);
        delay(1); // delay in between reads for stability
        // equations
        potPercent1 = ( 100 * ((float)potValue1 / 1023) );
        sensorPercent1 = ( 100 * ((float)sensorValue1 / 1023) );
        sensorPercent2 = ( 100 * ((float)sensorValue2 / 1023) ); 
        // print out the results of equations:
        Serial.println("percents");
        Serial.println(potPercent1);
        Serial.println(sensorPercent1);
        Serial.println(sensorPercent2);
        delay(1); // delay in between reads for stability
   
        //LED returning motion
        digitalWrite(led5, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led10, HIGH);  // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led4, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led9, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led5, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led10, LOW);   // turn the LED off by making the voltage LOW
        digitalWrite(led3, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led8, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led4, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led9, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led2, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led7, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led3, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led8, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led1, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led6, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led2, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led7, LOW);    // turn the LED off by making the voltage LOW
        delay(potPercent1 / 10);    // wait
        digitalWrite(led1, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led6, LOW);    // turn the LED off by making the voltage LOW
    }


//............................................................
//....................Light Meter.............................
//............................................................
    else
    {
    if (buttonValue1 == 0 )
    { 
        // Left Column Meter
        if ( sensorPercent1 > light1 ) {
        digitalWrite(led1, HIGH);           // turn the LED on (HIGH is the voltage level)
        } 
        else {
        digitalWrite(led1, LOW);            // turn the LED off by making the voltage LOW
        }
        if ( sensorPercent1 > light2 ) {
        digitalWrite(led2, HIGH);           // turn the LED on (HIGH is the voltage level)
        } 
        else {
        digitalWrite(led2, LOW);            // turn the LED off by making the voltage LOW
        }
        if ( sensorPercent1 > light3 ) {
        digitalWrite(led3, HIGH);           // turn the LED on (HIGH is the voltage level)
        } 
        else {
        digitalWrite(led3, LOW);            // turn the LED off by making the voltage LOW
        }
        if ( sensorPercent1 > light4 ) {
        digitalWrite(led4, HIGH);           // turn the LED on (HIGH is the voltage level)
        } 
        else {
        digitalWrite(led4, LOW);            // turn the LED off by making the voltage LOW
        }
        if ( sensorPercent1 > light5 ) {
        digitalWrite(led5, HIGH);           // turn the LED on (HIGH is the voltage level)
        } 
        else {
        digitalWrite(led5, LOW);            // turn the LED off by making the voltage LOW
        }
       
        // Right Column Meter
        if ( sensorPercent2 > light1 + lightCal1 ) {
        digitalWrite(led6, HIGH);           // turn the LED on (HIGH is the voltage level)
        } 
        else {
        digitalWrite(led6, LOW);            // turn the LED off by making the voltage LOW
        }
        if ( sensorPercent2 > light2 + lightCal2 ) {
        digitalWrite(led7, HIGH);           // turn the LED on (HIGH is the voltage level)
        } 
        else {
        digitalWrite(led7, LOW);            // turn the LED off by making the voltage LOW
        }
        if ( sensorPercent2 > light3 + lightCal3 ) {
        digitalWrite(led8, HIGH);           // turn the LED on (HIGH is the voltage level)
        } 
        else {
        digitalWrite(led8, LOW);            // turn the LED off by making the voltage LOW
        }
        if ( sensorPercent2 > light4 + lightCal4 ) {
        digitalWrite(led9, HIGH);           // turn the LED on (HIGH is the voltage level)
        } 
        else {
        digitalWrite(led9, LOW);            // turn the LED off by making the voltage LOW
        }
        if ( sensorPercent2 > light5 + lightCal5 ) {
        digitalWrite(led10, HIGH);           // turn the LED on (HIGH is the voltage level)
        } 
        else {
        digitalWrite(led10, LOW);            // turn the LED off by making the voltage LOW
        }
    }
   
   
//............................................................
//..................Reverse Night Rider.......................
//............................................................
    else
    {
    if ( buttonValue4 == 0 )
    {
        // LED start Reverse NightRider motion (left up, right down)
        digitalWrite(led1, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led10, HIGH);  // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led2, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led9, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led1, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led10, LOW);   // turn the LED off by making the voltage LOW
        digitalWrite(led3, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led8, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led2, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led9, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led4, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led7, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led3, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led8, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led5, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led6, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led4, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led7, LOW);    // turn the LED off by making the voltage LOW
        delay(potPercent1 / 10);    // wait
        digitalWrite(led5, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led6, LOW);    // turn the LED off by making the voltage LOW
 
        // read inputs
        potValue1 = analogRead(A0);
        sensorValue1 = analogRead(A1);
        sensorValue2 = analogRead(A2);
        buttonValue1 = digitalRead(button1);
        buttonValue2 = digitalRead(button2);
        buttonValue3 = digitalRead(button3);
        buttonValue4 = digitalRead(button4);
        // print out the value you read:
        Serial.println("Values");
        Serial.println(potValue1);
        Serial.println(sensorValue1);
        Serial.println(sensorValue2);
        Serial.println(buttonValue1);
        Serial.println(buttonValue2);
        Serial.println(buttonValue3);
        Serial.println(buttonValue4);
        delay(1); // delay in between reads for stability
        // equations
        potPercent1 = ( 100 * ((float)potValue1 / 1023) );
        sensorPercent1 = ( 100 * ((float)sensorValue1 / 1023) );
        sensorPercent2 = ( 100 * ((float)sensorValue2 / 1023) ); 
        // print out the results of equations:
        Serial.println("percents");
        Serial.println(potPercent1);
        Serial.println(sensorPercent1);
        Serial.println(sensorPercent2);
        delay(1); // delay in between reads for stability
   
        // LED return motion (left down, right up)
        digitalWrite(led5, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led6, HIGH);  // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led4, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led7, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led5, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led6, LOW);   // turn the LED off by making the voltage LOW
        digitalWrite(led3, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led8, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led4, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led7, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led2, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led9, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led3, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led8, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led1, HIGH);   // turn the LED on (HIGH is the voltage level)
        digitalWrite(led10, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(potPercent1);         // wait
        digitalWrite(led2, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led9, LOW);    // turn the LED off by making the voltage LOW      
    }
     

//............................................................
//.......................Fader................................
//............................................................
    else
    {
        // turn off holdover lights from other functions (eg., light meter).
        digitalWrite(led1, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led4, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led5, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led6, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led9, LOW);    // turn the LED off by making the voltage LOW
        digitalWrite(led10, LOW);   // turn the LED off by making the voltage LOW   
        // initialize LEDs.
        analogWrite(led2, brightness1);
        analogWrite(led3, brightness1);
        analogWrite(led7, brightness2);
        analogWrite(led8, brightness2);
        // change brightness values for next time through the loop.
        brightness1 = brightness1 + fadeAmt1;
        brightness2 = brightness2 + fadeAmt2;
        // reverse direction at the end of fade.
        if (brightness1 <= 20 || brightness1 >= 250)
          {
            fadeAmt1 = -fadeAmt1;
          }
        if (brightness2 <= 20 || brightness2 >= 250)
          {
            fadeAmt2 = -fadeAmt2;
          }
        // wait before changing the brightness
        delay( potValue1 / 10 );
    } // terminate else at start Fader section.
   

    } // terminate else at start Reverse Night Rider section (button4).
    } // terminate else at start Light Meter section (button1).
    } // terminate else at start NightRider section (button3).
    } // terminate else at start Dimmed Lights section (buttons 1&4).
 
} // end of loop

No comments:

Post a Comment