**Forward:**This instructable was roiginally posted at https://www.instructables.com/id/How-to-make-LED-Fader-using-Digispark/

My students and I developed it into this exemplar, for wich they received a very good mark.

Viewing the following video may leave you with a sense of too much too fast. Please continue to read this Instructable which documents my students' Tanner and Amanda's culminating math project. The concept of the project was to get my students to extend obtuse angles to beyond simple trigonometry, and solving triangles. Instead I wanted them to enjoy the experience of some authentic learning as they explored an application of the sine function that isn't found in their textbook.

## Step 1: Which Processor Board to Use?

The Digispark

The Digispark is one of the smallest and cheapest USB Arduino processors available today. It is bassed on the ATTiny85 processor. The Digispark is very easy to program using a version of the Arduino IDE tailored to the ATTiny 85 processor. The most significant difference from boards such as the Arduino Uno is pins assignments. The Digispark only has 6 data pins and three power pins as opposed to the Uno's 32. You can learn more about the Digispark at http://digistump.com. In this project we use pins 0, 1, and 4 as well as the GND pin.

The Digispark is one of the smallest and cheapest USB Arduino processors available today. It is bassed on the ATTiny85 processor. The Digispark is very easy to program using a version of the Arduino IDE tailored to the ATTiny 85 processor. The most significant difference from boards such as the Arduino Uno is pins assignments. The Digispark only has 6 data pins and three power pins as opposed to the Uno's 32. You can learn more about the Digispark at http://digistump.com. In this project we use pins 0, 1, and 4 as well as the GND pin.

## Step 2: Pulse Width Modulation

__What is PWM?__

Processor boards such as the Digispark can modulate the power sent to an LED giving the effect of fading while still providing a digital on or off signal. The process is known as Pulse Width Modulation or PWM. PWM switches on for a percentage of a duty cycle and off for the remainder. In a 12 volt circuit, the effect of 6 volts can be achieved if the power is switched on and off rapidly 50% of the time. This avoids heat issues that would be associated with using a rheostat or potentiometer. PMW values extend from 0 to 255, representing 0% to 100%.duty cycle. A PWM value of 64 corresponds to a 25% (0.25*255) duty cycle or 1/4 power. Similarly a PWM value of 191 corresponds to a duty cycle of 75% (0.75*255) or 3/4 power.

Now that we understand what PWM is, how do we generate a series of values that will give a subtle ebbing of LED intensity.

## Step 3: The Sine Wave Function

**Three Waves are Better than One**The basic sine wave function generates numbers from -1 to 1. How do we modify the basic function for use as a PWM number generator?

general form:

y = a*sin(b*x + c) + d

Where

a changes the amplituded (how tall the wave is)

b changes the period (how long the wave is)

c causes a phase shift along the x axis

d raises or lowers the wave along the y axis

b changes the period (how long the wave is)

c causes a phase shift along the x axis

d raises or lowers the wave along the y axis

The sine wave produces numbers between -1 and +1. This causes an issue because PWM values can not be negative. The first change we need to make is to add 1 by substituting 1 for d in the formula. y=a*sin(b*x+c)+1 will give us values between 0 and 2.

Next we needed to increase the amplitude to produce our maximum PWM value of 255. As it stands the max value is 2. Therefore 255/2= 127.5. The PWM needs to be an integer so we settle on 127 which will gives us a max of 254. Now the formula looks like this:

y=127*(sin(b*x+c)+1) note the additional brackets.

We have three LEDs which we want to interact together to give subtle shifts in additive colour values. Therefore we had to use a phase shift for each colour. This where it gets tricky for us. Computers use radians not degrees. Therefore the phase shift had to be expressed in radians. It turns out the conversion is simple. 90° = 90/180*PI radians or 1/2*PI radians. A 270° phase shift would require 3/2*PI radians. If we do not alter the period we now have three functions, one for each colour of our LED

Next we needed to increase the amplitude to produce our maximum PWM value of 255. As it stands the max value is 2. Therefore 255/2= 127.5. The PWM needs to be an integer so we settle on 127 which will gives us a max of 254. Now the formula looks like this:

y=127*(sin(b*x+c)+1) note the additional brackets.

We have three LEDs which we want to interact together to give subtle shifts in additive colour values. Therefore we had to use a phase shift for each colour. This where it gets tricky for us. Computers use radians not degrees. Therefore the phase shift had to be expressed in radians. It turns out the conversion is simple. 90° = 90/180*PI radians or 1/2*PI radians. A 270° phase shift would require 3/2*PI radians. If we do not alter the period we now have three functions, one for each colour of our LED

