Funpack第12期-基于Wio terminal的健康守护主题传感器试验
本项目为读取并显示传感器数据专题,在项目中将使用Seeed公司的Wio terminal作为主机连接温湿度、红外温度、超声测距、Tof激光测距传感器,完成家居环境及日常体温检测功能。
标签
嵌入式系统
显示
wio terminal
Funpack第12期
genvex
更新2021-12-30
1267

(一)前言

    在项目中将使用Seeed公司的Wio terminal作为主机连接温湿度、红外温度、超声测距、Tof激光测距传感器,完成家居环境及日常体温采集检测功能。下面将针对实施过程中主要解决的几个问题展开讨论,作为以Wio terminal为主控的创意应用开发的一次积极的探索。

(二)主要内容

  • 1.图像界面工具的选择

   说到嵌入式系统的界面设计,当下炙手可热的工具当属LvgL (Light and Versatile Graphics Library),可以开发出跟手机端类似操作界面,暂时还没涉足,后面适当时机选择正确的打开方式。本项目中还是考虑用相对传统的方法来完成简单UI界面的设计。Wio 新手教程中推荐使用的TFT_eSPI,这里顺便把近年的这些彩屏显示的驱动扒一下。

   首先Adafruit 公司提供AdafruitGFX 图形库,于2012年发布,至今仍是个相当好用的图形库,仍在维护更新,工作模式就是 AdafruitGFX + 屏幕的驱动,所以可以支撑市面上99%的屏幕,特点是全能,兼容各种mcu平台及屏幕硬件,经过长期考验性能稳定。

   第二个好评的彩屏驱动是TFT_eSPI,主要兼容Arduino 及 PlatformIO IDE平台 TFT库,支持驱动芯片包括刚出现不久的Raspberry Pi Pico (RP2040),常见的 STM32, ESP8266和ESP32 芯片,该库在 GitHub上保持活跃地更新,所以可靠性、专业性比较有保证,因此,Seeed Wio terminal 主推这个显示驱动;

     第三个是本项目是所使用的LovyanGFX库, 看起来很小众的样子。在玩耍M5stack的产品过程中偶尔窥探关于LovyanGFX大神的一点点信息,据说是个超级宅男,可以理解呀,不在家苦练杀敌本领,哪里来的科研成果。在大神在github项目中致敬AdafruitGFX 和TFT_eSPI ,说TFT_eSPI很棒,但结构有点复杂,所以功能很难拓展,所以对它进行了深度功能拓展及优化,如支持ESP-IDF的开发。从库的内容看来LovyanGFX 是TFT_eSPI的魔改版。另外,LovyanGFX专门对M5Stack及Wio terminal作过优化,里面各种骚操作等待大家去发掘。经过一个月来的使用感受来看,该库确实是功能很强大,使用了函数重载的方法对TFT_eSPI的功能进行了纵深的改造(假装能看懂的样子),但是即使一个成熟的库,刚上手也是会有各种问题,只能是在爬坑中锻炼坚强的意志。最后感觉,在可选的条件下还是会优先选择这个图形支持库。

     从这个脉络关系看来这三个库是相通的,只要学会了其中一种是其他两个也自然会了。下图为这三个库的一些简单信息汇报,具体可以在Arduino下载数据包,按照提供的例程进行学习。

 

   图1. GFX屏幕驱动库简介

  • 2.传感器组装

    本项目主要用到的疫情主题&人文健康题材的传感器红外测温传感器、ToF测距传感器、温湿度传感器。选择M5stack公司的传感器是因为它们颜值比较高,外形一致,组合起来比较好看(还有很多传感器没出场机会)。这三个传感器都是由经I2C接口连接的,所以用一个Hub就可以把它们并连到wio terminal的I2C的grove端口上。另外,手上正好有个电池盒和可以兼容乐高材料可以为wio提供离线电源,把传感器用乐高配件组合起来,这样就可以脱离电脑,到处游走,省去了购买一个原装wio电池底座的费用,使用到的材料参见下图。

图2.传感器组装示意图

Ft5boUMdEhKk6LPS-LHB8HPfQCDW

