932|0

33

帖子

4

TA的资源

一粒金砂(中级)

楼主
 

【DigiKey“智造万物,快乐不停”创意大赛】像素智能时钟-完结帖子 [复制链接]

 
像素智能时钟
作者: 老杰瑞
一、作品简介
本作品是基于esp32-Arduino开发的像素时钟,使用AWTRIX的服务器进行自定义数据显示。
作品原计划采用Seeed Studio XIAO ESP32C3作为主控,但因为遇到了在能力范围内修复不了的bug,最终采用esp32-worrm-32作为主控,Seeed Studio XIAO ESP32C3作为副主控进行手势识别读取传给主控。作品采用高质量的ws2812像素化显示屏,通过细小的LED像素点来呈现时间和其他相关信息,通过bmp250作为温度检测的模块,光敏电阻进行室内光强的测量。Esp32进行屏幕驱动和温度光强检测,再将数据回传服务器,由服务器下发显示的数据,进行数据显示。服务器使用树莓派4b进行搭建,与esp32通过mqtt协议进行通信,该项目为时钟项目,实现的时间显示,动画显示,也可以通过服务器设置显示相关api数据,扩展性强,可在网页端制作自定义动画和显示,能在日常生活中提供显示和装饰作用。通过修改上位机脚本,能实现多种自定义功能。
作品照片:
项目用到的板卡、芯片、模块等介绍:
Esp32 wroom-32开发板 和Seeed Studio XIAO ESP32C3开发板·、树莓派4b
Ws2812矩阵灯带,paj7650手势传感器,bp510温度模块,触摸模块
作品功能介绍:
作品分为服务器端和显示端,树莓派4b跑AWTRIX的服务器,esp32跑屏幕显示和触摸、手势、温度数据收集
图一:显示端
图二:服务器端
  1. 系统框图(图文结合)
    硬件框架:
图三:硬件框架
设esp32-worrm-32作为主控,负责灯带显示和温度,触摸模块数据收集,esp32-c3负责收集手势传感器数据发给主控模拟触摸信号。树莓派4b跑AWTRIX服务器,与主控通过局域网进行mqtt连接传输显示数据。.
软件框架:
图四:软件框架
三、各部分功能说明(图文结合)
代码用vs+pio+arduino的框架进行编写

像素矩阵驱动代码:

使用FastLED和Adafruit_GFX库来驱动ws2812 LED矩阵
参考链接:
链接已隐藏,如需查看请登录或者注册
#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <FastLED.h>
#include <FastLED_NeoMatrix.h>
#include <Fonts/TomThumb.h>
class Matrix
{
private:
int type;
int tempCorrection;
#define NUMBER_LED = 256;
#ifdef ESP8266
#define MATRIX_PIN = D2;
#else
#define MATRIX_PIN = 15;
#endif
enum MsgType {
MsgType_Wifi,
MsgType_Host,
MsgType_Temp,
MsgType_Audio,
MsgType_Gest,
MsgType_LDR,
MsgType_Other
};
CRGB leds[256];
FastLED_NeoMatrix *matrix;
void hardwareAnimatedUncheck(int typ, int x, int y);
void hardwareAnimatedCheck(MsgType typ, int x, int y);
public:
void init(int type, int tempCorrection);
void setTempCorrection(int tempCorrection);
void setType(int type);
void hardwareCheck();
void serverSearch(int rounds, int typ, int x, int y);
void hardwareAnimatedSearch(int typ, int x, int y);
void setTextToMatrix(bool clear, byte red, byte green, byte blue, int xPos, int yPos, String text);
void flashProgress(unsigned int progress, unsigned int total);
void fillScreen(byte red, byte green, byte blue);
void drawPixel(uint16_t x_coordinate, uint16_t y_coordinate, uint16_t data);
void drawPixel(uint16_t x_coordinate, uint16_t y_coordinate, byte red, byte green, byte blue);
void clear();
void setBrightness(byte brightness);
void setCursor(uint16_t x, uint16_t y);
uint16_t getCursorX();
uint16_t getCursorY();
void print(String text);
void setTextColor(byte red, byte green, byte blue);
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, byte red, byte green, byte blue);
void drawRect(uint16_t x0, uint16_t y0, uint16_t width, uint16_t height, byte red, byte green, byte blue);
void fillRect(uint16_t x0, uint16_t y0, uint16_t width, uint16_t height, byte red, byte green, byte blue);
void drawCircle(uint16_t x0, uint16_t y0, uint16_t radius, byte red, byte green, byte blue);
void fillCircle(uint16_t x0, uint16_t y0, uint16_t radius, byte red, byte green, byte blue);
private:
uint32_t Wheel(byte WheelPos, int pos);
};

 