red=127*(sin(x)+1)

green=127*(sin(x+1/2*PI)+1)

blue=127*(sin(x+3/2*PI)+1)

green=127*(sin(x+1/2*PI)+1)

blue=127*(sin(x+3/2*PI)+1)

## Step 4: Arduino Program

Arduinos are simple to program and the IDE is free under the CC licence. The Digispark uses a modified version fo the Arduino IDE which includeds special libraries to reflect the change in pin assignments etc. The Digispark Arduino IDE is available at http://digistump.com/wiki/digispark/tutorials/basics and http://digistump.com/wiki/digispark

ARDUINO BOARD IDE 1.0.3 CODE

//Declare all variables

int LED1; // these variables will be used to hold the led PWM values

int LED2;

int LED3;

int p0=0; /* these variables will assign a variable to receive PWM values and pass them to their respective pins*/

int p1=1;

int p4=4;

float x;

/*this a variable that will receive the angle value from variable i. This value is converted to radians in the sine function and will be used to generate the PWM values */

float r; // these variables will receive the PWM values calculated by the three sine functions

float g;

float b;

// the setup routine runs once when you press reset;

void setup() {

// initialize the digitals pin as an output.

pinMode(p0, OUTPUT); //sets up pin 0 for pwm

pinMode(p1, OUTPUT); //sets up pin 1 for pwm

pinMode(p4, OUTPUT); //sets up pin 4 for pwm

/*Run a diagnostic test that will verify that each colour of LED is working.

Turns on the LEDs consecutively with a delay of one second between each*/

digitalWrite(p0, HIGH);

delay(1000);

digitalWrite(p1, HIGH);

delay(1000);

digitalWrite(p4, HIGH);

delay(1000);

//Turn off LEDs one after the other with a one second deleay between each

digitalWrite(p0, LOW);

delay(1000);

digitalWrite(p1, LOW);

delay(1000);

digitalWrite(p4, LOW);

delay(1000);

}

// the loop routine runs over and over again forever:

