Any color is made up of three colors: Red, Green and Blue, using a simple RGB LED you can generate any color. But the limitation of RGB LED is that it has three separate LEDs inside it and requires three Pins of any microcontroller to operate one RGB LED. So it is not possible to connect hundreds of LEDs with one microcontroller.
To overcome this problem Adafruit has created NeoPixel LED Strip. It requires only three pins to drive several RGB NeoPixel LEDs. Two pins are for power and ground and one Pin is for Data In (DI). Data IN pin is used to address and control the different LEDs in the strip with their color, brightness etc. But it requires a Microcontroller to run NeoPixels. Arduino is very commonly used with NeoPixel, so today we will learn to Interface NeoPixel LEDs with Arduino. You can learn more about NeoPixels at AdaFruit.
Here in this project we are Controlling NeoPixel LED using Arduino and TFT LCD touch Screen. We have created 7 touch buttons of different colors on 2.4 inch TFT LCD and when we tap the button of certain color on the LCD, the NeoPixel LED strip illuminates with the same color of that button. Here we have used NeoPixel Digital RGB LED strip of 30 LEDs.
NeoPixel RGB LED can be illuminated in any color and so we can add more buttons on the LCD to glow the LED in more colors on tapping on those buttons. Other beautiful effects and patterns can also be added using Coding. You can build a full Arduino controlled Decoration System using NEO Pixel LEDs and can control this system by LCD lying near to you.
Required components:
- Arduino Mega or any other Arduino model
- 2.4 inch TFT LCD Shield with SPFD5408 controller
- NeoPixel RGB LED Strip
- Connecting Wires
- USB Cable or 12 V 1A adapter
Circuit Connections:
To connect NeoPixels Strip to Arduino Mega simply connect Arduino 5V pin to NeoPixel’s 5V pin and Mega’s GND to NeoPixel’s GND and then connect NeoPixel DI pin (data in) to Digital Pin no 36 of Arduino Mega. Carefully mount the TFT LCD Touch Shield over Arduino such that GND of MEGA lies beneath GND of LCD and 5V pin of Arduino connects to 5V pin of LCD.
Take care not to interchange GND and 5V pin of NeoPixel LED strip while connecting it to Arduino, otherwise it will damage the NeoPixel LED strip. Also note that here we have used Arduino Mega but you can use any other Arduino model.
Connections to Arduino to NeoPixel RGB LED Strip:
Arduino Pins |
NeoPixel Strip’s Pins |
5v |
5v |
GND |
GND |
Digital Pin no. 36 |
DI (data in) |
Working Explanation:
Working of NeoPixel LED with Arduino is very easy. Just tap the touch button of any color on the LCD in which you want to glow the NeoPixel LED strip. The LED will light according to that color. Code is written in such a way so that you can repeat this task endlessly without having to reset the Arduino Mega. You can check the Code and Demo Video at the end of this article.
When any button is tapped on the LCD, data is sent to Arduino and Arduino further sends instruction to NeoPixel Strip to light accordingly. For example NeoPixel LED strip glows in Green color when we tap the Green button on the LCD and LED strip glows in Red color when we press the Red button and so on.
Programming Explanation:
To Interface TFT LCD with Arduino we have used some libraries. All the libraries come in one rar file and can be downloaded from this link. Click on ‘Clone or download’ and ‘Download ZIP’ file and add to your Arduino library folder. This library is needed for proper functioning of TFT LCD.
#include <SPFD5408_Adafruit_GFX.h> // Core graphics library #include <SPFD5408_Adafruit_TFTLCD.h> // Hardware-specific library #include <SPFD5408_TouchScreen.h>
You should test your TFT LCD by burning Arduino with examples codes given in the Library and check if codes are working properly. First check the graphics test, then calibrate test and finally paint test. If you find that all features all working fine then start with code given in this tutorial.
Also for proper functioning of NeoPixel RGB LED strip, you will need one more library, which can be downloaded from here.
#include <Adafruit_NeoPixel.h>
As described earlier Digital Pin 36 of MEGA is connected to DI pin of NeoPixel LED Strip as shown in code below. Also the numbers of LEDs in the Strip are 30 so as is written in code:
#define PIN 36 #define NUM_LEDS 30
Display colors of LCD buttons are denoted by some Codes. You can change these codes according to your LCD.
#define BLACK 0x0000 #define YELLOW 0x001F #define GREEN 0xF800 #define RED 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define BLUE 0xFFE0 #define WHITE 0xFFFF
Some parameters for the buttons like size and position are defined in the code:
uint16_t width = 0; uint16_t height = 0; uint16_t x = 40; uint16_t y = height - 20; uint16_t w = 75; uint16_t h = 20;
h parameter is used to adjust the size of button on LCD. If you make it 40, then the size of button will get doubled. y parameter is y coordinate of LCD.
Touch buttons are denoted by numbers as shown in code:
#define BUTTONS 9 #define BUTTON_Red 0 #define BUTTON_DarkRed 1 #define BUTTON_RED 2 #define BUTTON_DarkGreen 3 #define BUTTON_DeepRed 4 #define BUTTON_Blue 5 #define BUTTON_LightBlue 6 #define BUTTON_LightBlue1 7
Some functions are used to emit the color out of NeoPixel like:
void EmitCyan(); void EmitWhite(); void EmitGreen(); void EmitYellow(); void EmitPink(); void EmitBlack();
To find the digital RGB values to be entered for the given color, you can follow this link. Just enter the color you want your NeoPixel strip to glow, find the RGB values for that color and put in above functions.
void initializeButtons() function is used for giving text and color to buttons and also for placing them at required place on LCD.
void initializeButtons() { uint16_t x = 40; uint16_t y = height - 20; uint16_t w = 75; uint16_t h = 40; uint8_t spacing_x = 5 ..... ..... .... ......
void showCalibration() function is used to draw the buttons on the LCD.
void showCalibration() { tft.setCursor (40, 0); for (uint8_t i = 0; i < 8; i++) { buttons[i].drawButton(); } }
Further the Full Arduino Code for Glowing the NeoPixel LED strip in desired Color is given below. Code is bit lengthy but simple, you can understand the code easily.
#include <Adafruit_NeoPixel.h>
#include <math.h>
#include <SPFD5408_Adafruit_GFX.h> // Core graphics library
#include <SPFD5408_Adafruit_TFTLCD.h> // Hardware-specific library
#include <SPFD5408_TouchScreen.h>
// *** SPFD5408 change -- End
#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif
#define YP A1 // must be an analog pin, use "An" notation!
#define XM A2 // must be an analog pin, use "An" notation!
#define YM 7 // can be a digital pin
#define XP 6 // can be a digital pin
#define PIN 36
#define NUM_LEDS 30
#define BRIGHTNESS 80
// Calibrate values
#define TS_MINX 125
#define TS_MINY 85
#define TS_MAXX 965
#define TS_MAXY 905
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
// optional
#define LCD_RESET A4
// Assign human-readable names to some common 16-bit color values:
#define BLACK 0x0000
#define YELLOW 0x001F
#define GREEN 0xF800
#define RED 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define BLUE 0xFFE0
#define WHITE 0xFFFF
void EmitCyan();
void EmitWhite();
void EmitGreen();
void EmitYellow();
void EmitPink();
void EmitBlack();
uint16_t width = 0;
uint16_t height = 0;
uint16_t x = 40;
uint16_t y = height - 20;
uint16_t w = 75;
uint16_t h = 20;
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
#define BOXSIZE 40
#define PENRADIUS 3
#define BUTTONS 9
#define BUTTON_Red 0
#define BUTTON_DarkRed 1
#define BUTTON_RED 2
#define BUTTON_DarkGreen 3
#define BUTTON_DeepRed 4
#define BUTTON_Blue 5
#define BUTTON_LightBlue 6
#define BUTTON_LightBlue1 7
Adafruit_GFX_Button buttons[BUTTONS];
uint16_t buttons_y = 0;
#define MINPRESSURE 10
#define MAXPRESSURE 1000
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println(F("Paint!"));
tft.reset();
tft.begin(0x9341); // SDFP5408
strip.begin();
strip.show(); // Initialize all pixels to 'off'
tft.setRotation(0); // Need for the Mega, please changed for your choice or rotation initial
tft.fillScreen(BLACK);
tft.setCursor (40, 20);
tft.setTextSize (5);
tft.setTextColor(WHITE);
tft.println("COLORS");
tft.setCursor (65, 85);
width = tft.width() - 1;
height = tft.height() - 100;
initializeButtons();
showCalibration();
}
void loop() {
// put your main code here, to run repeatedly:
// Test of calibration
int i = 0;
TSPoint p;
// Wait a touch
digitalWrite(13, HIGH);
p = waitOneTouch();
digitalWrite(13, LOW);
p.x = mapXValue(p);
p.y = mapYValue(p);
for (uint8_t b = 0; b <BUTTONS; b++) {
if (buttons[b].contains(p.x, p.y)) {
// Action
switch (b) {
case BUTTON_Red:
EmitPink();
showCalibration();
break;
case BUTTON_DarkRed:
EmitCyan();
showCalibration();
break;
case BUTTON_RED:
EmitBlack();
showCalibration();
break;
case BUTTON_DarkGreen:
EmitGreen();
showCalibration();
break;
case BUTTON_Blue:
EmitBlue();
showCalibration();
break;
case BUTTON_LightBlue:
EmitYellow();
showCalibration();
break;
case BUTTON_DeepRed:
EmitDeepRed();
showCalibration();
break;
}
}
}
}
void initializeButtons() {
uint16_t x = 40;
uint16_t y = height - 20;
uint16_t w = 75;
uint16_t h = 40;
uint8_t spacing_x = 5;
uint8_t textSize = 2;
char buttonlabels[7][20] = {"PINK", "CYAN", "WHITE", "GREEN", "RED", "BLUE", "YELLOW"};
uint16_t buttoncolors[15] = {RED, GREEN, BLACK, MAGENTA, CYAN, BLUE, YELLOW};
for (uint8_t b = 0; b < 9; b++) {
if (b < 3)
{
buttons[b].initButton(&tft, // TFT object
x + b * (w + spacing_x), y, // x, y,
w, h, BLACK, buttoncolors[b], WHITE, // w, h, outline, fill,
buttonlabels[b], textSize);
Serial.print( h);
}// text
if (b == 3)
{
uint16_t x = 40;
uint16_t y = height + 30 ;
uint16_t w = 75;
uint16_t h = 40;
buttons[b].initButton(&tft, // TFT object
x + 0 * (w + spacing_x) , y, // x, y,
w, h, BLACK, buttoncolors[b], WHITE, // w, h, outline, fill,
buttonlabels[b], textSize);
}
if (b == 4)
{
uint16_t x = 40;
uint16_t y = height + 30 ;
uint16_t w = 75;
uint16_t h = 40;
buttons[b].initButton(&tft, // TFT object
x + 1 * (w + spacing_x) , y, // x, y,
w, h, BLACK, buttoncolors[b], WHITE, // w, h, outline, fill,
buttonlabels[b], textSize);
}
if (b == 5)
{
uint16_t x = 40;
uint16_t y = height + 30 ;
uint16_t w = 75;
uint16_t h = 40;
buttons[b].initButton(&tft, // TFT object
x + 2 * (w + spacing_x) , y, // x, y,
w, h, BLACK, buttoncolors[b], WHITE, // w, h, outline, fill,
buttonlabels[b], textSize);
}
if (b == 6)
{
uint16_t x = 40;
uint16_t y = height + 80 ;
uint16_t w = 75;
uint16_t h = 20;
buttons[b].initButton(&tft, // TFT object
x + 0 * (w + spacing_x) , y, // x, y,
w, h,BLACK, buttoncolors[b], WHITE, // w, h, outline, fill,
buttonlabels[b], textSize);
}
if (b == 7)
{
uint16_t x = 40;
uint16_t y = height + 80 ;
uint16_t w = 75;
uint16_t h = 40;
buttons[b].initButton(&tft, // TFT object
x + 2 * (w + spacing_x) , y, // x, y,
w, h,BLACK, buttoncolors[b], WHITE, // w, h, outline, fill,
buttonlabels[b], textSize);
}
}
// Save the y position to avoid draws
buttons_y = y;
}
// Map the coordinate X
uint16_t mapXValue(TSPoint p) {
uint16_t x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
//Correct offset of touch. Manual calibration
//x+=1;
return x;
}
uint16_t mapYValue(TSPoint p) {
uint16_t y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
//Correct offset of touch. Manual calibration
//y-=2;
return y;
}
TSPoint waitOneTouch() {
TSPoint p;
do {
p = ts.getPoint();
pinMode(XM, OUTPUT); //Pins configures again for TFT control
pinMode(YP, OUTPUT);
} while ((p.z < MINPRESSURE ) || (p.z > MAXPRESSURE));
return p;
}
void showCalibration() {
tft.setCursor (40, 0);
for (uint8_t i = 0; i < 8; i++) {
buttons[i].drawButton();
}
}
void EmitDeepRed()
{
for(int i=0;i<30;i++)
{
strip. setPixelColor(i, 255, 0, 0);
strip.show();
}
}
void EmitCyan()
{
for(int i=0;i<30;i++)
{
strip. setPixelColor(i,0, 255, 255);
strip.show();
}
}
void EmitWhite()
{
for(int i=0;i<30;i++)
{
strip. setPixelColor(i,255, 255, 255);
strip.show();
}
}
void EmitGreen()
{
for(int i=0;i<30;i++)
{
strip. setPixelColor(i,0, 255, 0);
strip.show();
}
}
void EmitBlue()
{
for(int i=0;i<30;i++)
{
strip. setPixelColor(i,0, 0, 255);
strip.show();
}
}
void EmitYellow()
{
for(int i=0;i<30;i++)
{
strip. setPixelColor(i,255, 255, 0);
strip.show();
}
}
void EmitPink()
{
for(int i=0;i<30;i++)
{
strip. setPixelColor(i,255, 0, 255);
strip.show();
}
}
void EmitBlack()
{
for(int i=0;i<30;i++)
{
strip. setPixelColor(i,255, 255, 255);
strip.show();
}
}
is there any way that i can use this with another type of strip that has 4 wires (r,g,b, and power)