ATtiny85 Mini RGB Mood Light!
Intro: ATtiny85 Mini RGB Mood Light!
I have seen RGB mood lights using Arduino, PIC, and larger AVR chips, but never one with the ATtiny85. That's why I decided to make one.
This mood light is super simple to make and all the parts can be purchased online for about $5.00 total (not including the Arduino used to program the chip).
This is a contest entry in the LED contest with Elemental LED and the Hurricane Lasers contest, so if you like it, vote!
EDIT: I have changed this instructable so that it is a NIGHT LED Mood Lamp. It now only lights up when the ambient light in the room is very low (at night with all the lights off). You do need an LDR and a 10K ohm resistor to add this part though. If you want it to not have this feature, just remove the LDR/10K resistor part and connect Analog Input 3 of the ATtiny (pin 2) straight to ground.
This mood light is super simple to make and all the parts can be purchased online for about $5.00 total (not including the Arduino used to program the chip).
This is a contest entry in the LED contest with Elemental LED and the Hurricane Lasers contest, so if you like it, vote!
EDIT: I have changed this instructable so that it is a NIGHT LED Mood Lamp. It now only lights up when the ambient light in the room is very low (at night with all the lights off). You do need an LDR and a 10K ohm resistor to add this part though. If you want it to not have this feature, just remove the LDR/10K resistor part and connect Analog Input 3 of the ATtiny (pin 2) straight to ground.
STEP 1: How Does It Work?
The ATtiny85 only has 2 PWM pins, so obviously you can't make all 3 colors of the RGB LED fade in and out smoothly, right? Wrong.
The way I got around this was by using software PWM. This means that I can fade in and out of all 3 colors using any of the pins on the ATtiny.
How software PWM works is by setting the pin HIGH and then LOW at different rates so that the LED looks like it's dimming. This is called Persistence of Vision or POV (for more on POV, see my instructable here). The LED blinks so rapidly that the human eye can't detect that it is flashing at all, and it sees instead that the LED appears to be dimming.
The way I got around this was by using software PWM. This means that I can fade in and out of all 3 colors using any of the pins on the ATtiny.
How software PWM works is by setting the pin HIGH and then LOW at different rates so that the LED looks like it's dimming. This is called Persistence of Vision or POV (for more on POV, see my instructable here). The LED blinks so rapidly that the human eye can't detect that it is flashing at all, and it sees instead that the LED appears to be dimming.
STEP 2: Parts List
You will need:
1x Common cathode RGB LED
3x 220 ohm resistors
1x ATtiny85 Microcontroller
For the Light sensing part:
1x LDR (light dependent resistor)
1x 10K ohm resistor
And to program the ATtiny:
1x Arduino Uno or equivalent
1x A to B USB cable for Arduino
1x Common cathode RGB LED
3x 220 ohm resistors
1x ATtiny85 Microcontroller
For the Light sensing part:
1x LDR (light dependent resistor)
1x 10K ohm resistor
And to program the ATtiny:
1x Arduino Uno or equivalent
1x A to B USB cable for Arduino
STEP 3: Program the Chip
Go here and it will show you how to connect the ATtiny85 to the Arduino and program it. Once you are ready to upload the code to the ATtiny85, paste it into the Arduino IDE and click upload.
//ATtiny85 RGB color fading Mood Light NOW WITH LIGHT SENSING CAPABILITIES!!!
const int redPin = 2;
const int grnPin = 1;
const int bluPin = 0;
const int sensor = 3;
void setup()
{
pinMode(redPin, OUTPUT);
pinMode(grnPin, OUTPUT);
pinMode(bluPin, OUTPUT);
pinMode(sensor, INPUT);
}
void loop() {
if (analogRead(sensor) <= 200)
{
redtoyellow();
yellowtogreen();
greentocyan();
cyantoblue();
bluetomagenta();
magentatored();
}
else if (analogRead(sensor) >= 201)
{
digitalWrite(redPin, LOW);
digitalWrite(grnPin, LOW);
digitalWrite(bluPin, LOW);
}
}
void redtoyellow()
{
digitalWrite(redPin, HIGH);
digitalWrite(bluPin, LOW);
// fade up green
for(byte i=1; i<100; i++) {
byte on = i;
byte off = 100-on;
for( byte a=0; a<100; a++ ) {
digitalWrite(grnPin, HIGH);
delayMicroseconds(on);
digitalWrite(grnPin, LOW);
delayMicroseconds(off);
}
}
}
void yellowtogreen()
{
digitalWrite(grnPin, HIGH);
digitalWrite(bluPin, LOW);
// fade down red
for(byte i=1; i<100; i++) {
byte on = 100-i;
byte off = i;
for( byte a=0; a<100; a++ ) {
digitalWrite(redPin, HIGH);
delayMicroseconds(on);
digitalWrite(redPin, LOW);
delayMicroseconds(off);
}
}
}
void greentocyan()
{
digitalWrite(grnPin, HIGH);
digitalWrite(redPin, LOW);
// fade up blue
for(byte i=1; i<100; i++) {
byte on = i;
byte off = 100-on;
for( byte a=0; a<100; a++ ) {
digitalWrite(bluPin, HIGH);
delayMicroseconds(on);
digitalWrite(bluPin, LOW);
delayMicroseconds(off);
}
}
}
void cyantoblue()
{
digitalWrite(bluPin, HIGH);
digitalWrite(redPin, LOW);
// fade down green
for(byte i=1; i<100; i++) {
byte on = 100-i;
byte off = i;
for( byte a=0; a<100; a++ ) {
digitalWrite(grnPin, HIGH);
delayMicroseconds(on);
digitalWrite(grnPin, LOW);
delayMicroseconds(off);
}
}
}
void bluetomagenta()
{
digitalWrite(bluPin, HIGH);
digitalWrite(grnPin, LOW);
// fade up red
for(byte i=1; i<100; i++) {
byte on = i;
byte off = 100-on;
for( byte a=0; a<100; a++ ) {
digitalWrite(redPin, HIGH);
delayMicroseconds(on);
digitalWrite(redPin, LOW);
delayMicroseconds(off);
}
}
}
void magentatored()
{
digitalWrite(redPin, HIGH);
digitalWrite(grnPin, LOW);
// fade down blue
for(byte i=1; i<100; i++) {
byte on = 100-i;
byte off = i;
for( byte a=0; a<100; a++ ) {
digitalWrite(bluPin, HIGH);
delayMicroseconds(on);
digitalWrite(bluPin, LOW);
delayMicroseconds(off);
}
}
}
//ATtiny85 RGB color fading Mood Light NOW WITH LIGHT SENSING CAPABILITIES!!!
const int redPin = 2;
const int grnPin = 1;
const int bluPin = 0;
const int sensor = 3;
void setup()
{
pinMode(redPin, OUTPUT);
pinMode(grnPin, OUTPUT);
pinMode(bluPin, OUTPUT);
pinMode(sensor, INPUT);
}
void loop() {
if (analogRead(sensor) <= 200)
{
redtoyellow();
yellowtogreen();
greentocyan();
cyantoblue();
bluetomagenta();
magentatored();
}
else if (analogRead(sensor) >= 201)
{
digitalWrite(redPin, LOW);
digitalWrite(grnPin, LOW);
digitalWrite(bluPin, LOW);
}
}
void redtoyellow()
{
digitalWrite(redPin, HIGH);
digitalWrite(bluPin, LOW);
// fade up green
for(byte i=1; i<100; i++) {
byte on = i;
byte off = 100-on;
for( byte a=0; a<100; a++ ) {
digitalWrite(grnPin, HIGH);
delayMicroseconds(on);
digitalWrite(grnPin, LOW);
delayMicroseconds(off);
}
}
}
void yellowtogreen()
{
digitalWrite(grnPin, HIGH);
digitalWrite(bluPin, LOW);
// fade down red
for(byte i=1; i<100; i++) {
byte on = 100-i;
byte off = i;
for( byte a=0; a<100; a++ ) {
digitalWrite(redPin, HIGH);
delayMicroseconds(on);
digitalWrite(redPin, LOW);
delayMicroseconds(off);
}
}
}
void greentocyan()
{
digitalWrite(grnPin, HIGH);
digitalWrite(redPin, LOW);
// fade up blue
for(byte i=1; i<100; i++) {
byte on = i;
byte off = 100-on;
for( byte a=0; a<100; a++ ) {
digitalWrite(bluPin, HIGH);
delayMicroseconds(on);
digitalWrite(bluPin, LOW);
delayMicroseconds(off);
}
}
}
void cyantoblue()
{
digitalWrite(bluPin, HIGH);
digitalWrite(redPin, LOW);
// fade down green
for(byte i=1; i<100; i++) {
byte on = 100-i;
byte off = i;
for( byte a=0; a<100; a++ ) {
digitalWrite(grnPin, HIGH);
delayMicroseconds(on);
digitalWrite(grnPin, LOW);
delayMicroseconds(off);
}
}
}
void bluetomagenta()
{
digitalWrite(bluPin, HIGH);
digitalWrite(grnPin, LOW);
// fade up red
for(byte i=1; i<100; i++) {
byte on = i;
byte off = 100-on;
for( byte a=0; a<100; a++ ) {
digitalWrite(redPin, HIGH);
delayMicroseconds(on);
digitalWrite(redPin, LOW);
delayMicroseconds(off);
}
}
}
void magentatored()
{
digitalWrite(redPin, HIGH);
digitalWrite(grnPin, LOW);
// fade down blue
for(byte i=1; i<100; i++) {
byte on = 100-i;
byte off = i;
for( byte a=0; a<100; a++ ) {
digitalWrite(bluPin, HIGH);
delayMicroseconds(on);
digitalWrite(bluPin, LOW);
delayMicroseconds(off);
}
}
}
STEP 4: Connect It
Connect the ATtiny to the LEDs and 3V like shown in the schematic, and that's it!
If you want the circuit to not respond to light and be constantly on and fading, just remove the LDR and 10K resistor and connect Analog Input 3 (pin 2) straight to ground.
If you want the circuit to not respond to light and be constantly on and fading, just remove the LDR and 10K resistor and connect Analog Input 3 (pin 2) straight to ground.
STEP 5: You're Done!
Good Job! When you apply 3 volts it should start to fade through the different colors.
48 Comments
mousompal82 2 years ago
ddanon 5 years ago
I copy and paste the code however it still is not exactly working. I am not sure what I am doing wrong please explain thanks
samlf3rd 9 years ago
How can I make this without the sensor? I just want it to run constantly. Thank you!
blyamur 6 years ago
Hi, you can use this example:
//ATtiny85 RGB color fading Mood Light NOW WITH LIGHT SENSING CAPABILITIES!!!
const int redPin = 2;
const int grnPin = 1;
const int bluPin = 0;
long sensor;
void setup()
{
pinMode(redPin, OUTPUT);
pinMode(grnPin, OUTPUT);
pinMode(bluPin, OUTPUT);
sensor = random(10, 300);
}
void loop() {
if (analogRead(sensor) <= 200)
{
redtoyellow();
yellowtogreen();
greentocyan();
cyantoblue();
bluetomagenta();
magentatored();
}
else if (analogRead(sensor) >= 201)
{
digitalWrite(redPin, LOW);
digitalWrite(grnPin, LOW);
digitalWrite(bluPin, LOW);
}
}
void redtoyellow()
{
digitalWrite(redPin, HIGH);
digitalWrite(bluPin, LOW);
// fade up green
for(byte i=1; i<100; i++) {
byte on = i;
byte off = 100-on;
for( byte a=0; a<100; a++ ) {
digitalWrite(grnPin, HIGH);
delayMicroseconds(on);
digitalWrite(grnPin, LOW);
delayMicroseconds(off);
}
}
}
void yellowtogreen()
{
digitalWrite(grnPin, HIGH);
digitalWrite(bluPin, LOW);
// fade down red
for(byte i=1; i<100; i++) {
byte on = 100-i;
byte off = i;
for( byte a=0; a<100; a++ ) {
digitalWrite(redPin, HIGH);
delayMicroseconds(on);
digitalWrite(redPin, LOW);
delayMicroseconds(off);
}
}
}
void greentocyan()
{
digitalWrite(grnPin, HIGH);
digitalWrite(redPin, LOW);
// fade up blue
for(byte i=1; i<100; i++) {
byte on = i;
byte off = 100-on;
for( byte a=0; a<100; a++ ) {
digitalWrite(bluPin, HIGH);
delayMicroseconds(on);
digitalWrite(bluPin, LOW);
delayMicroseconds(off);
}
}
}
void cyantoblue()
{
digitalWrite(bluPin, HIGH);
digitalWrite(redPin, LOW);
// fade down green
for(byte i=1; i<100; i++) {
byte on = 100-i;
byte off = i;
for( byte a=0; a<100; a++ ) {
digitalWrite(grnPin, HIGH);
delayMicroseconds(on);
digitalWrite(grnPin, LOW);
delayMicroseconds(off);
}
}
}
void bluetomagenta()
{
digitalWrite(bluPin, HIGH);
digitalWrite(grnPin, LOW);
// fade up red
for(byte i=1; i<100; i++) {
byte on = i;
byte off = 100-on;
for( byte a=0; a<100; a++ ) {
digitalWrite(redPin, HIGH);
delayMicroseconds(on);
digitalWrite(redPin, LOW);
delayMicroseconds(off);
}
}
}
void magentatored()
{
digitalWrite(redPin, HIGH);
digitalWrite(grnPin, LOW);
// fade down blue
for(byte i=1; i<100; i++) {
byte on = 100-i;
byte off = i;
for( byte a=0; a<100; a++ ) {
digitalWrite(bluPin, HIGH);
delayMicroseconds(on);
digitalWrite(bluPin, LOW);
delayMicroseconds(off);
}
}
}
diy_bloke 9 years ago
you could take the IF...ELSE loop out of the program.
If you do not know how to do that, well you could replace the sensor by a wire bridge or leave it open, depending on how it is wird
In the program you see that if the value read from the sensor is greater or equal than 201, the lights shld go out.
As I presume the lights shld go out when it is light ( low resistance of LDR) and on when it is dark (high resistance of LDR), I guess just omitting the sensor would do the trick.
samlf3rd 9 years ago
diy_bloke 9 years ago
we all have to start learning at one point :-)
BrandonT7 9 years ago
Any ideas as to how I can slow down the rate at which the colors cycle? Love this project, by the way, you're awesome!
diy_bloke 9 years ago
OK, finally got around to build it and found the light changes extremely slow (on 8MHz). Which core are you using?
diy_bloke 9 years ago
found it. forgot to set the fuses for 8MHz
Hassan balaha 9 years ago
mikroskeem 10 years ago
diy_bloke 9 years ago
ide supports parallel programmer
mikroskeem 9 years ago
okay... i couldn't get it working :/
diy_bloke 9 years ago
I do not know why that is, the only thing I know is that the IDE supports a parallel programmer. If you cant get it to work you have to upload the hex file:
http://forum.arduino.cc/index.php?topic=114503.0
diy_bloke 9 years ago
Great article.
Though you are right on the software PWM, there is some discussion on wether it has 2 or 3 PWM outputs.
Supposedly it has 3, all addressable from inside the IDE
IC leg 6 (PB1),
IC leg 5 (PB0),
IC leg 3 (PB4),
Supposedly, strictly speaking IC leg 2 (D3/PB3) is also capable of PWM, but internally it shares the same timer used on leg 3.
I didnt try it myself, but that is what I have been reading. Some discussion going on here:
http://forum.arduino.cc/index.php?topic=134754.0
ironheartbj18 9 years ago
a special thanks to you https://www.youtube.com/watch?v=rupib_N7zqw
ironheartbj18 9 years ago
other tutorial great how to install attiny 0022 with library http://makezine.com/2011/10/10/how-to-shrinkify-your-arduino-projects/
I3L4ck5h33p 9 years ago
Which LDR was used for this?
kshowell 9 years ago
Nice Instructable. Thank you for the work. It was fun to build.