void loop() {

/*The for loop generates a value for a variable i which corresponds to 0 to 360 degrees. I is increased by 1 with each iteration. It is later converted to radians within the loop. Once i reaches 360 it resets back to 0. This establishes the periodic behaviour of the sine fun functions*/

for (int i=0; i<360; i++)

{

//convert i into a floating point variable that can be used with PI

x=float(i);

/* to calculate r,g,b the sine function is modified to increase amplitute (127*) to create a phase shift (x+1/2*PI) and (x+3/2*PI) finally the sine wave is raised to illiminate negative values below zero by adding 1*/

r=127*(sin(x/180*PI)+1);

g=127*(sin(x/180*PI+3/2*PI)+1);

b=127*(sin(x/180*PI+0.5*PI)+1);

//convert flaot r,g,b to integers that can be assigned to LED PWM numbers

LED1= int(r);

LED2= int(g);

LED3= int(b);

//write LED levels to p0, p1, p4 (ASSIGN PWM values to LEDs)

analogWrite (p0,LED1);

analogWrite (p1,LED2);

analogWrite (p4,LED3);

//wait for 1/100 of a second

delay(100);

In this project a number from 0-255 is used to represent 0%-100% duty cycle (brightness), sine function is used to generate it. Digispark uses sine function to generate the PWM (pulse width modulation). We convert the radians to degree's for the red, green, blue cycles. This is used to change the language for the computer to understand. One small difference from regular Arduino boards and the Digispark is that the program compiler prompts you to attach the Digispark when it is ready to upload. If you leave it connected you will get a compiler error.

ARDUINO BOARD IDE 1.0.3 CODE

//Declare all variables

int LED1; // these variables will be used to hold the led PWM values

int LED2;

int LED3;

int p0=0; /* these variables will assign a variable to receive PWM values and pass them to their respective pins*/

int p1=1;

int p4=4;

float x;

/*this a variable that will receive the angle value from variable i. This value is converted to radians in the sine function and will be used to generate the PWM values */

float r; // these variables will receive the PWM values calculated by the three sine functions

float g;

float b;

// the setup routine runs once when you press reset;

void setup() {

// initialize the digitals pin as an output.

pinMode(p0, OUTPUT); //sets up pin 0 for pwm

pinMode(p1, OUTPUT); //sets up pin 1 for pwm

pinMode(p4, OUTPUT); //sets up pin 4 for pwm

/*Run a diagnostic test that will verify that each colour of LED is working.

Turns on the LEDs consecutively with a delay of one second between each*/

digitalWrite(p0, HIGH);

delay(1000);

digitalWrite(p1, HIGH);

delay(1000);

digitalWrite(p4, HIGH);

delay(1000);

//Turn off LEDs one after the other with a one second deleay between each

digitalWrite(p0, LOW);

delay(1000);

digitalWrite(p1, LOW);

delay(1000);

digitalWrite(p4, LOW);

delay(1000);

}

// the loop routine runs over and over again forever:

void loop() {

/*The for loop generates a value for a variable i which corresponds to 0 to 360 degrees. I is increased by 1 with each iteration. It is later converted to radians within the loop. Once i reaches 360 it resets back to 0. This establishes the periodic behaviour of the sine fun functions*/

for (int i=0; i<360; i++)

{

//convert i into a floating point variable that can be used with PI

x=float(i);

/* to calculate r,g,b the sine function is modified to increase amplitute (127*) to create a phase shift (x+1/2*PI) and (x+3/2*PI) finally the sine wave is raised to illiminate negative values below zero by adding 1*/

r=127*(sin(x/180*PI)+1);

g=127*(sin(x/180*PI+3/2*PI)+1);

b=127*(sin(x/180*PI+0.5*PI)+1);

//convert flaot r,g,b to integers that can be assigned to LED PWM numbers

LED1= int(r);

LED2= int(g);

LED3= int(b);

//write LED levels to p0, p1, p4 (ASSIGN PWM values to LEDs)

analogWrite (p0,LED1);

analogWrite (p1,LED2);

analogWrite (p4,LED3);

//wait for 1/100 of a second

delay(100);

}

}In this project a number from 0-255 is used to represent 0%-100% duty cycle (brightness), sine function is used to generate it. Digispark uses sine function to generate the PWM (pulse width modulation). We convert the radians to degree's for the red, green, blue cycles. This is used to change the language for the computer to understand. One small difference from regular Arduino boards and the Digispark is that the program compiler prompts you to attach the Digispark when it is ready to upload. If you leave it connected you will get a compiler error.

## Step 5: The Bits

MATERIALS REQUIRED

(In order)

Optional one stop shooping instead of buying components separately is possible by purchasing the Digispark Starter kit from dgistump.com This kit has everything you need.

(In order)

Item | Supplier | Cat # | Quantity |

220 ohm resistor | digikey.com | 220QBK-ND | 3 |

RGB LED | digikey.com | 754-1492-ND | 1 |

Female header 3 pin | digikey.com | S7001-ND | 1 |

Female header 6 pin | digikey.com | S7004-ND | 1 |

Rectangular Connectors - Headers, Male Pins | digikey.com | S1011E-06-ND | 1 |

Rectangular Connectors - Headers, Male Pins | digikey.com | S1011E-03-ND | 1 |

PC DUAL-MINI BOARD | thesource.ca | 2760148 | 1 |

Digispark development board | digistump.com | n/a | 1 |

Optional one stop shooping instead of buying components separately is possible by purchasing the Digispark Starter kit from dgistump.com This kit has everything you need.

## Step 6: Building the Digispark Fader

The process of building the Fader was quite simple but required a steady hand when soldering.

- Cut out an 8x9 hole square hole from the perf board
- Solder female header pins to DigiSpark
- Solder the bits ( male header pins, resistors, RGB LED(longest leg is your ground)
- The resistors are soldered to the perf board in the PWM pins 1 and 4
- Then solder the resistors to the LED legs
- Solder the longest leg of the LED (ground) to the ground pin, cover the wire with insulation to avoid shorting out.
- Then use the Arduino 1.0.3 program to write your code (provided above) to program your PWM to your chip
- Plug in and play and your ready to go with your LED fader

## Step 7: Thanks for Checking Us Out!

**Extensions:**A possible extension for this project would be to include a light dependent resistor and code that would turn on the Fader only if the room was dark enough. This would require more hardware research and mathematical modeling. The extra hardware would be an LDR a 10Kohm resistor

While conferencing with the students it became evident that this project solidified their knowledge of the behaviour of trig ratios of obtuse angles. They were able to synthesize the knowledge and apply to a completely new circumstance. They were also able to demonstrate a great understanding and confidence when quizzed about simple trig ratios, sine law and cosine law. They also were able to relate trig concepts back to the first unit which dealt with mathematical modelling.

Here is the fader in action with a diffuser so you can see the colour shifts more easily.

**Credits:** Digispark:digistump.com

Arduino: Arduino.cc

Digikey: digikey.com

The Source: thesource.com

Animoto produced using Animoto.com account

Third party credit for music in video to Cool Affair Black and Brown

The course is MAP4C taught at the Renfrew Adult H.S, Renfrew County DSB, Ontario, Canada

Teacher: Marc Fournier

Students: Tanner Roderick and Amanda Reckzin

Date of completion June 26, 2013.

Feel free to post a comment. Email responses or inquiries should be directed to fournierm@rcdsb.on.ca.
Arduino: Arduino.cc

Digikey: digikey.com

The Source: thesource.com

Animoto produced using Animoto.com account

Third party credit for music in video to Cool Affair Black and Brown

The course is MAP4C taught at the Renfrew Adult H.S, Renfrew County DSB, Ontario, Canada

Teacher: Marc Fournier

Students: Tanner Roderick and Amanda Reckzin

Date of completion June 26, 2013.

<p>Excellent, very well explained and documented. This project can be implemented in so many places around the world, because digispark clones are very low cost Around USD $1.20 ( <a href="http://s.click.aliexpress.com/e/r3FQzBU" rel="nofollow">http://s.click.aliexpress.com/e/r3FQzBU</a> ) and are available worldwide!</p>

If you want the sine curves to be more evenly aligned with eachother, you can change the equations to:<br><br>r=127*(sin(x/180*PI)+1);<br>g=127*(sin(x/180*PI+2/3*PI)+1);<br>b=127*(sin(x/180*PI+4/3*PI)+1);<br><br>This way, the gaps between the max value peaks from each curve are all the same length (of time) apart.<br><br>(You can see it for yourself if you graph the three equations in a program, such as Desmos, or even just a graphing calculator)

Thanks for the input. I've used this project with other students using the attiny85 and one of the problems I asked them to solve was this issue. You'll glad to know they came up with the solution you have. The next group will be looking at manipulating PWM with a view to determining the range of PWM that actually produce a visible modulations of intensity.

I made it with uno.<br>thanks a lot. I like the math used very much<br>

You seems to be pretty cool with this Digispark. Can you maybe help? I need 4/5 LEDs to flash when a momentary switch is pushed and to stop when pushing again. The seitch is already connected and is working instead of a button to a joystick (its turning on pit speed limiter in a Racing game) im Then thinking of digispark Can be programmed to flash those LEDs when button is pressed? Thanks in advance :)

<p>Use an analog pin to read voltage from the switch. Use this ti trigger a loop in the sketch that will blink your LEDs hooked into any of the other digital pins. If you want to use mor LEDs that you have digital pins, use a relay to switch a large number of LEDS on and off. </p><p>The on board power regulator is rated at 500mA 5V. Typical 5mm through hole LED has a forward voltage of 2V and draws 20mA, so you could hook up two LED per digital output safely at 100% duty cycle in parallel using 100ohm resistors.</p>

<p>Nice little project, I tried it out on my UNO, don't have an RGB led so used 3 led's red, green and blue, it works, unfortunately the red and blue dominate over the green, and that's despite choosing resistors to try and even things out.</p>

<p>Ttry changing the PWM values in the program so the red and blue peak at half power 127 (or less) instead of 255</p><p>change:</p><p>r=127*(sin(x/180*PI)+1);<br> g=127*(sin(x/180*PI+3/2*PI)+1);<br> b=127*(sin(x/180*PI+0.5*PI)+1);</p><p>to:</p><p>r=63*(sin(x/180*PI)+1);<br> g=127*(sin(x/180*PI+3/2*PI)+1);<br> b=63*(sin(x/180*PI+0.5*PI)+1);</p><p>This will reduce the amplitude of the sin curve which is used to set the PWM of the individual red and blue LEDS. by half. The numbers will take some fiddling since different colours of LEDs will saturate at differing voltages. You can fiddle with the values more cheaply and with less mess and re soldering than if you use resistors.</p>

<p>Of course, I didn't consider adjusting the multipliers, thanks for this.</p>

<p>I forgot to mention that final form should allow the PWM calculation for r and b need to cycle back down to 0. Since the amplitude has been halved the vertical offset also has to be reduced.</p><p>r=63*(sin(x/180*PI)+<strong>0.5</strong>);<br>g=127*(sin(x/180*PI+3/2*PI)+1);<br>b=63*(sin(x/180*PI+0.5*PI)+<strong>0.5</strong>);</p>

<p>Hi, you can try my digispark clone with onboard RGB led <a href="https://www.tindie.com/products/bobricius/picoduino/" rel="nofollow">https://www.tindie.com/products/bobricius/picoduino/</a></p>