0
Offline
Newbie
Karma: 0
Posts: 12
Arduino rocks
|
 |
« on: October 03, 2008, 01:52:07 am » |
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!! #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
Full Member
Karma: 0
Posts: 193
Ard at work
|
 |
« Reply #1 on: October 03, 2008, 03:23:39 am » |
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
Newbie
Karma: 0
Posts: 12
Arduino rocks
|
 |
« Reply #2 on: October 03, 2008, 04:04:45 am » |
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
Faraday Member
Karma: 6
Posts: 6226
Have fun!
|
 |
« Reply #3 on: October 03, 2008, 04:13:47 am » |
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
Newbie
Karma: 0
Posts: 12
Arduino rocks
|
 |
« Reply #4 on: October 03, 2008, 08:01:19 am » |
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. 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
Faraday Member
Karma: 6
Posts: 6226
Have fun!
|
 |
« Reply #5 on: October 03, 2008, 08:38:30 am » |
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! 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
Newbie
Karma: 0
Posts: 12
Arduino rocks
|
 |
« Reply #6 on: October 03, 2008, 09:01:34 am » |
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
Newbie
Karma: 0
Posts: 12
Arduino rocks
|
 |
« Reply #7 on: October 03, 2008, 07:32:37 pm » |
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!! 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
Faraday Member
Karma: 6
Posts: 6226
Have fun!
|
 |
« Reply #8 on: October 03, 2008, 11:14:53 pm » |
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
Newbie
Karma: 0
Posts: 12
Arduino rocks
|
 |
« Reply #9 on: October 04, 2008, 07:28:52 am » |
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
Faraday Member
Karma: 6
Posts: 6226
Have fun!
|
 |
« Reply #10 on: October 04, 2008, 07:58:57 am » |
The reference page for millis is here: http://www.arduino.cc/en/Reference/MillisAnd 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/BlinkWithoutDelayTry 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
Newbie
Karma: 0
Posts: 12
Arduino rocks
|
 |
« Reply #11 on: October 04, 2008, 11:26:34 pm » |
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? 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
God Member
Karma: 3
Posts: 992
Arduino rocks
|
 |
« Reply #12 on: October 05, 2008, 12:05:47 am » |
Eclipse, I believe your problem stems from this little snippet of 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
Newbie
Karma: 0
Posts: 12
Arduino rocks
|
 |
« Reply #13 on: October 05, 2008, 12:56:45 am » |
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
Full Member
Karma: 0
Posts: 193
Ard at work
|
 |
« Reply #14 on: October 05, 2008, 01:24:33 am » |
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! 
|
|
|
|
« Last Edit: October 05, 2008, 01:27:54 am by Syvwlch »
|
Logged
|
---------- Mathieu
|
|
|
|
|