在主函数中只要配置FastLED,根据LED矩阵(WS2812)
配置FastLED库,设置LED数量和连接的Arduino引脚
创建Adafruit_GFX兼容类,通过创建的类,你可以使用Adafruit_GFX提供的所有标准图形函数,如drawLine(), drawCircle(), fillRect()等。
这些函数最终会调用drawPixel()方法来在LED矩阵上绘制图形。
最后使用FastLED的show()方法来更新LED矩阵的显示。

网络配置

在网络配置方面直接使用了WiFiManager库在esp32上创建和管理WiFi连接的一部分。它主要负责设置和配置WiFi连接参数,以及为用户提供一个配置界面,用于输入和管理这些参数。
// 设置 WiFiManager 的回调函数和参数
wifiManager.setAPStaticIPConfig(IPAddress(172, 217, 28, 1), IPAddress(172, 217, 28, 1), IPAddress(255, 255, 255, 0));
//WiFiManager 创建的访问点(AP)配置为使用静态 IP 地址 172.217.28.1,默认网关也设置为相同的 IP 地址,并且使用子网掩码 255.255.255.0。
WiFiManagerParameter custom_awtrix_server("server", "AWTRIX Host", awtrix_server, 16);
//创建一个参数对象 custom_awtrix_server,并将其关联到 AWTRIX 服务器的主机名或 IP 地址。当用户使用设备时,可以通过配置界面输入 AWTRIX 服务器的地址,该地址将被存储在 awtrix_server 数组中,
// 其他WiFiManager参数设置,包括服务器地址、端口和矩阵类型等
WiFiManagerParameter custom_port("Port", "Matrix Port", Port, 6);
//创建一个参数对象 custom_port,并将其关联到 Matrix 端口号
WiFiManagerParameter custom_matrix_type("matrixType", "MatrixType", "0", 1);
//创建一个参数对象 custom_matrix_type,并将其关联到 Matrix 类型。用户可以在配置界面中选择 Matrix 的类型,这个选择将被存储为一个字符(通常是数字)
WiFiManagerParameter host_hint("<small>AWTRIX Host IP (without Port)<br></small><br><br>");
//创建一个提示信息的参数对象 host_hint,它将在配置界面中显示帮助用户理解如何配置 AWTRIX 服务器的主机名或 IP 地址。这对于向用户提供清晰的配置说明非常有用。提示信息将以 HTML 的形式呈现,以便更好地格式化和显示在配置界面中。
WiFiManagerParameter port_hint("<small>Communication Port (default: 7001)<br></small><br><br>");
//创建了一个名为 port_hint 的参数对象,用于提供用户在配置界面中输入通信端口号的提示信息。提示信息是 "Communication Port (default: 7001)",它告诉用户可以在这里输入通信端口号,并且提供了默认值为 7001。
WiFiManagerParameter matrix_hint("<small>0: Columns; 1: Tiles; 2: Rows <br></small><br><br>");
//创建了一个名为 matrix_hint 的参数对象,用于提供用户在配置界面中选择 Matrix 类型的提示信息。提示信息列出了三种选项(0: Columns; 1: Tiles; 2: Rows),并告诉用户可以在这里选择 Matrix 类型。
WiFiManagerParameter p_lineBreak_notext("<p></p>");
//创建一个分隔线
wifiManager.setSaveConfigCallback(saveConfigCallback);
wifiManager.setAPCallback(configModeCallback);
wifiManager.addParameter(&p_lineBreak_notext);
wifiManager.addParameter(&host_hint);
wifiManager.addParameter(&custom_awtrix_server);
wifiManager.addParameter(&port_hint);
wifiManager.addParameter(&custom_port);
wifiManager.addParameter(&matrix_hint);
wifiManager.addParameter(&custom_matrix_type);
wifiManager.addParameter(&p_lineBreak_notext);
在时钟第一次启动的时候会进wifi配网的模式,也可以在时钟开机显示boot画面的时候按特定按键重置网络状态
// 检测按钮状态,当按钮按下时进行重置
// 当数字引脚15为高电平时,执行以下循环
//清除数据
while (!digitalRead(0))
{
// 如果变量zahl发生变化,则更新显示屏的内容
if (zahl != zahlAlt)
{
matrix->clear();// 清除屏幕
matrix->setTextColor(matrix->Color(255, 0, 0));// 设置文字颜色为红色
matrix->setCursor(6, 6);// 设置光标位置
matrix->print("RESET ");// 打印文本“RESET”
matrix->print(zahl);// 打印变量zahl的值
matrix->show();// 显示内容
zahlAlt = zahl;// 更新zahlAlt的值为zahl的当前值
}
// 更新变量zahl的值,它与启动时间有关
zahl = 5 - ((millis() - zeit) / 1000);
// 如果计时器归零,执行重置操作
if (zahl == 0)
{
// 以下代码块用于重置设备的WiFi设置和配置文件
// 清除屏幕并显示“RESET!”
matrix->clear();
matrix->setTextColor(matrix->Color(255, 0, 0));
matrix->setCursor(6, 6);
matrix->print("RESET!");
matrix->show();
delay(1000);
// 如果 LittleFS 初始化成功,删除配置文件
if (LITTLEFS.begin())
{
delay(1000);
LITTLEFS.remove("/awtrix.json");
LITTLEFS.end();
delay(1000);
}
// 重置 WiFi 设置
wifiManager.resetSettings();
Serial.println("重置 WiFi 设置");
//ESP.reset();
}
}
// 如果无法连接 WiFiManager 自动连接热点
if (!wifiManager.autoConnect("AWTRIX Controller", "awtrixxx"))
{
//reset and try again, or maybe put it to deep sleep
//ESP.reset();
delay(5000);
}
与服务器通信
这部分代码直接使用了awtrix的代码,作者能力有限,只在按键操作方面进行了修改,适配手势操作
//is needed for the server search animation
// 处理 Arduino OTA
if (firstStart && !ignoreServer)
{
// 每500毫秒执行一次服务器搜索动画
if (millis() - myTime > 500)
{
serverSearch(myCounter, 0, 28, 0);
myCounter++;
if (myCounter == 4)
{
myCounter = 0;
}
myTime = millis();
}
}
//not during the falsh process
// 如果不处于更新过程中
if (!updating)
{
// 如果是USB连接或首次启动
if (USBConnection || firstStart)
{
int x = 100;
while (x >= 0)
{
x--;
//USB
if (Serial.available() > 0)
{
//read and fill in ringbuffer
// 读取并填充环形缓冲区
myBytes[bufferpointer] = Serial.read();
messageLength--;
for (int i = 0; i < 14; i++)
{
if ((bufferpointer - i) < 0)
{
myPointer[i] = 1000 + bufferpointer - i;
}
else
{
myPointer[i] = bufferpointer - i;
}
}
//prefix from "awtrix" == 6?
// 前缀是 "awtrix" 吗
if (myBytes[myPointer[13]] == 0 && myBytes[myPointer[12]] == 0 && myBytes[myPointer[11]] == 0 && myBytes[myPointer[10]] == 6)
{
//"awtrix" ?
if (myBytes[myPointer[9]] == 97 && myBytes[myPointer[8]] == 119 && myBytes[myPointer[7]] == 116 && myBytes[myPointer[6]] == 114 && myBytes[myPointer[5]] == 105 && myBytes[myPointer[4]] == 120)
{
messageLength = (int(myBytes[myPointer[3]]) << 24) + (int(myBytes[myPointer[2]]) << 16) + (int(myBytes[myPointer[1]]) << 8) + int(myBytes[myPointer[0]]);
SavemMessageLength = messageLength;
awtrixFound = true;
}
}
// 如果找到 "awtrix" 并且消息长度为0
if (awtrixFound && messageLength == 0)
{
byte tempData[SavemMessageLength];
int up = 0;
for (int i = SavemMessageLength - 1; i >= 0; i--)
{
if ((bufferpointer - i) >= 0)
{
tempData[up] = myBytes[bufferpointer - i];
}
else
{
tempData[up] = myBytes[1000 + bufferpointer - i];
}
up++;
}
USBConnection = true;
updateMatrix(tempData, SavemMessageLength);
awtrixFound = false;
}
bufferpointer++;
if (bufferpointer == 1000)
{
bufferpointer = 0;
}
}
else
{
break;
}
}
}
//Wifi
if (WIFIConnection || firstStart)
{
//Serial.println("wifi oder first...");
// 如果未连接到服务器,重新连接
if (!client.connected())
{
//Serial.println("nicht verbunden...");
reconnect();
if (WIFIConnection)
{
USBConnection = false;
WIFIConnection = false;
firstStart = true;
}
}
else
{
client.loop();
}
}
// 如果连接超时,重置连接状态
if (millis() - connectionTimout > 20000)
{
USBConnection = false;
WIFIConnection = false;
firstStart = true;
}
}
checkTaster(0);
checkTaster(1);
checkTaster(2);
checkTouchButtons();
//checkTaster(3);
//is needed for the menue...
// 如果忽略服务器,显示菜单
if (ignoreServer)
{
if (pressedTaster > 0)
{
matrix->clear();
matrix->setCursor(0, 6);
matrix->setTextColor(matrix->Color(0, 255, 50));
//matrix->print(myMenue.getMenueString(&menuePointer, &pressedTaster, &minBrightness, &maxBrightness));
matrix->show();
}
//get data and ignore
// 获取数据并忽略
if (Serial.available() > 0)
{
Serial.read();
}
}

 

