Pages: [1] 2   Go Down
Author Topic: Color change timer  (Read 1360 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, all

I am new to C and new to the arduino.
I basically don't have any background of C and electronics....

I'm currently making a color change timer by using tri-color (RGB) LED.
My initial idea is that I just want to change the color from green, blue to red within 10 seconds, but I don't want to use "delay".
I used a light sensor(Photocell) as a switch. I also used "MsTimer2.h" in the sketch.

I'll show my sketch below. It doesn't work properly, because of my lack of programming skill... Tri-color LED flashes with "purple" and "green" with this sketch. I don't know why...
Please help me!!

Here is my sketch. Please modify it.-----
If I can't complete my idea with this sketch, please give me any idea.
Thanks heaps!!

Code:
#include <MsTimer2.h>

int ledPinG=10; //Green LED
int ledPinB=11; //BLUE LED
int ledPinR=12; //RED LED
int switchPin=2;  //Light sensor
int val;// Switch connected to digital pin 2


void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  pinMode(switchPin, INPUT);  // Light sensor as a switch
  pinMode(ledPinG,OUTPUT);  // sets the digital pin as input to read switch
  pinMode(ledPinB,OUTPUT);  // sets the digital pin as input to read switch
  pinMode(ledPinR,OUTPUT);  // sets the digital pin as input to read switch

  MsTimer2::set(1000, flash); // 1000ms period
  MsTimer2::start();
}
void flash() {
static boolean output = HIGH;
   if (digitalRead(switchPin) ==LOW) //if the light sensor is uncovered
   {
      digitalWrite(ledPinB, output); //blink Blue LED
      output = !output;
      digitalWrite(ledPinG, output);  //blink Greene LED
      output = !output;
      digitalWrite(ledPinR, output);  //blink Red LED
      output = !output;

   }
}

void loop() {
    val = digitalRead(switchPin);   // read input value and store it in val
    if (val == HIGH) {              // if the light sensor is covered
    digitalWrite(ledPinG, LOW);    // turn LED off
    digitalWrite(ledPinB, LOW);    // turn LED off
    digitalWrite(ledPinR, LOW);    // turn LED off
  }

}
« Last Edit: October 03, 2008, 01:56:31 am by eclipsemints » Logged

New Jersey
Offline Offline
Full Member
***
Karma: 0
Posts: 193
Ard at work
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
     digitalWrite(ledPinB, output); //blink Blue LED
      output = !output;
      digitalWrite(ledPinG, output);  //blink Greene LED
      output = !output;
      digitalWrite(ledPinR, output);  //blink Red LED
      output = !output;

If you enter that sequence with output HIGH then blue is high, green is low and red is high and you exit with output LOW.

If you enter it with output LOW (e.g. looping around a second time), then blue is low, green is high and red is low, and you exit with output HIGH.

In other words, you always have either green on alone, or blue and red on together: green and purple.

If you want to cycle thru three states (blue, red and green) you need a state variable (e.g. output) that can hold three values, so not a boolean. For flexibility, you might want three booleans, one per LED.
Logged

----------
Mathieu

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Mathieu!
But, I still can't get it...

If it possible, could someone tell me how I can change the sketch?
(what variable should I add & which part shuould I change?)
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I wonder if you are unnecessarily making things difficult for yourself. Why not try it using delay instead of the timer. That way you can sequence through each of the colors you want. Once you have that code running it will be easier to see how you can modify it for use with a timer if you really need to do that.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for your suggention!

I tried color timer setting with "delay" function, but I can't turn off the "color changing" immediately during the loop . It always stops after the RED LED blink.
When I cover the light sensor, I want to turn off it immediately.
How should I change the sketch?