图3.组装实物及程序欢迎页

   读取这三个传感器难度不大,因为都是成熟的传感器,支持的驱动库有很多选择,上机测试下即可完成,但每个传感器都有很深奥的驱动原理,能把一个传感器学习透了,也不错呀,因为我们不缺调包侠,硬件驱动这些硬骨头可能工资更高。本项目不涉及传感器硬件驱动,主要工作量体现在界面的设计上,做一个稍微好看一点居家摆件,提升逼格,深入学习一下LovyanGFX 这个图形库的使用技巧。在此没有将程序代码全部贴出,只将核心关键的函数列出,供讨论分析。

  • 3.界面切换

    设置按键3为中断功能关联界面切换函数。

void setup()
{
....

    // UI 界面中断激发初始化
    pinMode(BUTTON_3, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(BUTTON_3), wheelAdd, FALLING);

....

}

// 按下顶部按键实现自动切换页面

void wheelAdd()
{
    static long start = millis(); //防抖
    if (millis() - start > 50)
    {
        label++;
        label %= 5;  //共有5个页面,轮番
        start = millis();
    }
}
​

 

  • 4.渐变动态壁纸

为了增加界面的趣味性,数据显示背景会缓慢的变化,以至于抬眼望去都是不同的景观。

void drawGradient(void)
{
    static int k = 0;
    static int scale = 1; 
    k += scale;             //每次循环逐渐更新背景。
    if (k > 250 || k < 1) //
        scale = -scale;
    for (int i = 0; i < tft.width(); i++)
    {
        for (int j = 0; j < tft.height(); j++)
        {
            int r = (i + j) >> 1; //形成倒三角
            int g = j;            //可尝试更换r,g,b 顺序或其他函数获取不同的色彩变化效果。
            int b = ~k;
            spr.writePixel(i, j, tft.color888(r, g, b));
        }
    }
}

 

  • 5.太空人动画

     标配太空人!


//太空人素材
#include "img/pangzi/i0.h"
#include "img/pangzi/i1.h"
#include "img/pangzi/i2.h"
#include "img/pangzi/i3.h"
#include "img/pangzi/i4.h"
#include "img/pangzi/i5.h"
#include "img/pangzi/i6.h"
#include "img/pangzi/i7.h"
#include "img/pangzi/i8.h"
#include "img/pangzi/i9.h"

//  没有使用其他图片显示库,只用了 LGFX提供的drawJpg加载。

void imgAnim(void)
{
    int x = 120, y = 150, dt = 30; //
    // const uint8_t *jpg[] = {&i0, &i1};
    spr.drawJpg(i0, sizeof(i0), x, y);
    delay(dt);
    spr.pushSprite(&tft, 0, 0);
    spr.drawJpg(i1, sizeof(i1), x, y);
    delay(dt);
    spr.pushSprite(&tft, 0, 0);
    spr.drawJpg(i2, sizeof(i2), x, y);
    delay(dt);
    spr.pushSprite(&tft, 0, 0);
    spr.drawJpg(i3, sizeof(i3), x, y);
    delay(dt);
    spr.pushSprite(&tft, 0, 0);
    spr.drawJpg(i4, sizeof(i4), x, y);
    delay(dt);
    spr.pushSprite(&tft, 0, 0);
    spr.drawJpg(i5, sizeof(i5), x, y);
    delay(dt);
    spr.pushSprite(&tft, 0, 0);
    spr.drawJpg(i6, sizeof(i6), x, y);
    delay(dt);
    spr.pushSprite(&tft, 0, 0);
    spr.drawJpg(i7, sizeof(i7), x, y);
    delay(dt);
    spr.pushSprite(&tft, 0, 0);
    spr.drawJpg(i8, sizeof(i8), x, y);
    delay(dt);
    spr.pushSprite(&tft, 0, 0);
    spr.drawJpg(i9, sizeof(i9), x, y);
    delay(dt);
    spr.pushSprite(&tft, 0, 0);
}

// 怎么可以写得更优雅。

 

  • 6.中文显示

   中文显示技术似乎备受关注,目前没有很完美的方案。

   采用LovyanGFX可以加载自带的中文字库,包含全部中文字体(tft.loadFont(&fonts::efontCN_12)) 即可获得中文显示支持,可以适用普通的日常使用,这是也为什么选择LovyanGFX库的原因之一。其不足之处,就是字库字体较小,放大后效果感人,采用抗锯齿方法提取字库后,就回不去了。字库提取方法虽好,毛病就是操作步骤多,需要练习几次,内存占用大,需要及时退出字体,下面将字库制作的流程附上,确保万全。

