原文地址:https://circuitdigest.com/microcontroller-projects/neopixel-rgb-led-strip-with-arduino
如何利用Arduino和TFT LCD操控NeoPixel LED灯条
经过**阿维纳什·库玛(Avinash Kumar)** 2016年8月30日1个
任何颜色都由三种颜色组成:红色,绿色和蓝色,使用简单的RGB LED即可生成任何颜色。但是RGB LED的局限性在于它内部具有三个独立的LED,并且需要任何微控制器的三个引脚才能操作一个RGB LED。因此,不可能将数百个LED与一个微控制器连接。
为了克服这个问题,Adafruit创建了NeoPixel LED灯带。它仅需三个引脚即可驱动多个RGB NeoPixel LED。两个引脚用于电源和接地,一个引脚用于数据输入(DI)。数据输入引脚用于通过颜色,亮度等对条带中的不同LED进行寻址和控制。但是它需要一个微控制器来运行NeoPixels。Arduino在NeoPixel中非常常用,因此今天我们将学习将NeoPixel LED与Arduino接口。您可以在AdaFruit上了解有关NeoPixels的更多信息。
在此项目中,我们正在使用Arduino和TFT LCD触摸屏控制NeoPixel LED。我们在2.4英寸TFT LCD上创建了7个不同颜色的触摸按钮,当您在LCD上点击某种颜色的按钮时,NeoPixel LED灯条将以与该按钮相同的颜色点亮。在这里,我们使用了30个LED的NeoPixel数字RGB LED灯带。
NeoPixel RGB LED可以用任何颜色点亮,因此我们可以在LCD上添加更多按钮,以便在点击这些按钮时以更多颜色发光。也可以使用编码添加其他漂亮的效果和图案。您可以使用NEO Pixel LED建立一个完整的**Arduino控制的装饰系统,**并可以通过附近的LCD控制该系统。
所需组件:
- Arduino Mega或任何其他Arduino模型
- 带SPFD5408控制器的2.4英寸TFT LCD屏蔽
- NeoPixel RGB LED灯条
- 连接线
- USB电缆或12 V 1A适配器
电路连接:
要将NeoPixels Strip连接到Arduino Mega,只需将Arduino 5V引脚连接到NeoPixel的5V引脚,将Mega的GND连接到NeoPixel的GND,然后将NeoPixel DI引脚(数据输入)连接到Arduino Mega的数字引脚36。小心地将TFT LCD触摸屏安装在Arduino上,以使MEGA的GND位于LCD的GND下方,而Arduino的5V引脚连接至LCD的5V引脚。
将其连接到Arduino时,请注意不要互换NeoPixel LED灯条的GND和5V引脚,否则会损坏NeoPixel LED灯条。还要注意,这里我们使用了Arduino Mega,但您也可以使用任何其他Arduino模型。
与Arduino的NeoPixel RGB LED灯带连接:
Arduino引脚 | NeoPixel Strip的别针 |
---|---|
5伏 | 5伏 |
地线 | 地线 |
数字引脚号 36 | DI(数据输入) |
工作说明:
NeoPixel LED与Arduino的工作非常简单。只需在要点亮NeoPixel LED灯带的LCD上点按任何颜色的触摸按钮即可。LED将根据该颜色点亮。代码的编写方式使您可以无休止地重复执行此任务,而不必重置Arduino Mega。您可以在本文末尾查看代码和演示视频。
当在LCD上点击任何按钮时,数据将发送到Arduino,然后Arduino进一步将指令发送到NeoPixel Strip相应地点亮。例如,当我们点击LCD上的绿色按钮时,NeoPixel LED灯条会发出绿色光,而当我们按下红色按钮时,LED灯条会发出红色光,依此类推。
编程说明:
为了将TFT LCD与Arduino接口,我们使用了一些库。所有的库都放在一个rar文件中,可以从此链接下载 。单击“克隆或下载”和“下载ZIP”文件,然后添加到您的Arduino库文件夹。TFT LCD的正常运行需要该库。
#include <SPFD5408_Adafruit_GFX.h> //核心图形库
#include <SPFD5408_Adafruit_TFTLCD.h> //特定于硬件的库
#include <SPFD5408_TouchScreen.h>
您应该通过使用库中提供的示例代码烧录Arduino来测试TFT LCD,并检查代码是否正常工作。首先检查图形测试,然后进行校准测试,最后进行油漆测试。如果发现所有功能都可以正常工作,则从本教程中给出的代码开始。
另外,为了使NeoPixel RGB LED灯带正常工作,您将需要一个其他的库,可以从这里下载。
#include <Adafruit_NeoPixel.h>
如前所述,MEGA的数字引脚36连接到NeoPixel LED灯带的DI引脚,如下代码所示。同样,代码条中的LED数量为30,如代码所示:
#define PIN 36
#define NUM_LEDS 30
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
代码中定义了按钮的一些参数,例如大小和位置:
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参数用于调整LCD上按钮的尺寸。如果将其设置为40,则按钮的大小将增加一倍。y参数是LCD的y坐标。
触摸按钮由数字表示,如代码所示:
#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
一些功能用于从NeoPixel发出颜色,例如:
void EmitCyan();
void EmitWhite();
void EmitGreen();
void EmitYellow();
void EmitPink();
void EmitBlack();
要查找要为给定颜色输入的数字RGB值,您可以点击此链接。只需输入您希望NeoPixel发光的颜色,找到该颜色的RGB值,然后输入上面的功能即可。
*void initializeButtons()*函数用于为按钮赋予文本和颜色,并将其放置在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()*函数用于在LCD上绘制按钮。
void showCalibration() {
tft.setCursor (40, 0);
for (uint8_t i = 0; i < 8; i++) {
buttons[i].drawButton();
}
}
此外,下面给出了用于以所需颜色发光NeoPixel LED灯带的完整Arduino代码。代码有点长,但是很简单,您可以轻松理解代码。
代码
#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();
}
}