完整代码见附件,全部有点大,就不放出来了

4原理图

图5:原理图
由于只做了一块板子,就用洞洞板进行飞线完成了电路板的制作,节省成本

5屏幕显示方式

图6:屏幕图
为了匀光效果,在ws2812的矩阵屏幕上,3d打印了一份光栅板进行隔光,防止显示太花再购买了硫酸纸,安装在光栅板上进行匀光,使得显示均匀
图7:无硫酸纸效果
图8:有硫酸纸效果

6服务器端

使用树莓派4b安装了awtrix服务器,给树莓派配了个120块钱的屏幕和25块钱的支架,放桌面上可以当作linux主机使用
图9:树莓派服务器
  1. 作品源码
在审核 下载链接粘贴到作品文档和作品提交帖中)
代码.zip (72.43 MB, 下载次数: 1)
五、作品功能演示视频
功能演示:
d7c7c25a328d4beac1a5709b9cf877c2

 
六、项目总结
感谢得捷电子提供的元器件支持,在这次项目实现过程中学习到了很多,以前只玩过stm32和51单片机。这次第一次玩上了esp32和pio上的arduino开发。
在代码移植,库的适配上遇到了很多很多bug,也在一步一步的学习中逐渐搞定。
本次的项目其实还有很大的完善空间,下次再搞像素时钟的话,我的显示灯会更换spi控制的apa201来,这样就不会收到中断和WiFi的影响了,还有显示效果,现在依然还不能脱离awtrix服务器运行,今后会自己写出离线版本的像素时钟,还有一个遗憾是准备了功放和喇叭,由于期末周时间太紧还没有集成上去,想加音乐频谱的功能和蓝牙播放。以后还要继续完善,fastled库是真的牛皮,学习过程中受益匪浅。
感谢EEWorld提供本次创意大赛的机会,衷心祝愿EEWorld也会越办越好
.
word文档 【DigiKey“智造万物,快乐不停”创意大赛】像素智能时钟-完结帖子-格式.doc (10.68 MB, 下载次数: 5)
点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
寻迹小车设计

