Archive for March, 2011
FFT Library for Arduino
60
I am planning to make a slightly more complex but fun project which is visualizing music with LED. There are couple of ways of doing it. VU meter is display amplitude of sound. Fancier way of visualizing music involve frequency analysis of music. Think of your old music component or music visualization of Winamp and etc. The frequency of signal can be analyzed by FFT. Fast Fourier transform (FFT) is rather a complex math which I don’t clearly understand. It is quite difficult to do with 8 bit microcontroller like Arduino.
I tried some FFT code for Arduino and found fixed point FFT from ELM Chan works best for me. The main problem with Chan’s code was written by Assembler which is difficult to make it as a Arduino library. Luckily, AMurchick from Arduino forum make it work as a Arduino Library. I modified code little bit and add Processing application (modified from boolscott’s) to visualize data. All credits should go to where it belong.
DownLoad FFT Library : http://code.google.com/p/neuroelec/downloads/list
Code : http://code.google.com/p/neuroelec/source/browse/#svn%2Ftrunk%2Fffft
Of course, I want to show you how well it works. Compare FFT results from Oscilloscope and Arduino.
Intrusion Detect Mood Lamp
0Here is a fourth fun project with High Power RGB LED Shield and Arduino.
Even though these projects used HP RGB Shield, they are more of general Arduino tutorials mostly focusing on sensor use.
This time I am using PIR motion detection sensor.
What you need
- Arduino (any version)
- High Power RGB LED shield
- RGB LED
- PIR sensor module
You can find a PIR sensor module from followings:
- RadioShack : http://www.radioshack.com/product/index.jsp?productId=2906724&CAWELAID=124299771
- Futurelec : http://www.futurlec.com/PIR_Sensors.shtml
- Sparkfun : http://www.sparkfun.com/products/8630
- Adafuruit : http://www.adafruit.com/index.php?main_page=product_info&cPath=35&products_id=189
Arduino Libraries
- HPRGB Library : powering High Power RGB LED Shield
Circuit
The PIR sensor is very easy to connect to Arduino. Just connect VCC, GND and Signal line (digital I/O pin). You can find detailed information regarding PIR sensor form ladyada. Normally PIR signal pin can be connected to any digital pins, but for educational purpose, demo code use external interrupt pins which has to be D2 or D3 of the Arduino.
The picture from ladyada.
Setup Picture
Arduino + High Power RGB LED Shield + Heatsink + RGB LEDs + PIR Sensor Module
Arduino Code
The code can be really simple. However I made it slightly more sophiscated. Instead of normal Digitalread, the code include external interrrupt to detect PIR sensor signal. Also Fading effect is done without delay().
The lamp normally show sleeping like fading. When PIR detect motion, it show red blink for 5 sec.
1: /*********************************************************************************************
2: PIR based LED Alarm
3:
4: Normally White LEDs on CH3 have Sleeping LED effect
5: When motion is detected, Red LED Blink alarm for 5 sec.
6: **********************************************************************************************
7: Details
8:
9: Instead of regular digitalread for PIR detection, Interrupt used for educational purpose.
10: Fade without delay used for quick response to status change
11: **********************************************************************************************/
12:
13: #include <Wire.h>
14: #include <HPRGB.h>
15:
16: int pirPin = 2; // for interrupt use, pin has to be D2 or D3
17: boolean pirHigh = false; // no motion detected
18: long previousMillis = 0; // will store last time LED was updated
19: int fadeInterval = 50;
20: int brightness = 0; // how bright the LED is
21: int fadeAmount = 5; // how many points to fade the LED by
22:
23: HPRGB ledShield;
24:
25: void setup() {
26: ledShield.begin(); // assum you have proper current, frequency setting stored in EEPROM of the HP RGB shield
27: pinMode(pirPin, INPUT);
28: attachInterrupt(0, alarm, RISING); // D2 pin interrupt, only detect LOW to HIGH
29: }
30:
31: void loop(){
32: if (pirHigh) { // alarm for 5 sec
33: for(int i=0; i<10 ;i++){
34: ledShield.goToRGB(255,0,0);
35: delay(400);
36: ledShield.goToRGB(0,0,0);
37: delay(100);
38: }
39: pirHigh = false; // put it back to normal
40: } else { // sleeping mood light effect without delay
41: unsigned long currentMillis = millis();
42: if(currentMillis - previousMillis > fadeInterval) {
43: previousMillis = currentMillis;
44: ledShield.goToRGB(brightness,brightness,brightness);
45: brightness = brightness + fadeAmount;
46: if (brightness == 0 || brightness == 255) {
47: fadeAmount = -fadeAmount ;
48: }
49: }
50: }
51: }
52: void alarm(){
53: pirHigh = true;
54: }
Video
Demonstration of setup and code
RGB LED Mood Lamp Clock
3
Here is a third fun project with High Power RGB LED Shield and Arduino.
There are several interesting clocks using LEDs. Here is my blinking LED clock.
Maxim DS1307 is a popular real time clock chip which is available as module as well.
Basically, clock is displayed as number of blinking of hour(red), first digit minute(green), second digit(blue).
What you need
- Arduino (any version)
- High Power RGB LED shield
- RGB LED
- DS1307 real-time clock
- Push button
You can find a DS1307 module from followings:
- Futurelec : http://www.futurlec.com/Mini_DS1307.shtml
- Sparkfun : http://www.sparkfun.com/products/99
- Adafuruit : http://www.ladyada.net/learn/breakoutplus/ds1307rtc.html
Arduino Libraries
- HPRGB Library : powering High Power RGB LED Shield
- Time Library : useful time function and DS1307 library
- Bounce Library : to make push button work correctly
Circuit
For push button, one pin connected to 5V, the other pin to digitalIn (2) which need to pull-down by conneting to GND through resistor (1-100K ohms)
DS1307 communicate with Arduino using I2C. At least four pins need to connected. VCC, GND, SCK(A5), SDA(A4)
Setup Picture
Arduino + High Power RGB LED Shield + Heatsink + RGB LEDs + DS1307 module + push button
Arduino Code
Download and install Shield, Time, Bounce libraries.
It read push button press using debounce method to eliminate button press noise. If button is pressed, read the current time from DS1307. Time is separated into three variables: hour, first digit of minute, second digit of minute, then blink specific color of LED
1: #include <Wire.h>
2: #include <HPRGB.h>
3: #include <Time.h>
4: #include <DS1307RTC.h>
5: #include <Bounce.h>
6:
7: #define blinkDelay 200
8: #define BUTTON 2
9:
10: HPRGB ledShield; // default mcp4728 id(0) and default czyRGB address(9)
11: Bounce bouncer = Bounce(BUTTON,5);
12:
13: int red, green, blue;
14:
15: void setup()
16: {
17: ledShield.begin();
18: ledShield.setCurrent(700,700,700); // set maximum current for channel 1-3 (mA)
19: ledShield.setFreq(600);// operation frequency of the LED drive
20: ledShield.stopScript();
21: ledShield.goToRGB(255,255,255);
22: setSyncProvider(RTC.get); // the function to get the time from the RTC
23: setTime(2,34,00,14,3,2011); // set the time for demo
24: pinMode(BUTTON,INPUT);
25: }
26:
27: void loop()
28: {
29: bouncer.update(); // Update the debouncer
30: int value = bouncer.read(); // Get the update value
31: if (value == HIGH) { // If button is pressed
32: int minuteT = minute();
33: int minuteMS = minuteT / 10;
34: int minuteLS = minuteT % 10;
35:
36: red=255; green=0; blue=0;
37: clockBlink(hourFormat12());
38: delay(500);
39: red=0; green=255; blue=0;
40: clockBlink(minuteMS);
41: delay(500);
42: red=0; green=0; blue=255;
43: clockBlink(minuteLS);
44: ledShield.goToRGB(255,255,255);
45: }
46: }
47:
48: void clockBlink(int num) {
49: while(num >= 1)
50: {
51: ledShield.goToRGB(0,0,0);
52: delay(blinkDelay);
53: ledShield.goToRGB(red,green,blue);
54: delay(blinkDelay);
55: num--;
56: }
57: }
Video
Demonstration of setup and code
IR controlled Mood Lamp
0Here is a second fun project with High Power RGB LED Shield and Arduino.
It is very easy to make a Infrared remote controlled RGB mood lamp with Arduino. All you need are a common IR receiver diode and IR remote. Now, you have full control of color and brightness of the LED.
Receiving IR code from a remote is handled by Ken’s fantastic IRremote library.
http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
What you need.
- Arduino (any version)
- High Power RGB LED shield
- RGB LED
- Infrared receiver diode (38KHz, TSOP328)
- IR remote (NEC, SONY, RC5, RC6 compatible)
You can find IR receiver diode from followings:
- Mouser : http://www.mouser.com/Search/ProductDetail.aspx?R=TSOP38238virtualkey61370000virtualkey782-TSOP38238
- Sparkfun : http://www.sparkfun.com/products/10266
- RadioShack : http://www.radioshack.com/product/index.jsp?productId=2049727
The IRremote library only decode 4 different IR codes, however they are very common types. It is highly likely you have one of those that are supported. I used a Canon camcorder remote.
Circuit
Depending on receiver diode. Normally 5V, GND, and signal.
Connect Signal pin to any digital pin (11). IR receiver does not look like in the picture though.
Setup Picture
Arduino + High Power RGB LED Shield + Heatsink + RGB LEDs + IR receiver
Arduino Code
First, install IRremote library from https://github.com/shirriff/Arduino-IRremote
You can find IR code of a remote by running IRrecvDemo example of IR remote library.
Change IR code of the sketch based on your IR remote code.
The Arduino sketch read IR code and output Hue or brightness value to the shield.
1: #include <Wire.h>
2: #include <HPRGB.h>
3: #include <IRremote.h>
4:
5: #define HUEUP 0xA16E54AB
6: #define HUEDOWN 0xA16ED42B
7: #define BRIGHTUP 0xA16E38C7
8: #define BRIGHTDOWN 0xA16EB847
9:
10: int RECV_PIN = 11;
11: int hueValue = 255;
12: int hueStep = 5;
13: int brightness = 255;
14: int brightnessStep = 5;
15:
16: HPRGB ledShield; // default mcp4728 id(0) and default czyRGB address(9)
17: IRrecv irrecv(RECV_PIN);
18: decode_results results;
19:
20: void setup()
21: {
22: ledShield.begin();
23: ledShield.setCurrent(700,700,700); // set maximum current for channel 1-3 (mA)
24: ledShield.setFreq(600);// operation frequency of the LED drive
25: ledShield.stopScript();
26: irrecv.enableIRIn(); // Start the receiver
27: }
28:
29: void loop() {
30: if (irrecv.decode(&results)) {
31: switch (results.value) {
32: case HUEUP: // Hue up
33: hueValue = hueValue + hueStep;
34: ledShield.fadeToHSB(hueValue, 255, brightness);
35: break;
36: case HUEDOWN: // Hue down
37: hueValue = hueValue - hueStep;
38: ledShield.fadeToHSB(hueValue, 255, brightness);
39: break;
40: case BRIGHTUP: // brightness up
41: if (brightness + hueStep < 255){
42: brightness = brightness + brightnessStep;
43: }
44: ledShield.fadeToHSB(hueValue, 255, brightness);
45: break;
46: case BRIGHTDOWN: // brightness down
47: if (brightness - brightnessStep > 0){
48: brightness = brightness - brightnessStep;
49: }
50: ledShield.fadeToHSB(hueValue, 255, brightness);
51: break;
52: }
53: irrecv.resume(); // Resume decoding (necessary!)
54: }
55: }
Video
Demonstration of setup and code
Color changing mood light
0
Here is a first fun project with High Power RGB LED Shield and Arduino.
Since it is first project, it is really simple to make and code. Color changing beautiful mood lamp.
White box in the video is the rectangular light shade that I made with white polycarbonate from local hardware store.
What you need.
- Arduino (any version)
- High Power RGB LED shield
- RGB LED
- Potentiometer (any type, any ohm range)
Circuit
It is a very simple circuit. One end of potentiometer to 5V, the other end to GND, and middle wiper to A0. That’s it.
Setup Picture
Arduino + High Power RGB LED Shield + Heatsink + RGB LEDs + Potentiometer
Arduino Code
19 lines of code. Read potentiometer value and output Hue value to the shield.
1: #include <Wire.h>
2: #include "HPRGB.h"
3:
4: HPRGB ledShield; // default mcp4728 id(0) and default czyRGB address(9)
5: const int analogInPin = A0;
6:
7: void setup()
8: {
9: ledShield.begin();
10: ledShield.setCurrent(700,700,700); // set maximum current for channel 1-3 (mA)
11: ledShield.setFreq(600);// operation frequency of the LED drive
12: }
13:
14: void loop()
15: {
16: int potValue = analogRead(analogInPin); // read the analog in value:
17: int hueValue = map(potValue, 0, 1023, 0, 255); // map it to the range of the Hue:
18: ledShield.fadeToHSB(hueValue, 255, 255);
19: }
Video
Demonstration of setup and code
High PWM frequency for LED.. Good or Bad?
16More technical writings on the LED driver before I write about fun stuffs soon.
This is just for people who are interest in technical details for the LED driver. Normal users should not worry much about it. So, please skip this.
There seems confusion about PWM frequency for high power LED dimming. I saw posts in forums about LED flickering especially at low PWM %. Some think they are seeing this problem due to low PWM frequency when they are driving high power LEDs. I want to point out that is highly unlikely the case. Here is why.
The PWM is a great way of dimming LEDs by adjusting ratio of on/off quickly. How quickly? The rule of thumb is higher than 100Hz frequency PWM make human can not see the flickering. When you see a movie, you are seeing 24Hz flickering. People barely tell it is flickering. When light is completely turn on/off, you need higher frequency than that. That’s about 100Hz. You can find more information about that by searching “flicker fusion threshold”
There are some cases where you want to have higher frequency PWM than 100Hz for LED. When you or your lighting source is moving, you may notice flickering at 100Hz due to the movements. Some very high current output LED driver or weird board design make you to hear PWM noise due to capacitor or something else ringing. Some people hear noises when they are driving motors with audible PWM frequency. That is a very rare case for PWM LED dimming.
Those two may be the only reasons why you need to use high PWM frequency for LED. Here are why you should avoid high PWM frequency for LED dimming for high power LED driver. When switching LED driver handle PWM signal, it is essentially turn on/off switching supply based on PWM signal. However it can not turn on/off at very high speed. Regular LED driver takes about 10-50us for on/off. Now let’s do a simple calculation. If PWM frequency is 100 Hz, each full PWM pulse is 10ms (1sec / 100). For 8 bit PWM dimming, each pulse need to divide into 256. So 1/255 pulse will be 40us. Now you are start to see a potential problem. Since some LED driver takes 50us to turn on/off, 40us pulse of PWM is not enough time. Now what you are start to see is half way on/off which result in flickering LED. Because most good LED drivers have on/off time close to 10-15us, you don’t see this kind of problem with 8 bit PWM with 100Hz frequency.
The problem is that Arduino has a two different default PWM frequencies (500Hz and 1000Hz) depending on pins. Now you see why some people saw these flicking like effect at low PWM duty cycle. If LED driver is connected to 1KHz PWM pin, LED driver need to turn on/off LED within 4us which is too short time even for the good LED driver. You may see flicking LED at low % PWM. To make this on/off time faster, some LED driver designs include additional transistors or mosfets which make LED driver to on/off less than 1us. My high power RGB LED driver shield also has mosfets even though it is not quite necessary.
There are PCB mount LED driver module like popular Luxdrive BuckPucks or some switching LED drivers from China. These may not be good even for 8 bit PWM dimming. For example, the BuckPuck has total 30us on/off time (15us each). They are recommending 50us. I know these are maximum values. Still they are barely OK for 8 bit PWM at 100Hz. If you use Arduino default frequency, they are definitely start to flickering at low PWM duty cycle (below 13/255 at 1KHz). You want to use low PWM frequency with those drivers not default frequency. It is not Luxdrive’s fault at all. Majority of LED drivers and modules are actually designed that way. Assuming that their drivers have flicker-less operation and 8 bit PWM dimming at 100-200Hz.
So you don’t want to use regular high power LED drivers with high PWM frequency and higher than 8 bit resolution PWM unless you know what you are doing. Naturally, analog dimming has no flickering problem, since you are not on/off LEDs.
Power LED Review
0
There are many different power LEDs from manufactures. Even the same LEDs mounted on different boards. I have some high power LEDs that I bought for the LED shield. Here is a brief review on these for the people who consider to buy one of those.
White LED
350mA White LED
The LED is one of most common 350mA white LED and is copycat of famous Luexeon I. I bought it from Sparkfun but it is likely sourced from China. It come with MCPCB. Measured Vf=3.18 at 350mA
700mA Cree XR-E Q2
Cree is a big name in the high power LED industry. They are simply cutting-edge in term of LED chip technology along with Philips. They are making one of the most efficient LED in the market. XR-E is also quite efficient 700mA line. “Q2” is the bin codes which indicate basically brightness LED among the same XR-E. There are quite a bit of price difference depending on bin code. Better bin code means brighter and better efficiency. (P2 bin – 67lm, Q2 – 87lm, Q5 – 107lm, all at 350mA, minimum flux). You can buy XR-E P4, Q2, Q5, R2 bins from dealextreme. Measured Vf=3.62 at 700mA
http://www.dealextreme.com/p/cree-xr-e-q2-emitter-with-star-2395
RGB LED
700mA Cree XR-E Color
These are red, green, blue LEDs that are same series with white XR-E. Bought them from dealextreme as well. they are efficient and bright but don’t have any bin code. Color LED have slightly different wavelength depending on bin code. Since they are three separate LED, they are not good for RGB color mixing. Lens from Sparkfun can be used with these three LEDs for color mixing though. If you know any place I can buy Cree RGB mounted on single MCPCB, please let me know. Measured Vf at 700mA are red = 2.16V, green = 3.65V, blue =3.2V
http://www.dealextreme.com/p/blue-cree-led-emitter-20mm-3-2-3-4v-1775
http://www.dealextreme.com/p/green-cree-led-emitter-20mm-1-9-2-2v-1777
http://www.dealextreme.com/p/red-cree-led-emitter-20mm-1-9-2-2v-1776
3W (350mA x 3) RGB LED
This is basically 3 LED dies (Red, Green, Blue) combined in a chip. Each color is rated 350mA. I bought it from sprakfun. Almost same kind are widely available from many places. Since 3 different LED dies are in a chip, it has very good color mixing. Quility of build is just fine. Solder points are a bit too close. Be careful not to make a short. Measured Vf at 350mA are red=2.36, green = 3.24, blue = 3.18
http://www.sparkfun.com/products/8718
10W (350mA x 3 x 3) RGB LED
When you want to have a powerful RGB LED that has a good color mixing, this is what your looking for. This LED is exactly 3x 3W RGB LED above. This LED has 3x 350mA in series for each color. This is not exactly 10W more less 8.8W, but still very bright. Quality of build is very good. It is cheaper than similar 700mA Lumiled comination. Measured Vf at 350mA are red=6.39V, Green=9.38V, Blue=9.22V
http://www.dealextreme.com/p/10w-500-lumen-multi-color-rgb-led-emitter-metal-plate-140-degree-44043
700mA Philips Lumiled Color
Philips is another big name in LED market along with Cree, Osram, SSC and so on. They make very efficient 700mA. Unlike Cree color led, you can easily find RGB LEDs that are mounted on single MCPCB or FR-4 PCB. Believe or not red big PCB (from Sparkfun) and small white star MCPCB (from ledsupply) have same kinds of LEDs. They have all Three RGB 700mA Lumileds. A difference in LEDs is one from Sparkfun has royal blue rather than ragular blue. Royal blue is the way how Philips call deeper blue (shorter wave length). MCPCB has smaller thermal resistance than FR-4 PCB. Small thermal resistance means cooler LED (about 10 Celsius degree difference). Due to the larger size of PCB (Sparkfun), it has poorer RGB color mixing.
http://www.sparkfun.com/products/9738
http://www.sparkfun.com/products/9732
Ready for Sale
0
I decided to run first production.
You will get fully assembled and tested shield for $37.
(Without thermo sensor and arduino stackable pins)
Shipping is flat rate (shipped by USPS post)
US : $3
Canada, Mexico : $12
International : $15
Paypal Only
You can order from store menu.
http://neuroelec.com/products-page/
first 10 shields will come with stackable pins.
Once, I get more stackable pins, I will add a option for that (+$1.50)
If you have question, please leave a comment or email me at neuroelec/at/gmail.com
I have updated the manual page and shield library.
Manual : http://neuroelec.com/hp-rgb-led-shield/high-power-rgb-led-shield-manual/
Recent Comments