基于esp32的ws2812点阵rgb屏幕开源项目
title: 基于esp32的ws2812点阵rgb屏幕开源项目
date: 2023-04-06 14:18:28
tags:
基于esp32的ws2812点阵rgb屏幕开源项目
开源代码库如下,代码是arduino框架下的历程,具体项目未完成
# /*
#像素信息协议数组 : information = {{x,y,r,g,b} , ---第一个像素信息
# {x,y,r,g,b} ...} ---第二个像素信息
#*/
#我写了一个图片转数组的脚本,可以大大提高转换效率,后期我也会将这个脚本转化软件
import cv2
cv2.namedWindow('new',cv2.WINDOW_NORMAL)
img_yuan = cv2.imread('./123.png',)
#规定显示的照片尺寸
re_x = 8
re_y = 8
re = (re_x,re_y)
img = cv2.resize(img_yuan,re,interpolation= cv2.INTER_LINEAR) #(x,y)
cv2.imshow('new',img)
print(img.shape)
# print(img)
a = img.shape
# print(a[0]) #y
# print(a[1]) #x
# print(a[2])
# print(img[0][0])
# print("***************test************")
i = 0
j = 0
print("uint8_t font_1[][5]= {")
while i<a[0]: # y
while j<a[1]: # x
if(i == a[0]-1 and j == a[1]-1):
print("{%d,%d,%d,%d,%d}"%(j,i,
int(img[i][j][2]), #red
int(img[i][j][1]), #green
int(img[i][j][0]))) #blue
else :
print("{%d,%d,%d,%d,%d},"%(j,i,
int(img[i][j][2]), #red
int(img[i][j][1]), #green
int(img[i][j][0]))) #blue
j+=1
j = 0
i+=1
print("}")
if cv2.waitKey(0) & 0xff==ord('q'):
cv2.destroyAllWindows()
以下是程序源代码,可以进行多平台移植,移植时只需要将void drawRGBpoint(uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b)函数里的pixels0.setPixelColor(x, pixels0.Color(r, g, b));改为对应单片机信号输出函数即可
#include <sc2812.h>
Adafruit_NeoPixel pixels0(WS_NUM, WS_PIN0, NEO_GRB + NEO_KHZ800); // 第一个参数led个数,第二个引脚号,第三个rgb模式,第四个800khz-ws2812
Adafruit_NeoPixel pixels1(WS_NUM, WS_PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels2(WS_NUM, WS_PIN2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels3(WS_NUM, WS_PIN3, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels4(WS_NUM, WS_PIN4, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels5(WS_NUM, WS_PIN5, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels6(WS_NUM, WS_PIN6, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels7(WS_NUM, WS_PIN7, NEO_GRB + NEO_KHZ800);
//像素点函数
void drawRGBpoint(uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b)
{
switch (y)
{
case 0:
pixels0.setPixelColor(x, pixels0.Color(r, g, b));
break;
case 1:
pixels1.setPixelColor(x, pixels1.Color(r, g, b));
break;
case 2:
pixels2.setPixelColor(x, pixels2.Color(r, g, b));
break;
case 3:
pixels3.setPixelColor(x, pixels3.Color(r, g, b));
break;
case 4:
pixels4.setPixelColor(x, pixels4.Color(r, g, b));
break;
case 5:
pixels5.setPixelColor(x, pixels5.Color(r, g, b));
break;
case 6:
pixels6.setPixelColor(x, pixels6.Color(r, g, b));
break;
case 7:
pixels7.setPixelColor(x, pixels7.Color(r, g, b));
break;
}
}
// 画某一个图片 ,且图片是基本图片位置信息
void drawPicXY(uint8_t x, uint8_t y, uint8_t (*information)[5], uint8_t num) // 图片位置坐标,信息二维数组,图片的像素个数
{
int i = 0;
for (i = 0; i < num; i++)
{
int x_m, y_m, r, g, b;
x_m = information[i][0];
y_m = information[i][1]; // 提取坐标信息
r = information[i][2];
g = information[i][3];
b = information[i][4]; // 提取颜色信息
drawRGBpoint(x_m + x, y_m + y, r, g, b); // 画点
}
}
// 画某一个图案,图案的位置信息为渲染后信息
void drawPicSC(uint8_t (*information)[5], uint8_t num) // 图片位置坐标,信息二维数组,图片的像素个数
{
int i = 0;
for (i = 0; i < num; i++)
{
int x, y, r, g, b;
x = information[i][0];
y = information[i][1]; // 提取坐标信息
r = information[i][2];
g = information[i][3];
b = information[i][4]; // 提取颜色信息
drawRGBpoint(x, y, r, g, b); // 画点
}
}
//字库显示函数
void numberFOUNT(uint8_t foundi ,uint8_t loc,uint8_t r, uint8_t g, uint8_t b)
{
int fontx, fonty, numb = 0;
uint8_t(*temp_m)[2] = 0;
uint8_t font_1[][2] = {{2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}}; // ---- 1
uint8_t font_2[][2] = {{0, 6}, {1, 6}, {2, 6}, {3, 6}, {3, 5}, {3, 4}, {0, 3}, {1, 3}, {2, 3}, {3, 3}, {0, 2}, {0, 1}, {0, 0}, {1, 0}, {2, 0}, {3, 0}}; // ------2
uint8_t font_3[][2] = {{0, 6}, {1, 6}, {2, 6}, {3, 6}, {3, 5}, {3, 4}, {0, 3}, {1, 3}, {2, 3}, {3, 3}, {3, 2}, {3, 1}, {0, 0}, {1, 0}, {2, 0}, {3, 0}}; // ------3
uint8_t font_4[][2] = {{2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {1, 3}, {3, 3}}; // ---- 4
uint8_t font_5[][2] = {{0, 6}, {1, 6}, {2, 6}, {3, 6}, {0, 5}, {0, 4}, {0, 3}, {1, 3}, {2, 3}, {3, 3}, {3, 2}, {3, 1}, {0, 0}, {1, 0}, {2, 0}, {3, 0}}; // ------5
uint8_t font_6[][2] = {{0, 6}, {1, 6}, {2, 6}, {3, 6}, {0, 5}, {0, 4}, {0, 3}, {1, 3}, {2, 3}, {3, 3}, {3, 2}, {3, 1}, {0, 2}, {0, 1}, {0, 0}, {1, 0}, {2, 0}, {3, 0}}; // ------6
uint8_t font_7[][2] = {{0, 6},{1, 6},{2, 6},{3, 6},{3, 6},{3, 5},{3, 4},{3, 3},{3, 2},{3, 1},{3, 0},}; // -------7
uint8_t font_8[][2] = {{0, 6}, {1, 6}, {2, 6}, {3, 6}, {0, 5}, {0, 4}, {3, 5}, {3, 4}, {0, 3}, {1, 3}, {2, 3}, {3, 3}, {3, 2}, {3, 1}, {0, 2}, {0, 1}, {0, 0}, {1, 0}, {2, 0}, {3, 0}}; // ------8
uint8_t font_9[][2] = {{0, 6}, {1, 6}, {2, 6}, {3, 6}, {0, 5}, {0, 4}, {3, 5}, {3, 4}, {0, 3}, {1, 3}, {2, 3}, {3, 3}, {3, 2}, {3, 1}, {0, 0}, {1, 0}, {2, 0}, {3, 0}}; // ------9
uint8_t font_0[][2] = {{0, 6}, {1, 6}, {2, 6}, {3, 6}, {0, 5}, {0, 4}, {3, 5}, {3, 4}, {0, 3}, {3, 3}, {3, 2}, {3, 1}, {0, 2}, {0, 1}, {0, 0}, {1, 0}, {2, 0}, {3, 0}}; // ------0
uint8_t font_point[][2]= {{0,1},{1,1},{0,2},{1,2}, {0,4},{0,5},{1,4},{1,5},};
switch (foundi)
{
case 0:
temp_m = font_0;
numb = 18;
break;
case 1:
temp_m = font_1;
numb = 7;
break;
case 2:
temp_m = font_2;
numb = 16;
break;
case 3:
temp_m = font_3;
numb = 16;
break;
case 4:
temp_m = font_4;
numb = 13;
break;
case 5:
temp_m = font_5;
numb = 16;
break;
case 6:
temp_m = font_6;
numb = 18;
break;
case 7:
temp_m = font_7;
numb = 10;
break;
case 8:
temp_m = font_8;
numb = 20;
break;
case 9:
temp_m = font_9;
numb = 18;
break;
case 10:
temp_m = font_point;
numb = 8;
break;
}
int i = 0;
for (i = 0; i < numb; i++)
{
fontx = temp_m[i][0];
fonty = temp_m[i][1]; // 提取坐标信息
drawRGBpoint(fontx +loc, fonty , r, g, b); // 画点
}
}
// SC函数封装
void AutodrawPicSC(uint8_t (*information)[5])
{
drawPicSC(information, sizeof(information) / (sizeof(information[0])));
}
// XY函数封装
void AutodrawPicXY(uint8_t x, uint8_t y, uint8_t (*information)[5])
{
drawPicXY(x, y, information, sizeof(information) / (sizeof(information[0])));
}
void show_2812()
{
pixels0.show(); // 刷新
pixels1.show(); // 刷新
pixels2.show(); // 刷新
pixels3.show(); // 刷新
pixels4.show(); // 刷新
pixels5.show(); // 刷新
pixels6.show(); // 刷新
pixels7.show(); // 刷新
}
void setup_2812()
{
/***WS2812******/
pixels0.begin(); // 初始化灯带
pixels0.clear(); // 清空灯带数组
pixels0.show(); // 刷新
/***WS2812******/
/***WS2812******/
pixels1.begin(); // 初始化灯带
pixels1.clear(); // 清空灯带数组
pixels1.show(); // 刷新
/***WS2812******/
/***WS2812******/
pixels2.begin(); // 初始化灯带
pixels2.clear(); // 清空灯带数组
pixels3.show(); // 刷新
/***WS2812******/
/***WS2812******/
pixels4.begin(); // 初始化灯带
pixels4.clear(); // 清空灯带数组
pixels4.show(); // 刷新
/***WS2812******/
/***WS2812******/
pixels5.begin(); // 初始化灯带
pixels5.clear(); // 清空灯带数组
pixels5.show(); // 刷新
/***WS2812******/
/***WS2812******/
pixels6.begin(); // 初始化灯带
pixels6.clear(); // 清空灯带数组
pixels6.show(); // 刷新
/***WS2812******/
/***WS2812******/
pixels7.begin(); // 初始化灯带
pixels7.clear(); // 清空灯带数组
pixels7.show(); // 刷新
/***WS2812******/
}
void clear_2812()
{
pixels0.clear(); // 清空灯带数组
pixels1.clear(); // 清空灯带数组
pixels2.clear(); // 清空灯带数组
pixels3.clear(); // 清空灯带数组
pixels4.clear(); // 清空灯带数组
pixels5.clear(); // 清空灯带数组
pixels6.clear(); // 清空灯带数组
pixels7.clear(); // 清空灯带数组
}
#ifndef SC2812_H
#define SC2812_H
#include <Arduino.h>
#include <Adafruit_NeoPixel.h> //关键是这个库
#define WS_PIN0 32 // 定义选择引脚
#define WS_PIN1 25 // 定义选择引脚
#define WS_PIN2 27 // 定义选择引脚
#define WS_PIN3 12 // 定义选择引脚
#define WS_PIN4 22 // 定义选择引脚
#define WS_PIN5 33 // 定义选择引脚
#define WS_PIN6 26 // 定义选择引脚
#define WS_PIN7 14 // 定义选择引脚
#define WS_NUM 31 // 定义led个数,决定数组长度
/*
像素信息协议数组 : information = {{x,y,r,g,b} , ---第一个像素信息
{x,y,r,g,b} ...} ---第二个像素信息
*/
// uint8_t pic[][5] = {
// {0, 0, 197, 115, 77},
// {0, 1, 197, 115, 77},
// // {0,2,197,115,77},
// {1, 0, 197, 115, 77},
// {1, 1, 197, 115, 77},
// {1, 2, 197, 115, 77},
// {2, 1, 197, 115, 77},
// {2, 0, 197, 115, 77},
// {2, 2, 197, 115, 77}, // 橙色
// {3, 0, 35, 29, 35},
// {4, 0, 214, 213, 218},
// {5, 0, 33, 30, 35},
// {6, 0, 177, 175, 176},
// {7, 0, 32, 29, 34}, // 第一层
// {4, 1, 31, 31, 35},
// {6, 1, 8, 7, 12},
// {8, 1, 33, 28, 34}, // 第二层
// {3, 2, 243, 193, 83},
// {4, 2, 238, 196, 101},
// {6, 2, 240, 194, 89},
// {5, 2, 234, 204, 151},
// {7, 2, 245, 197, 97},
// {8, 2, 250, 219, 116}, // 第三层
// {3, 3, 197, 31, 31},
// {4, 3, 252, 43, 36},
// {5, 3, 252, 218, 118},
// {6, 3, 254, 218, 118},
// {7, 3, 251, 171, 62},
// {8, 3, 251, 216, 121},
// {2, 4, 140, 137, 43},
// {3, 4, 212, 206, 212},
// {5, 4, 180, 177, 182},
// {6, 4, 255, 255, 255},
// {7, 4, 255, 255, 255},
// {8, 4, 255, 255, 255},
// {2, 5, 140, 137, 143},
// {3, 5, 255, 255, 255},
// {4, 5, 212, 206, 212},
// {6, 5, 255, 255, 255},
// {7, 5, 255, 255, 255},
// {8, 5, 180, 177, 182},
// {6, 6, 173, 145, 77}};
//pic_坤坤头像
void drawRGBpoint(uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b);
void drawPicXY(uint8_t x, uint8_t y, uint8_t (*information)[5], uint8_t num); // 图片位置坐标,信息二维数组,图片的像素个数
void drawPicSC(uint8_t (*information)[5], uint8_t num); // 图片位置坐标,信息二维数组,图片的像素个数
void AutodrawPicSC(uint8_t (*information)[5]);
void AutodrawPicXY(uint8_t x, uint8_t y, uint8_t (*information)[5]);
void numberFOUNT(uint8_t foundi, uint8_t loc, uint8_t r, uint8_t g, uint8_t b);
void show_2812();
void setup_2812();
void clear_2812();
#endif
时钟显示项目
#include <Arduino.h>
#include <Adafruit_NeoPixel.h> //关键是这个库
// #include <SPI.h>
#include <WiFi.h>
#include <sc2812.h>
const char *ssid = "Hebe";
const char *passwd = "2740931764";
/*===============================================================================*/
//--------------------------------------变量定义-----------------------------------------------//
int i = 0;
int counter;
//---------------------------------------开机动画-----------------------------------------------//
uint8_t information[][5] = {{0, 0, 100, 0, 0}, {1, 1, 0, 100, 0}, {2, 2, 0, 0, 100}, {3, 3, 200, 0, 0}, {4, 4, 0, 50, 0}, {5, 5, 0, 0, 200}, {6, 6, 100, 0, 100}, {7, 7, 100, 100, 0}};
//---------------------------------------time-----------------------------------------------//
const char *ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600;
const int daylightOffset_sec = 0;
int hour = 0;
int min_my = 0;
int count_my = 0;
//---------------------------------------函数定义-----------------------------------------------//
void showtime();
void printLocalTime();
/*===============================================================================*/
void setup()
{
Serial.begin(115200);
setup_2812();
//------------------开机动画------------//
for(i =0;i<=30;i++)
{
for(int j =0;j<=7;j++)
{
information[j][0] = information[j][0] +1;
}
clear_2812();
show_2812();
drawPicSC(information,8);
show_2812();
vTaskDelay(50);
}
for(i =30;i>=0;i--)
{
for(int j =0;j<=7;j++)
{
information[j][0] = information[j][0] -1;
}
clear_2812();
show_2812();
drawPicSC(information,8);
show_2812();
vTaskDelay(50);
}
//------------------开机动画------------//
WiFi.begin(ssid, passwd); // 连接网络
while (WiFi.status() != WL_CONNECTED) // 等待网络连接成功
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
Serial.println("IP address: ");
Serial.println(WiFi.localIP()); // 打印模块IP
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
}
void loop()
{
//-----------------------------------------------------------------------------///////////////////
clear_2812();
showtime();
show_2812();
vTaskDelay(1000);
}
void showtime()
{
printLocalTime();
numberFOUNT(hour/10, 0, 100,0, 50);
numberFOUNT(hour%10, 5, 100,0, 50);
numberFOUNT(min_my/10, 11, 0,100, 50);
numberFOUNT(min_my%10, 16, 0,100, 50);
numberFOUNT(count_my/10, 22, 0,50, 100);
numberFOUNT(count_my%10, 27, 0,50, 100);
show_2812();
counter++;
if(counter%2 ==0)
{
numberFOUNT(10, 20, 100,100,100);
numberFOUNT(10, 9, 100,100,100);
}
if(counter ==100) counter =0;
}
//-------------------------------------------------------------------------//
void printLocalTime()
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo))
{
Serial.println("Failed to obtain time");
return;
}
// Serial.println(&timeinfo, "%F %T %A"); // 格式化输出
hour = timeinfo.tm_hour;
min_my = timeinfo.tm_min;
count_my = timeinfo.tm_sec;
}
版权声明:
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
羽老板的心事!
喜欢就支持一下吧