严格按以下教程可以实现抗锯齿中文显示。

 

https://www.cnblogs.com/deng1821333144/p/15307883.html

具体步骤继续分解一下动作,供参考。

第一步:准备好要转化的文字。

 

 新春大吉生龙活虎待续未完温度湿度超声波距离室内环境体检测气压℃

第二步:到下列网址将中文转换为unicode格式。

转unicode : http://tool.chinaz.com/tools/unicode.aspx

第三步:将生成Unicode码拷贝到一个文字编辑器,然后用0x替换Unicode码中的 \u。

 

0x65b0,0x6625,0x5927,0x5409,0x751f,0x9f99,0x6d3b,0x864e,0x5f85,0x7eed,0x672a,0x5b8c,0x6e29,0x5ea6,0x6e7f,0x5ea6,0x8d85,0x58f0,0x6ce2,0x8ddd,0x79bb,0x5ba4,0x5185,0x73af,0x5883,0x4f53,0x68c0,0x6d4b,0x6c14,0x538b,0x2103

第四步:转到Processing 进行抗锯齿转换,严格下列网址按教程执行。

https://www.cnblogs.com/deng1821333144/p/15307883.html

 

第五步:将 .Vlw字体转.h文件。

在下列网址将FontFiles文件夹里的新生成的vlw文件上传到下列网址获得hex码。

复制hex码到文字编辑器。

头部补充:#include <pgmspace.h>

const uint8_t  fangzheng28[] PROGMEM = {

其中fangzheng28是自定义的加载的时候需要用到。

尾部加:};

注意有冒号。

https://tomeko.net/online_tools/file_to_hex.php?lang=zh

第六步:将.h文件拷贝到跟主程序文件目录下备用。

 

FqrL2oDOc12PS1jH6X65UVcLpwoG

图4.抗锯齿中文显示及动态渐变壁纸展示

  •  7.屏幕自动翻转

   非常使用的小功能,目前只设置前后翻转,没有左右翻转。

void autoRotation(void) //实用。
{
    float x_values;
    x_values = lis.getAccelerationX();//根据陀螺仪X轴数据进行判断
    if (x_values > 0.5)
    {
        tft.setRotation(1);
    }
    if (x_values < -0.5)
    {
        tft.setRotation(3);
    }
}

 

 

FhR0QXeuaYFBIwYwB8r_J5vV_ML2

图5.自带陀螺仪数据读取及显示

(三)心得总结

     经过两个月的不断学习这期活动有望取得预期的效果,这跟Seeed 公司为Wio terminal 提供完善的新手入门教程有关,从开箱到深度使用都有详细的手把手教程,非常贴心,从这里看到如何打造用户生态的案例(主要是题目比较简单/狗头)。在这个项目中成功入门了LovyanGFX图形库,过程中应用到是该库的大部分日常功能,目前主流的图形库都是相互借鉴的(披上了一个马甲,M5GFX,DFRobot_GDL),使用方法相同,因此,在这个基础上以后转移到其他芯片的主板上还是可以派得上用场的。例如这些库已经开始支持raspberry pico,所以在pico上应该还是可以用得上这个图形工具的。

    Wio terminal 功能很全面,可玩性很高,可以进行一些进阶的项目,例如深度学习部分,但是由于时间精力有限,还没有全部过一遍。项目中是用的虽然是用platform IO进行编程,但是还是使用了传统的Arduino的框架,没有用上FreeRTOS的特性,往后可以进行优化,使得程序运行得更加流畅。

新手上路,还有很多坑需要面对!

最后,感谢小伙伴的相互点赞,相互搀扶!恭祝大家新年快乐!

FnegQYAkK5SltABK3lSecWVQmEKH

图6.实物上帝视角图

 

对于本项目有问题或指导欢迎留言讨论!

附件下载
mix.zip
PlatformIO 主程序
汉字制作过程.docx
团队介绍
一个水水的摸鱼高手
团队成员
Fifi
五年级小伙伴,带货实习生
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号