Here is the sketch.
Code:
int ledPinG=10; //Green LED
int ledPinB=11; //BLUE LED
int ledPinR=12; //RED LED
int switchPin=2;  //Light sensor
int val;// Switch connected to digital pin 2

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  pinMode(switchPin,INPUT);  // Light sensor as a switch
  pinMode(ledPinG,OUTPUT);  // sets the digital pin as input to read switch
  pinMode(ledPinB,OUTPUT);  // sets the digital pin as input to read switch
  pinMode(ledPinR,OUTPUT);  // sets the digital pin as input to read switch
}

void loop() {
     val = digitalRead(switchPin);   // read input value and store it in val
      if (val == LOW) {              // the light sensor is uncovered by a hand
      digitalWrite(ledPinG, HIGH);  //blink Greene LED
      digitalWrite(ledPinB, HIGH); //blink Blue LED
      digitalWrite(ledPinR, HIGH);  //blink Red LED
      delay(2000);
      digitalWrite(ledPinG, HIGH);  //blink Greene LED
      digitalWrite(ledPinB, LOW); //
      digitalWrite(ledPinR, LOW);  /
      delay(2000);
      digitalWrite(ledPinG, HIGH);  //blink Greene LED
      digitalWrite(ledPinB, HIGH); //blink Blue LED
      digitalWrite(ledPinR, LOW);  //
      delay(2000);
      digitalWrite(ledPinG, LOW);  //
      digitalWrite(ledPinB, HIGH); //blink Blue LED
      digitalWrite(ledPinR, LOW);  //
      delay(2000);
      digitalWrite(ledPinG, LOW);  //
      digitalWrite(ledPinB, HIGH); //blink Blue LED
      digitalWrite(ledPinR, HIGH);  //blink Red LED
      delay(2000);
      digitalWrite(ledPinG, LOW);  /
      digitalWrite(ledPinB, LOW); //
      digitalWrite(ledPinR, HIGH);  //blink Red LED
      delay(2000);
      }
    
    val = digitalRead(switchPin);   // read input value and store it in val
    if (val == HIGH) {              // if the light sensor is covered by a hand
    digitalWrite(ledPinG, LOW);    // turn LED off
    digitalWrite(ledPinB, LOW);    // turn LED off
    digitalWrite(ledPinR, LOW);    // turn LED off
  }
}
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This may give you some ideas of how to proceed. Its not tested so may need some work but I hope points you in the right direction. After you get it going, you can improve it by using an array to define your colors and looping through the array elements in for loop. This would let you replace those repeated checks for sensor state with a single check at the top of the loop.

Have fun!

Code:
int ledPinG=10; //Green LED
int ledPinB=11; //BLUE LED
int ledPinR=12; //RED LED
int switchPin=2;  //Light sensor
int val;// Switch connected to digital pin 2

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  pinMode(switchPin,INPUT);  // Light sensor as a switch
  pinMode(ledPinG,OUTPUT);  // sets the digital pin as input to read switch
  pinMode(ledPinB,OUTPUT);  // sets the digital pin as input to read switch
  pinMode(ledPinR,OUTPUT);  // sets the digital pin as input to read switch
}

void loop() {
  if( digitalRead(switchPin) == LOW)
    setColor(1,1,1,2000);        
  if( digitalRead(switchPin) == LOW)
    setColor(0,1,0,2000);  
  if( digitalRead(switchPin) == LOW)        
    // do your other colors ....


  if( digitalRead(switchPin) == HIGH)
     setColor(0,0,0,0);  // turn LEDs off
}


void setColor(int R, int G, int B, int delayMs){
  // set the LED colors and delay for the given number of milliseconds
  // but return if sensor is covered
  digitalWrite(ledPinG, R);
  digitalWrite(ledPinB, G);
  digitalWrite(ledPinR, B);
  while(delayMs--){
    // this loop checks the sensor every millisecond
    delay(1);
    if( digitalRead(switchPin) == HIGH)
      return; // exit the while loop if sensor is covered
  }  
}
« Last Edit: October 03, 2008, 08:39:07 am by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for your quick reply, mem!!
It works perfectly!!

