本周带来的项目是如何利用Arduino来显示Unicode文本。
开发板任意一块带有Arduino_GFX支持的Arduino开发板。
第1步:统一码和UTF-8参考: https://github.com/moononournation/Arduino_GFX
Unicode定义了144k 字符,涵盖159种现代和历史文字,以及符号、表情符号和非视觉控制和格式化代码。
Unicode可以通过不同的字符编码来实现。
Unicode标准定义了Unicode转换格式(UTF)。UTF-8、UTF-16和UTF-32,以及其他几种编码方式。
为了更好地向后兼容,Arduino IDE、最新的操作系统和网页都使用UTF-8编码。
UTF-8是为了向后兼容ASCII而设计的:Unicode的前128个字符,与ASCII一一对应,使用与ASCII相同的二进制值的单个字节进行编码。
第2步:为什么需要UTF-8?参考文献:
https://en.wikipedia.org/wiki/Unicode
https://en.wikipedia.org/wiki/UTF-8
https://en.wikipedia.org/wiki/ASCII
有些项目其实只需使用ASCII字符就可以很好地呈现,而不需要Unicode。
而有些项目则需要Unicode来支持多国语言,例如:
- • 显示你的手机通知的蓝牙设备
- • 显示最新新闻的RSS阅读器
- • 国内天气预告显示面板
- • 电子书
还有更多需要文本显示的项目。
第3步:扩展ASCIIArduino_GFX继承了Adafruit_GFX,自Adafruit_GFX 1.0以来默认使用经典的固定空间位图字体。这种字体叫glcdfont,大小为5×7像素,包含128个ASCII字符和128个扩展ASCII字符。我们可以在AsciiTable的例子中查看所有的字符。
在启用UTF-8编码之前,Arduino_GFX可以通过函数切换UTF-8编码。
gfx->setUTF8Print(true);
启用UTF-8编码后,不能使用扩展的ASCII字符。但我们可以使用相应的UTF-8编码的字符来代替。
例如,用扩展ASCII打印摄氏度符号是:
gfx->print("\xF8""C");
由于Arduino IDE可以直接使用UTF-8编码的字符串,所以用UTF-8打印相同的符号是:
gfx->print("°C");
或者:
gfx->print("℃");
取决于所选择的UTF-8字体文件中包含的字符字形。
第4步:字体数据大小如前面所说的,Unicode包含超过144k个字符,要在Arduino程序中全部打包是不容易的。
Unifont是包含最常见的UTF-8字符的字体类型之一。在最新的unifont_jp-14.0.02版本中,它包含57389个字形,BCF格式的字体文件大小为9.4MB。
常见的AVR系列开发板只有32KB的闪存存储程序;ESP8266有4MB的闪存,但仍把程序限制在1MB左右;RTL8720DN可以存储2MB的程序;ESP32 Huge APP模式可以存储3MB的程序;Raspberry Pi Pico可以存储2MB的程序(有些变化可以存储16MB)。
第5步:U8g2字体参考资料:
https://en.wikipedia.org/wiki/GNU_Unifont
http://unifoundry.com/pub/unifont/unifont-14.0.02/font-builds/
Arduino_GFX采用U8g2字体格式作为UTF-8解决方案。U8g2字体支持UTF-8编码,同时U8g2提供了一些工具来将字体文件转换为Arduino源文件。
bdfconv是U8g2提供的工具之一,它可以将unifont bdf字体文件转换为Arduino源文件。
输出的二进制文件是压缩格式的,而且bdfconv可以选择编码范围来输出,这两个特性都可以减少数据的大小。
第6步:选择字体子集参考文献:
https://github.com/olikraus/u8g2/wiki/u8g2fontformat
https://github.com/olikraus/u8g2/tree/master/tools/font/bdfconv
由于我们不能简单地把整套Unifont字体挤进有限的程序空间,所以我们需要选择一个字体子集,用于特定的项目。
U8g2已经为各种语言准备了很多unifont子集,例如:
- • u8g2_font_unifont_t_polish
- • u8g2_font_unifont_t_vietnamese1
- • u8g2_font_unifont_t_chinese2
- • u8g2_font_unifont_t_japanese1
- • u8g2_font_unifont_t_korean1
即使这样,有些语言依旧无法在Arduino中容纳所有的字体,所以它有不同的尺寸的子集来满足不同的要求,比如,中文字体有3个子集。
- • u8g2_font_unifont_t_chinese1 - 大小为14,178 字节
- • u8g2_font_unifont_t_chinese2 - 大小为20,225 字节
- • u8g2_font_unifont_t_chinese3 - 大小为37,502 字节
你可以参考U8g2 Github Wiki以了解更多细节:
https://github.com/olikraus/u8g2/wiki/fntgrpunifont
第7步:Arduino_GFX准备的字体文件正如在前面的步骤中提到的,一些MCU可以存储程序大小到1-3MB。
所以,我们可以量身定做一个字体文件,尽可能多地显示字形。下面是Arduino_GFX中准备的一些额外的字体文件。
- • u8g2_font_unifont_h_utf8
- • u8g2_font_unifont_t_chinese
- • u8g2_font_unifont_t_chinese4
- • u8g2_font_unifont_t_cjk
BDF字体位图使用unifont_jp-14.0.02,转换工具是U8g2提供的bdfconv。
第8步:自定义字体 U8g2_font_unifont_h_utf8
This font included all glyphs in unifont_jp-14.0.02.
Number of Glyph: 57,389
Data size: 2,250,360 bytes
Converting script:
bdfconv -v -f 1 -b 1 -m "0-1114111" unifont_jp-14.0.02.bdf -o u8g2_font_unifont_h_utf8.h -n u8g2_font_unifont_h_utf8
第9步:自定义字体 U8g2_font_unifont_t_chinese注意: 由于字体数据本身超过2MB,所以只有ESP32家族的Huge app模式可以存储该程序。一些特定版本的Raspberry Pi Pico有超过2MB的闪存,但我还没有测试。
这个字体包括了所有汉字范围的字形。
- • 字形数量:22,145
- • 数据大小: 979,557字节
转换脚本:
bdfconv -v -f 1 -m "32-127,11904-12351,19968-40959,63744-64255,65280-65376" unifont_jp-14.0.02.bdf -o u8g2_font_unifont_t_chinese.h -n u8g2_font_unifont_t_chinese
由于ESP8266有1MB的程序大小限制,所有的汉字还是不能装进去。这就需要另一个子集,只缩小到常用的字符。
常用字的列表来自于字集中的常用國字標準字體表和GlyphWiki的字表:中国常用字。
字形的数量:7199
数据大小: 298,564 Bytes
转换的脚本:
bdfconv -v -f 1 -M common.txt unifont_jp-14.0.02.bdf -o u8g2_font_unifont_t_chinese4.h -n u8g2_font_unifont_t_chinese4
这个字体包含所有的中文、日文和韩文字符。这三种语言共享92,865个中日韩统一表意文字,所以可以用一个字体文件来显示三种不同的语言,非常方便。
字形数量: 41364
数据大小: 1,704,862 Bytes
转换脚本:
bdfconv -v -f 1 -m "32-127,4352-4607,11904-12255,12288-19903,19968-40943,43360-43391,44032-55203,55216-55295,63744-64255,65072-65103,65280-65519" unifont_jp-14.0.02.bdf -o u8g2_font_unifont_t_cjk.h -n u8g2_font_unifont_t_cjk
第12步:软件准备参考:
https://en.wikipedia.org/wiki/CJK_Unified_Ideographs
https://stackoverflow.com/questions/56310609/what-the-chinese-japanese-and-korean-characters-are-in-unicode
Arduino IDE
下载并安装Arduino IDE,如果你还没有的话:
https://www.arduino.cc/en/main/software
Arduino_GFX库选择 "工具 "菜单->"管理库... ",搜索 "GFX for various displays "然后点击 "install "按钮安装。
第13步:Unicode实例
Arduino_GFX在U8g2Font子文件夹中提供了各种Unicode例子。
在Arduino IDE中,选择 "文件 "菜单->"示例"->"GFX Library for Arduino"->"U8g2Font"。5个例子中的4个是Unicode例子。
- • U8g2FontPrintUTF8 - 用U8g2内置字体打印各种语言的Hello World
- • U8g2FontUTF8Chinese - 使用字体文件u8g2_font_unifont_t_chinese打印一篇中文文章样本
- • U8g2FontUTF8FullCJK - 使用字体文件u8g2_font_unifont_t_cjk打印一个简单的中文、日文和韩文问候信息。
- • U8g2FontUTF8FullUnifont - 使用字体文件u8g2_font_unifont_h_utf8打印74种语言的Hello World。
- • U8g2RssReader - 用字体文件u8g2_font_unifont_t_chinese4打印在线RSS信息。
第14步:开始尝试吧!
现在,我们的Arduino项目就可以突破ASCII文本的限制了!有项目可以利用起来了!
原文链接:https://www.instructables.com/Display-Unicode-in-Arduino/
原文作者:陳亮
译文首发:DF创客社区 https://mc.dfrobot.com.cn/thread-313253-1-1.html
转载请注明原作者及出处
,