本帖最后由 POMIN 于 2023-5-18 15:39 编辑
鲁班猫创意大赛参赛项目——基于鲁班猫0的满血版AWTRIX时钟,基于鲁班猫0的开发板,搭配ESP8266制作该项目。 硬件组成部分框图开发步骤
官方在2022的八月份停止了更新,不过硬件连接图、代码都已经开源,服务器端也公开了jar包,源码没有开源。 复刻AWTRIX硬件直接用核心板,连接一下各种模块,用立创eda画一个底板。 简单布线一下pcb。 AWTRIX时钟使用的灯光板淘宝可以买到,但是比较大,重新画了个灯光板来缩小面积。 自制灯光板PCB256个灯珠、256个104电容 固件修改焊一焊已经到货的底板 把模块插上,拧上铜柱 由于体积较大,3D打印比较费材料(其实是比较费钱),就买了个25*7*7cm尺寸的木盒子。 灯光板到了开始组装AWTRIX控制端。 灯光板到了才发现AWTRIX时钟使用的灯光板和我画的灯板扫描顺序不太一样,固件需要修改。
我画的的扫描顺序:
原版的扫描顺序:
查阅 AWTRIX 的代码可以看到采用的是 FastLED_NeoMatrix 这个库,这个库是用 C++ 写的库,不过代码结构比较清晰,找出画点的函数 FastLED_NeoMatrix::drawPixel,函数实现如下 - void FastLED_NeoMatrix::drawPixel(int16_t x, int16_t y, uint16_t color) {
- if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return;
- _leds[XY(x,y)] = passThruFlag ? passThruColor : expandColor(color);
- }
复制代码其中 XY(x,y) 函数就是把屏幕的坐标点转换为_leds数组的索引,跳到XY(x,y)函数中查看。
- int FastLED_NeoMatrix::XY(int16_t x, int16_t y) {
- // Beware, this returns a special out of bounds value, you need an extra
- // safety pixel at the end of your array to host this, or if you use
- // drawPixel, the value willl get rejected.
- if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return numpix-1;
- int16_t t;
- switch(rotation) {
- case 1:
- t = x;
- x = WIDTH - 1 - y;
- y = t;
- break;
- case 2:
- x = WIDTH - 1 - x;
- y = HEIGHT - 1 - y;
- break;
- case 3:
- t = x;
- x = y;
- y = HEIGHT - 1 - t;
- break;
- }
- int tileOffset = 0, pixelOffset;
- if(remapFn) { // Custom X/Y remapping function
- pixelOffset = (*remapFn)(x, y);
- } else { // Standard single matrix or tiled matrices
- uint8_t corner = type & NEO_MATRIX_CORNER;
- uint16_t minor, major, majorScale;
- if(tilesX) { // Tiled display, multiple matrices
- uint16_t tile;
- minor = x / matrixWidth; // Tile # X/Y; presume row major to
- major = y / matrixHeight, // start (will swap later if needed)
- x = x - (minor * matrixWidth); // Pixel X/Y within tile
- y = y - (major * matrixHeight); // (-* is less math than modulo)
- // Determine corner of entry, flip axes if needed
- if(type & NEO_TILE_RIGHT) minor = tilesX - 1 - minor;
- if(type & NEO_TILE_BOTTOM) major = tilesY - 1 - major;
- // Determine actual major axis of tiling
- if((type & NEO_TILE_AXIS) == NEO_TILE_ROWS) {
- majorScale = tilesX;
- } else {
- _swap_uint16_t(major, minor);
- majorScale = tilesY;
- }
- // Determine tile number
- if((type & NEO_TILE_SEQUENCE) == NEO_TILE_PROGRESSIVE) {
- // All tiles in same order
- tile = major * majorScale + minor;
- } else {
- // Zigzag; alternate rows change direction. On these rows,
- // this also flips the starting corner of the matrix for the
- // pixel math later.
- if(major & 1) {
- corner ^= NEO_MATRIX_CORNER;
- tile = (major + 1) * majorScale - 1 - minor;
- } else {
- tile = major * majorScale + minor;
- }
- }
- // Index of first pixel in tile
- tileOffset = tile * matrixWidth * matrixHeight;
- } // else no tiling (handle as single tile)
- // Find pixel number within tile
- minor = x; // Presume row major to start (will swap later if needed)
- major = y;
- // Determine corner of entry, flip axes if needed
- if(corner & NEO_MATRIX_RIGHT) minor = matrixWidth - 1 - minor;
- if(corner & NEO_MATRIX_BOTTOM) major = matrixHeight - 1 - major;
- // Determine actual major axis of matrix
- if((type & NEO_MATRIX_AXIS) == NEO_MATRIX_ROWS) {
- majorScale = matrixWidth;
- } else {
- _swap_uint16_t(major, minor);
- majorScale = matrixHeight;
- }
- // Determine pixel number within tile/matrix
- if((type & NEO_MATRIX_SEQUENCE) == NEO_MATRIX_PROGRESSIVE) {
- // All lines in same order
- pixelOffset = major * majorScale + minor;
- } else {
- // Zigzag; alternate rows change direction.
- if(major & 1) pixelOffset = (major + 1) * majorScale - 1 - minor;
- else pixelOffset = major * majorScale + minor;
- }
- }
- return(tileOffset + pixelOffset);
- }
复制代码
这段代码就是根据当前的旋转方向等信息来计算偏移从而确定其索引。 其中有很重要的一行代码 - if(remapFn) { // Custom X/Y remapping function
- pixelOffset = (*remapFn)(x, y);
- }
复制代码
这行代码调用了一个回调函数,通过回调函数可以实现对于计算数组索引方法的自定义 我画的屏幕是横S形状的扫描方式,简单数学计算可以得到坐标和索引的变换关系为: y 为偶数时 index = 32 y;
y 为奇数时 index = 32 y + 31 - x; 写一个转换函数 - uint16_t remapDisp(uint16_t x, uint16_t y) {
- if (y % 2) {
- return (32 * y + x);
- } else {
- return (32 * y + (31 - x));
- }
- }
复制代码
然后初始化函数 matrixInit 中添加一行注册代码,注册到XY函数的回调 - matrix->setRemapFunction(remapDisp);
复制代码
用 VSCode 中的 PIO 插件编译一下 烧录到ESP8266接上控制板,正常点亮。 PS:灯光板的大小超了这个木盒子,把四个角切掉,飞线解决;栅格板是用fashion360画,3D打印的,均光板直接剪的A4纸。 鲁班猫网络配置先把鲁班猫设置为静态地址,这里使用 nmtui 工具来设置,静态 IP 为 192.168.0.150,网关地址为 192.168.0.1,DNS 地址为 114.114.114.114 安装 JAVA环境直接用 apt 工具安装即可,安装完成后使用 java --version 命令查看版本信息,查看是否安装成功。 - apt install openjdk-11-jdk
复制代码
注册 AWTRIX 为 service编写一个 awtrix.service 文件 - [Unit]
- Description=AWTRIX HOST
- After=network.target
- [Service]
- WorkingDirectory=/root/awtrix/
- Type=simple
- ExecStart=/usr/bin/java -jar /root/awtrix/awtrix.jar
- Restart=always
- RestartSec=3
- [Install]
- WantedBy=multi-user.target
复制代码
复制到 /etc/systemd/system/ 文件夹中,设置开机自动启动并打开服务 - cp awtrix.service /etc/systemd/system/
- systemctl enable awtrix
- systemctl start awtrix
复制代码
AWTRIX 控制器连接到服务器AWTRIX 时钟上电后进入 HOSTPOD 模式,设置 AWTRIX 的 Wi-Fi 和服务器 IP,服务器IP设置为 192.168.0.150 至此,鲁班猫作为 AWTRIX 的服务器已经搭建完成了。 安装 EMQX执行如下命令安装即可 - curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash
- apt install emqx
复制代码
设置 nginx 反向代理记 IP太麻烦,用 nginx 设置反向代理来访问awtrix服务端
改写 nginx的网站配置文件 - nano /etc/nginx/sites-available/default
复制代码
改写为如下内容 - map $http_upgrade $connection_upgrade {
- default upgrade;
- '' close;
- }
- server{
- listen 80;
- server_name awtrix.lubancat.dev;
- index index.php index.html index.htm;
- location / {
- proxy_pass http://127.0.0.1:7000;
- proxy_set_header Host $proxy_host;
- proxy_http_version 1.1;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection $connection_upgrade;
- }
- }
- server{
- listen 80;
- server_name mqtt.lubancat.dev;
- index index.php index.html index.htm;
- location / {
- proxy_pass http://127.0.0.1:18083;
- proxy_set_header Host $proxy_host;
- proxy_http_version 1.1;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection $connection_upgrade;
- }
- }
复制代码
用 SwitchHosts 修改一下 hosts 文件,设置 awtrx.lubancat.dev 和 mqtt.lubancat.dev 解析到 192.168.0.150,实现 emqx 的后台通过 mqtt.lubancat.dev 访问,AWTRIX 服务器后台通过 awtrx.lubancat.dev 来访问 组装 AWTRIX 所有硬件使用 Type-C 转 Mirco USB 的线将鲁班猫和ESP8266连接在一起,使用 Type-C转 Type-C的线将鲁班猫的电源连接到主板的侧面电源接口上面,喇叭、触摸按键屏幕连接到主板上面 全都连接好: 然后安装一些 APP 点亮 AWTRIX 时钟可以查看温度、湿度和时间、当前度过了一年的百分之多少 也可以自定义显示内容 也可以显示打篮球的动画 查看设备端的状态 查看服务器端的状态 项目总结用ESP8266和鲁班猫复刻了国外曾经很火的AWTRIX像素时钟,简单的外观,超强的“心脏”,得益于鲁班猫0的强大性能,可以完美的平替原项目作为服务器主机使用的树莓派,富余的性能还可以用来安装Alist、EMQX、ADguard、ESP Home、Home Assistant等应用,可玩性极高。 [size=0em]
|