I'll try to add more functions and develop this color timer.
Thanks a lot!!
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, all

I added some codes to create "10 seconds color timer", below.
This timer changes its color every 2 seconds.
sec.
0~1: white
2~3: green
4~5: light blue
6~7: blue
8~9: purple
10:   red

Now, I want to add another function that
"when timer is over 10 seconds, it blinks quickly with red color till the light sensor is covered by a hand".
Is there any way to do that? Please, help me!!
Thanks!!

Code:
int ledPinG=10; //Green LED
int ledPinB=11; //BLUE LED
int ledPinR=12; //RED LED
int switchPin=2;  //Light sensor
int val;// Switch connected to digital pin 2

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  pinMode(switchPin,INPUT);  // Light sensor as a switch
  pinMode(ledPinG,OUTPUT);  // sets the digital pin as input to read switch
  pinMode(ledPinB,OUTPUT);  // sets the digital pin as input to read switch
  pinMode(ledPinR,OUTPUT);  // sets the digital pin as input to read switch
}

void loop() {
  if( digitalRead(switchPin) == LOW)
    setColor(1,1,1,2000);
  if( digitalRead(switchPin) == LOW)
    setColor(1,0,0,2000);    
  if( digitalRead(switchPin) == LOW)
    setColor(1,1,0,2000);  
  if( digitalRead(switchPin) == LOW)
    setColor(0,1,0,2000);
  if( digitalRead(switchPin) == LOW)
    setColor(0,1,1,2000);    
  if( digitalRead(switchPin) == LOW)
    setColor(0,0,1,2000);    
    // do your other colors ....
    
  if( digitalRead(switchPin) == HIGH)
     setColor(0,0,0,0);  // turn LEDs off
}

void setColor(int R, int G, int B, int delayMs){
  // set the LED colors and delay for the given number of milliseconds
  // but return if sensor is covered
  digitalWrite(ledPinG, R);
  digitalWrite(ledPinB, G);
  digitalWrite(ledPinR, B);
  while(delayMs--){
    // this loop checks the sensor every millisecond
    delay(1);
    if( digitalRead(switchPin) == HIGH)
      return; // exit the while loop if sensor is covered
  }
}
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There are many ways you can do that. Why not add some code in loop to keep track of time and check if more then ten seconds have elapsed.

You can use the millis function to get the time (in milliseconds) since the sketch started and if you save the value in a variable each time the timer is restarted you can calculate the elapsed time  (elapsed time is the current time minus the start time).

Another way. Because the time for each color change is hard coded in your sketch, you would know its time to flash after the color goes to red (i.e. after ten seconds). For this to work you need to restart the color sequence from the first color when the sensor is covered.
« Last Edit: October 03, 2008, 11:18:54 pm by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I checked about :Millis" function.
I'm a Newbie, so I did't understand how I can use it in my sketch :'(
Should I make "void redBlink..." or something??
Can I use "mills" directly into the loop?

Thank you for your help many times!!
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6250
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


The reference page for millis is here: http://www.arduino.cc/en/Reference/Millis

And there are a few tutorials with examples of how to use it to determine elapsed time, here is one: http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

Try either of  both of those examples and when you see how it works you can think about adding to your sketch.

Have fun
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for your information!

I added a function of RED LED blink after RGB color changing.
Firstly, I tried Red LED blink code separately and it was working.
However when I added this sketch into the color timer sketch,
it doesn't work.... Could you help me to modify this sketch?

Code:
int ledPinG=10; //Green LED
int ledPinB=11; //BLUE LED
int ledPinR=12; //RED LED
int switchPin=2;  //Light sensor
int val;// Switch connected to digital pin 2
int value = LOW;                // previous value of the LED
long previousMillis = 0;        // will store last time LED was updated
long interval = 250;           // interval at which to blink (milliseconds)


