芯查查logo
  • 物料选型
  • 数据服务
    1. 新产品
    2. 查替代
    3. 丝印反查
    4. 查品牌
    5. PCN/PDN
    6. 查方案
    7. 查代理
    8. 数据合作
  • SaaS/方案
      SaaS产品
    1. 供应链波动监测预警
    2. 半导体产业链地图
    3. BOM管理
    4. 解决方案
    5. 汽车电子
    6. 政府机构
    7. 数据API
  • 商城
  • 行业资讯
    1. 资讯
    2. 直播
  • 论坛社区
    1. 论坛
    2. 学习
    3. 测评中心
    4. 活动中心
    5. 积分商城
  • 查一下
野火电子-尹桢
【鲁班猫参赛作品赏析】7-基于鲁班猫0满血版AWTRIX时钟

今日跟大家分享下鲁班猫参赛项目——基于鲁班猫0的满血版AWTRIX时钟,基于鲁班猫0的开发板,搭配ESP8266制作该项目。

硬件组成部分框图

 

实验步骤

 

1、复刻 AWTRIX 时钟硬件

AWTRIX时钟的官方网站:

 https://awtrixdocs.blueforcer.de/#/en-en/

 

 

 

官方在2022的八月份停止了更新,不过硬件连接图、代码都已经开源,服务器端也公开了jar包,源码没有开源。

 

官网的PCB网站: https://awtrixdocs.blueforcer.de/#/en-en/pcb

 

直接用核心板,连接一下各种模块,用立创eda画一个底板。

 

 

 

具体管脚信息在代码中可以看到,代码地址:https://github.com/awtrix/AWTRIX2.0-Controller

 

 

简单布线一下pcb。

 

 

实物图

 

 

焊接好底板后,把模块插上,拧上铜柱

 

 

2、画AWTRIX 灯光板和“定制外壳”

 

AWTRIX时钟使用的灯光板淘宝可以买到,但是比较大,重新画了个灯光板来缩小面积。此灯光板 256个灯珠、256个104电容

 

 

灯光板到了才发现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接上控制板,正常点亮。

 

 

对于外壳,由于体积较大,3D打印比较费材料(其实是比较费钱),就买了个25*7*7cm尺寸的木盒子。

 

 

PS:灯光板的大小超了这个木盒子,把四个角切掉,飞线解决;栅格板是用fashion360画,3D打印的,均光板直接剪的A4纸。

 

 

 


3、安装AWTRIX server

 

  • 鲁班猫网络配置

 

先把鲁班猫设置为静态地址,这里使用 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.targe

                                                                                                                                                                                  

 

复制到 /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 来访问

 

 

4、组装 AWTRIX 所有硬件

 

使用 Type-C 转 Mirco USB 的线将鲁班猫和ESP8266连接在一起,使用 Type-C转 Type-C的线将鲁班猫的电源连接到主板的侧面电源接口上面,喇叭、触摸按键屏幕连接到主板上面

 

 

全都连接好:

 

 

将 AWTRIX 服务器设置为串口连接到控制器,可以实现稳定不掉线的显示,这里连接到鲁班猫的串口为 /dev/ttyUSB0,MQTT 服务器为本地地址127.0.0.1,端口1883,AWTRIX 也提供了 MQTT 的 api,说明文档:https://awtrixdocs.blueforcer.de/#/en-en/api

 

 

然后安装一些APP

 

 

项目功能展示

 

可以查看温度、湿度和时间、当前度过了一年的百分之多少

 

 

可以自定义显示内容

 

 

可以显示打篮球的动画

 

 

查看设备端的状态

 

 

查看服务器端的状态

 

 

 

项目总结

 

用ESP8266和鲁班猫复刻了国外曾经很火的AWTRIX像素时钟,简单的外观,超强的“心脏”,得益于鲁班猫0的强大性能,可以完美的平替原项目作为服务器主机使用的树莓派,富余的性能还可以用来安装Alist、EMQX、ADguard、ESP Home、Home Assistant等应用,可玩性极高(注:项目相关资料可在原帖6下载)


 

相关帖子链接

 

1. 鲁班猫0.无线版开箱,惊艳

 

https://bbs.elecfans.com/jishu_2346808_1_1.html

 

2. 鲁班猫0 复刻 AWTRIX 时钟硬件

 https://bbs.elecfans.com/jishu_2348197_1_1.html

 

3. 鲁班猫0 AWTRIX 灯光板和“定制外壳”

 https://bbs.elecfans.com/jishu_2349201_1_1.html

 

4. 鲁班猫0 AWTRIX 控制端固件修改烧录 

 https://bbs.elecfans.com/jishu_2350764_1_1.html

 

5. 鲁班猫0 安装AWTRIX server 

 https://bbs.elecfans.com/jishu_2353403_1_1.html

 

6. 项目结项

  https://bbs.elecfans.com/jishu_2353448_1_1.html

 

开源社区
版块: 野火
2023/09/18 16:20
  • 举报
😁😂😃😄😅😆😉😊😋😌😍😏😒😓😔😖😘😚😜😝😞😠😡😢😣😤😥😨😩😪😫😭😰😱😲😳😵😷😸😹😺😻😼😽😾😿🙀🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏✂✅✈✉✊✋✌✏✒✔✖✨✳✴❄❇❌❎❓❔❕❗❤➕➖➗➡➰🚀🚃🚄🚅🚇🚉🚌🚏🚑🚒🚓🚕🚗🚙🚚🚢🚤🚥🚧🚨🚩🚪🚫🚬🚭🚲🚶🚹🚺🚻🚼🚽🚾🛀Ⓜ🅰🅱🅾🅿🆎🆑🆒🆓🆔🆕
@好友

全部评论

加载中
游客登录通知
已选择 0 人
自定义圈子
移动
发布帖子
发布动态
发布问答
最新帖子
【星允派 NEBULA PI】09:USB虚拟CDC与串口1【星允派 NEBULA PI】15:高级定时器输出PWM【星允派 NEBULA PI】14:使用DMA方式读取ADC【有奖话题35期】明明硬件比软件难,但为什么待遇还不如软件?【星允派 NEBULA PI】12:添加时间任务调度器
热门版块
查看更多
问型号
问技术
问行情
电子DIY
汽车电子工程师论坛
工业电子专区
新手入门指南
单片机/MCU论坛
PCB设计
开源项目

2

收藏

分享

微信扫码
分享给好友

评论