一. 起因、目标及车体设计 一、 概述以自制方式为主制作一辆低成本的寻迹小车,用于学习嵌入式应用(单片机),这个项目有两 ...

一个老外写的DDS(VHDL)的例子,很经典

-- DDFS.vhd ------------------------------------- -- Direct Digital Freq. Synthesis -- ------------------------------ ...

示波器V2.0调试过程贴(定期更新)

本人主要负责软件的开发,硬件由FLT9006负责,板已做好,汤汤已经把板发到我手上,现在开始全面调试工作 前天收到包裹,包括 ...

大学堂之系统初始化及时钟配置

本文主要介绍MSP430G2231的内部时钟结构,采用Grace进行该单片机的时钟配置为例,并介绍如何将Grace生成的初始化代码移植到IAR f ...

LCD单层菜单翻滚的实现

在很多项目中我们都需要菜单,特别是多层菜单应用比较广泛,但是写一个能够很方便移植的多层菜单非常麻烦,我们这里就先研究一下 ...

RC π型滤波电阻和电容的取值-------

RC π型滤波电阻和电容的取值------- 有人说按将经验取值,2πfR或者2πfc或者2πfl小于(开关频率1M)*1/5或者1/1 ...

示波器测量微弱信号放大时,人体经过示波器或者放大电路或者信号源,波形会波动

对uv级别直流信号进行放大,放大之后,感觉十分容易受到干扰。 已经共低5了

上海航芯 ACM32F070开发板+触控功能评估板评估 - 第三篇 时钟和温度显示界面

本测评实验使用RTC获取实时时间,使用I2C从板载传感器获取温度数据,将时间和温度像是在LCD屏幕上。 代码实现主要参考了S ...

【2022得捷电子创新设计大赛】-智能电子称重系统

一、功能概况 ESP32S2: 1、是基于CircuitPython语言开发 2、自带LCD屏,驱动LCD屏,输出信息 3、连接HX711称重计量 ...

【NUCLEO H533RE】USB串口CDC-ACM设备栈

测试介绍 CDC-ACM(Communication Device Class——Abstract Control Model)串口设备为一种通用串口设备,属于ACM ...

关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表