void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  pinMode(switchPin,INPUT);  // Light sensor as a switch
  pinMode(ledPinG,OUTPUT);  // sets the digital pin as input to read switch
  pinMode(ledPinB,OUTPUT);  // sets the digital pin as input to read switch
  pinMode(ledPinR,OUTPUT);  // sets the digital pin as input to read switch
}

void loop() { // G, B, R color change
  if( digitalRead(switchPin) == LOW) // light blue
    setColor(1,1,0,2000);
  if( digitalRead(switchPin) == LOW) // blue
    setColor(0,1,0,2000);    
  if( digitalRead(switchPin) == LOW) //green
    setColor(1,0,0,2000);  
  if( digitalRead(switchPin) == LOW) //yellow
    setColor(1,0,1,2000);
  if( digitalRead(switchPin) == LOW) //purple
    setColor(0,1,1,2000);    
  if( digitalRead(switchPin) == LOW) //red
    setColor(0,0,1,2000);    
  // add more colors--------------
  
  // Red LED blinks
   if ( (millis() - previousMillis > interval) ) {
         previousMillis = millis();                         // remember the last time - blinked the LED
         // if the LED is off turn it on and vice-versa.
         if (value == LOW)
            value = HIGH;
         else
            value = LOW;
         digitalWrite(ledPinR, value);
   }
  
   // turn LEDs off
   if( digitalRead(switchPin) == HIGH)
   setColor(0,0,0,0);

}

void setColor(int R, int G, int B, int delayMs){
  // set the LED colors and delay for the given number of milliseconds
  // but return if sensor is covered
  digitalWrite(ledPinG, R);
  digitalWrite(ledPinB, G);
  digitalWrite(ledPinR, B);
  while(delayMs--){
    // this loop checks the sensor every millisecond
    delay(1);
    if(digitalRead(switchPin) == HIGH)
      return; // exit the while loop if sensor is covered  
        }
}

Logged

Austin, TX USA
Offline Offline
God Member
*****
Karma: 4
Posts: 997
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Eclipse,

I believe your problem stems from this little snippet of code:

Code:
 if ( (millis() - previousMillis > interval) ) {
         previousMillis = millis();                         // remember the last time - blinked the LED
         // if the LED is off turn it on and vice-versa.
         if (value == LOW)
            value = HIGH;
         else
            value = LOW;
         digitalWrite(ledPinR, value);
   }
  
   // turn LEDs off
   if( digitalRead(switchPin) == HIGH)
   setColor(0,0,0,0);

In the first {} clause, you correctly flip the value of the red LED every 250ms.  However in the very next line, you turn ALL the LEDs off, per the comment.  If you turn an LED on and immediately turn it off, you won't be able to see it.

Mikal
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for your feedback, mikalhart.

I tried to use "millis" function, but I couldn't manage "RGB color changing" part with this "RED LED blinks" part in my sketch...
Sorry, I'm new to programming...  If it possible, could someone modify it?
Thanks so much!
Logged

New Jersey
Offline Offline
Full Member
***
Karma: 0
Posts: 193
Ard at work
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Eclipsemints,

When you tried the red blink code by itself, it was the only thing in the main loop of the sketch... that is, inside void loop(). Anything inside void loop() will repeat forever, so in that case, the red link blinked.

When you moved it into your original code, it no longer repeats, because only the entire void loop() repeats. So you flash the various leds, toggle the red led once, and then immediately, either turn everything off if switchpin is high, and restart the loop or go straight to restarting the loop and if switchpin is low, start with cyan (light blue) in which the red led is off.

What you need to do is put the red blink code into its own loop, for example a while loop, which will continue looping as long as (i.e. while) switchpin is low.

Here is the reference for the while loop, see if you can change your code to put the red blink inside one, with the stay-in-loop-while-this-is-true condition (switchpin == low).

Good luck!  smiley-wink
« Last Edit: October 05, 2008, 01:27:54 am by Syvwlch » Logged

----------
Mathieu

Pages: [1] 2   Go Up
Jump to: