【问题标题】:reducing memory required for KeDei TFT library used with 3.5" TFT display with Arduino使用 Arduino 减少与 3.5" TFT 显示器一起使用的 KeDei TFT 库所需的内存
【发布时间】:2021-07-19 10:21:32
【问题描述】:

我需要减少与Osoyoo 3.5" TFT touch screen display shield for Arduino Uno and ATmega 2560 一起使用的KeDei TFT library 所需的内存。当我尝试编写一个使用 TFT 显示器和 KeDei 库的简单 Arduino 应用程序时,Arduino 上的大部分可用内存都被库本身占用了。

不幸的是,我发现虽然 ATmega 2560 确实具有必要的内存量,但当 TFT 显示器与该设备一起使用时,KeDei TFT 库无法提供正确的触摸坐标,因此除非 Osoyoo 客户支持,否则 ATmega 2560 不可行虽然有一个解决方案。

查看库源代码,我在文件 KeDei_font.cpp 中发现了一个位图字体表,用于生成显示的字符。这个位图字体表是一个数组,unsigned char font16_B[96][16],似乎是主内存占用。此数组包含从空格字符 0x20 到波浪字符 0x7e 的 ASCII 字符的位图字体。

我做过的一件事是通过消除小写字母并将小写字母转换为大写字母来减少字符数。这会产生一个表const unsigned char font16_B[59][16],它比原始表的大小略多一点。

通过这种方法,我还消除了一些其他标点符号类型的字符,但只要我只显示字母数字字符和空格,这将起作用。

#if defined(SMALLER_FONT_TABLE)
    static const unsigned char font16_B[59][16] = {
#else
    static const unsigned char font16_B[95][16] = {
#endif
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
            {0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x38,0x38,0x00,0x00},/*"!",1*/
            {0x00,0xD8,0xFC,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/
            {0x00,0x00,0x00,0x6C,0x6C,0x6C,0xFF,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x00,0x00},/*"#",3*/
            {0x00,0x00,0x18,0x3C,0x7E,0x7E,0x1E,0x1C,0x38,0x78,0x78,0x7E,0x7E,0x3C,0x18,0x18},/*"$",4*/
            {0x00,0x00,0x00,0x66,0x6F,0x3F,0x3F,0x3F,0x7E,0xF8,0xFC,0xFC,0xFC,0x66,0x00,0x00},/*"%",5*/
            {0x00,0x00,0x00,0x1C,0x36,0x36,0x36,0x1E,0xFE,0x6F,0x7B,0x33,0xB3,0xFE,0x00,0x00},/*"&",6*/
            {0x00,0x0E,0x0E,0x0C,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
            {0x00,0xC0,0x60,0x30,0x30,0x18,0x18,0x18,0x18,0x18,0x18,0x30,0x30,0x60,0xC0,0x00},/*"(",8*/
            {0x00,0x06,0x0C,0x18,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x18,0x0C,0x06,0x00},/*")",9*/
            {0x00,0x00,0x00,0x00,0x18,0x18,0xFF,0x3C,0x3C,0xFF,0x18,0x18,0x00,0x00,0x00,0x00},/*"*",10*/
            {0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x00,0x00,0x00},/*"+",11*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0C,0x07},/*",",12*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"-",13*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x00,0x00},/*".",14*/
            {0x00,0x00,0x80,0xC0,0xC0,0x60,0x60,0x30,0x30,0x18,0x18,0x0C,0x0C,0x06,0x06,0x00},/*"/",15*/
            {0x00,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00},/*"0",16*/
            {0x00,0x00,0x00,0x18,0x1E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00},/*"1",17*/
            {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x60,0x60,0x30,0x18,0x0C,0xC6,0xFE,0x00,0x00},/*"2",18*/
            {0x00,0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x60,0xC0,0xC0,0xC6,0x66,0x3C,0x00,0x00},/*"3",19*/
            {0x00,0x00,0x00,0x60,0x70,0x78,0x6C,0x6C,0x66,0x66,0xFE,0x60,0x60,0xF8,0x00,0x00},/*"4",20*/
            {0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x3E,0x6E,0xC0,0xC0,0xC6,0x66,0x3C,0x00,0x00},/*"5",21*/
            {0x00,0x00,0x00,0x78,0x6C,0x06,0x06,0x3E,0x6E,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00},/*"6",22*/
            {0x00,0x00,0x00,0xFE,0x66,0x66,0x30,0x30,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00},/*"7",23*/
            {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x6C,0x38,0x6C,0xC6,0xC6,0xC6,0x7C,0x00,0x00},/*"8",24*/
            {0x00,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xEC,0xF8,0xC0,0xC0,0x6C,0x3C,0x00,0x00},/*"9",25*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x00,0x00,0x00,0x00,0x38,0x38,0x00,0x00},/*":",26*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x0C},/*";",27*/
            {0x00,0x00,0x00,0xC0,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00,0x00},/*"<",28*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00},/*"=",29*/
            {0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x0C,0x06,0x00,0x00},/*">",30*/
            {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xCE,0xC0,0x60,0x30,0x30,0x00,0x38,0x38,0x00,0x00},/*"?",31*/
            {0x00,0x00,0x00,0x3C,0x66,0xFE,0xFF,0xFF,0xFF,0xFF,0x7F,0xC6,0x66,0x3C,0x00,0x00},/*"@",32*/
            {0x00,0x00,0x00,0x18,0x18,0x38,0x3C,0x3C,0x6C,0x7C,0x66,0xC6,0xC6,0xEF,0x00,0x00},/*"A",33*/
            {0x00,0x00,0x00,0x3F,0x66,0x66,0x66,0x3E,0x66,0xC6,0xC6,0xC6,0x66,0x3F,0x00,0x00},/*"B",34*/
            {0x00,0x00,0x00,0xFC,0xC6,0xC6,0x03,0x03,0x03,0x03,0x03,0xC6,0x66,0x3C,0x00,0x00},/*"C",35*/
            {0x00,0x00,0x00,0x3F,0x66,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x66,0x3F,0x00,0x00},/*"D",36*/
            {0x00,0x00,0x00,0x7F,0xC6,0x36,0x36,0x3E,0x36,0x36,0x06,0xC6,0xC6,0x7F,0x00,0x00},/*"E",37*/
            {0x00,0x00,0x00,0x7F,0xC6,0x36,0x36,0x3E,0x36,0x36,0x06,0x06,0x06,0x0F,0x00,0x00},/*"F",38*/
            {0x00,0x00,0x00,0x7C,0x66,0x66,0x03,0x03,0x03,0xF3,0x63,0x66,0x66,0x3C,0x00,0x00},/*"G",39*/
            {0x00,0x00,0x00,0xEF,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xEF,0x00,0x00},/*"H",40*/
            {0x00,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00},/*"I",41*/
            {0x00,0x00,0x00,0xFC,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x33,0x1F},/*"J",42*/
            {0x00,0x00,0x00,0xFF,0x66,0x36,0x1E,0x1E,0x1E,0x36,0x36,0x66,0x66,0xFF,0x00,0x00},/*"K",43*/
            {0x00,0x00,0x00,0x0F,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0xC6,0xFF,0x00,0x00},/*"L",44*/
            {0x00,0x00,0x00,0xFF,0x7E,0x7E,0x7E,0x7E,0x7E,0x7E,0x7E,0x7E,0x7E,0xFF,0x00,0x00},/*"M",45*/
            {0x00,0x00,0x00,0xE7,0xCE,0xCE,0xDE,0xDE,0xF6,0xF6,0xF6,0xE6,0xE6,0xCF,0x00,0x00},/*"N",46*/
            {0x00,0x00,0x00,0x3C,0x66,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x66,0x3C,0x00,0x00},/*"O",47*/
            {0x00,0x00,0x00,0x7F,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x06,0x0F,0x00,0x00},/*"P",48*/
            {0x00,0x00,0x00,0x3C,0x66,0xC3,0xC3,0xC3,0xC3,0xC3,0xDF,0xF7,0x76,0x3C,0xE0,0x00},/*"Q",49*/
            {0x00,0x00,0x00,0x7F,0xC6,0xC6,0xC6,0x7E,0x36,0x36,0x66,0x66,0xC6,0xCF,0x00,0x00},/*"R",50*/
            {0x00,0x00,0x00,0xFC,0xC6,0xC6,0x06,0x0C,0x38,0x60,0xC0,0xC6,0xC6,0x7E,0x00,0x00},/*"S",51*/
            {0x00,0x00,0x00,0xFF,0xDB,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00},/*"T",52*/
            {0x00,0x00,0x00,0xEF,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00},/*"U",53*/
            {0x00,0x00,0x00,0xEF,0xC6,0xC6,0x66,0x6C,0x6C,0x3C,0x3C,0x38,0x18,0x18,0x00,0x00},/*"V",54*/
            {0x00,0x00,0x00,0xFF,0xDB,0xDB,0xDB,0xDB,0xFF,0xFF,0x7E,0x66,0x66,0x66,0x00,0x00},/*"W",55*/
            {0x00,0x00,0x00,0xEF,0xC6,0x6C,0x6C,0x38,0x38,0x38,0x6C,0x6C,0xC6,0xEF,0x00,0x00},/*"X",56*/
            {0x00,0x00,0x00,0xFF,0x66,0x66,0x3C,0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00},/*"Y",57*/
            {0x00,0x00,0x00,0xFE,0x63,0x60,0x30,0x30,0x18,0x0C,0x0C,0xC6,0xC6,0x7F,0x00,0x00},/*"Z",58*/
#if !defined(SMALLER_FONT_TABLE)
            // In the interest of reducing the memory requirements for the TFT library, we
            // allow for the use of a smaller font table which eliminates the lower case letters
            // as well as a few symbols. See below conversion of lower case letters to upper case.
            //    Richard Chambers, 04-25-2021
            {0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00},/*"[",59*/
            {0x00,0x00,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x30,0x30,0x60,0x60,0x60,0xC0,0xC0},/*"\",60*/
            {0x00,0x3E,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3E,0x00},/*"]",61*/
            {0x00,0x78,0xCC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF},/*"_",63*/
            {0x00,0x0E,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xF8,0xCC,0xC6,0xC6,0xFC,0x00,0x00},/*"a",65*/
            {0x00,0x00,0x00,0x07,0x06,0x06,0x06,0x3E,0x6E,0xC6,0xC6,0xC6,0x6E,0x3E,0x00,0x00},/*"b",66*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0xCC,0x06,0x06,0x06,0xCC,0x78,0x00,0x00},/*"c",67*/
            {0x00,0x00,0x00,0xE0,0xC0,0xC0,0xC0,0xF8,0xCC,0xC6,0xC6,0xC6,0xEC,0xF8,0x00,0x00},/*"d",68*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0x06,0x06,0xC6,0x7C,0x00,0x00},/*"e",69*/
            {0x00,0x00,0x00,0xF0,0x98,0x18,0x18,0xFE,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00},/*"f",70*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x66,0x66,0x3C,0x06,0x7C,0xC6,0xC6,0x7C},/*"g",71*/
            {0x00,0x00,0x00,0x07,0x06,0x06,0x06,0x7E,0xCE,0xC6,0xC6,0xC6,0xC6,0xEF,0x00,0x00},/*"h",72*/
            {0x00,0x00,0x00,0x1C,0x1C,0x00,0x00,0x1E,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00},/*"i",73*/
            {0x00,0x00,0x00,0x70,0x70,0x00,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x66,0x3E},/*"j",74*/
            {0x00,0x00,0x00,0x07,0x06,0x06,0x06,0xF6,0x36,0x1E,0x3E,0x36,0x66,0xFF,0x00,0x00},/*"k",75*/
            {0x00,0x00,0x00,0x1E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00},/*"l",76*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xB6,0xB6,0xB6,0xB6,0xB6,0xFF,0x00,0x00},/*"m",77*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xCE,0xC6,0xC6,0xC6,0xC6,0xEF,0x00,0x00},/*"n",78*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00},/*"o",79*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x6E,0xC6,0xC6,0xC6,0x66,0x3E,0x06,0x0F},/*"p",80*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xCC,0xC6,0xC6,0xC6,0xCC,0xF8,0xC0,0xE0},/*"q",81*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xDC,0x0C,0x0C,0x0C,0x0C,0x3F,0x00,0x00},/*"r",82*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xC6,0x06,0x7C,0xC0,0xC6,0x7E,0x00,0x00},/*"s",83*/
            {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x18,0x70,0x00,0x00},/*"t",84*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0xC6,0xC6,0xC6,0xC6,0xE6,0xFC,0x00,0x00},/*"u",85*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEF,0xC6,0x6C,0x6C,0x3C,0x18,0x18,0x00,0x00},/*"v",86*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xDB,0xDB,0xFF,0xFF,0x66,0x66,0x00,0x00},/*"w",87*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x6C,0x38,0x38,0x38,0x6C,0xFE,0x00,0x00},/*"x",88*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEF,0xC6,0x6C,0x6C,0x3C,0x38,0x18,0x18,0x0F},/*"y",89*/
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x66,0x30,0x18,0x18,0xCC,0xFE,0x00,0x00},/*"z",90*/
            {0x00,0xC0,0x60,0x60,0x60,0x60,0x60,0x30,0x60,0x60,0x60,0x60,0x60,0x60,0xC0,0x00},/*"{",91*/
            {0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30},/*"|",92*/
            {0x00,0x0E,0x18,0x18,0x18,0x18,0x18,0x30,0x18,0x18,0x18,0x18,0x18,0x18,0x0E,0x00},/*"}",93*/
            {0x1C,0x76,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",94*/
#endif
        };

然后在生成字符并逐像素显示它们的函数中,如果我启用了较小的表,我有以下代码可以将小写字符转换为大写字符。

#if defined(SMALLER_FONT_TABLE)
    // Lets translate the character to one of the printable
    // characters in our font table. What we are doing is
    // to translate lower case letters to upper case letters
    // since in order to have a smaller font table taking up
    // less memory we remove the lower case letters.
    //    Richard Chambers, 04-25-2021
    if (_data < ' ' || _data > 'z') return;
    if (_data >= 'a') _data = _data - 'a' + 'A';
#endif
    char_i=(int)_data - ' ';

使用这种方法,当我使用定义的 SMALLER_FONT_TABLE 编译我的 Arduino 草图时,编译完成并出现以下警告:

Sketch uses 12844 bytes (39%) of program storage space. Maximum is 32256 bytes.
Global variables use 1556 bytes (75%) of dynamic memory, leaving 492 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.

如何进一步减少显示字体所需的内存?是否有另一种使用更少内存的位图字体?

【问题讨论】:

  • 严格来说,“字母数字”应该是 36 个字符 A-Z、0-9、+ 1 表示空格 = 37。试试看。或者重写库,这可能是臃肿和浪费,几乎每个 Arduino 库都是。其他要考虑的事情是程序。或者您自己设计的较小字体。
  • @TomServo 我正在重写库。目前我允许选择原始的 16x16 位图字体或我在 GitHub 中找到的 8x8 位图字体。我还添加了使用位图字体双高、双宽或将两者结合起来的功能,从而提供了很好的样式组合。我现在正在处理库的位图显示部分。
  • 那很好。我从来没有见过一个“流行”的 Arduino 库,它不是一个缓慢、臃肿的混乱,专为修补匠和业余爱好者而设计。我已经预订了您的问题,因为我也对这种类型的展示感兴趣。
  • @TomServo 一个 KeDei TFT 库的分支,我的更改位于我的 github 存储库中,地址为 github.com/RichardChambers/driver/tree/master/KeDeiTFT
  • 是的,我看到了,我会看的,谢谢。

标签: c++ fonts arduino microcontroller bitmap-fonts


【解决方案1】:

我研究的第一种方法是对位图字体表使用某种压缩,例如运行长度编码,因为许多条目都是二进制零。我测试了这种方法,它确实减少了内存量,同时增加了一些复杂性。然而,使用我测试的简单方法节省的内存量约为 200 字节。

我看到的第二种方法是通过首先消除小写字母然后更改位图字体来减小数组的大小。将位图字体从 16x16 大小的字体更改为 8x8 大小的字体会显着降低内存使用率。

但是将表格大小从const unsigned char font16_B[96][16]更改为const unsigned char font16_B[96][8]意味着TFT屏幕上显示的字符会变小。

所以在使用的内存量和字符显示大小之间需要权衡。较大的显示字符需要更多的内存来描述字形。

快速搜索“8 位图字体”可以找到 Daniel Hepper 的这个 GitHub 存储库,https://github.com/dhepper/font8x8,具有 8x8 大小的字体,并且许可证是公共领域。

使用预处理器指令选择要使用的字体表并从 Hepper 的 GitHub 存储库中选择文件 font8x8_basic.h 的子部分,我将以下内容添加到 KeDei TFT 库中。

#if defined(USE_FONT_8_B)
#define FONT_ROW_LEN  8
#if defined(SMALLER_FONT_TABLE)
    static const unsigned char font8_B[59][8] = {
#else
    static const unsigned char font8_B[96][8] = {
#endif
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0020 (space)
        { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00 },   // U+0021 (!)
        { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0022 (")
        { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00 },   // U+0023 (#)
        { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00 },   // U+0024 ($)
        { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00 },   // U+0025 (%)
        { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00 },   // U+0026 (&)
        { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0027 (')
        { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00 },   // U+0028 (()
        { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00 },   // U+0029 ())
        { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00 },   // U+002A (*)
        { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00 },   // U+002B (+)
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06 },   // U+002C (,)
        { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00 },   // U+002D (-)
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00 },   // U+002E (.)
        { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 },   // U+002F (/)
        { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00 },   // U+0030 (0)
        { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00 },   // U+0031 (1)
        { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00 },   // U+0032 (2)
        { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00 },   // U+0033 (3)
        { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00 },   // U+0034 (4)
        { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00 },   // U+0035 (5)
        { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00 },   // U+0036 (6)
        { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00 },   // U+0037 (7)
        { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00 },   // U+0038 (8)
        { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00 },   // U+0039 (9)
        { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00 },   // U+003A (:)
        { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06 },   // U+003B (;)
        { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00 },   // U+003C (<)
        { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00 },   // U+003D (=)
        { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00 },   // U+003E (>)
        { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00 },   // U+003F (?)
        { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00 },   // U+0040 (@)
        { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00 },   // U+0041 (A)
        { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00 },   // U+0042 (B)
        { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00 },   // U+0043 (C)
        { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00 },   // U+0044 (D)
        { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00 },   // U+0045 (E)
        { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00 },   // U+0046 (F)
        { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00 },   // U+0047 (G)
        { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00 },   // U+0048 (H)
        { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 },   // U+0049 (I)
        { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00 },   // U+004A (J)
        { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00 },   // U+004B (K)
        { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00 },   // U+004C (L)
        { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00 },   // U+004D (M)
        { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00 },   // U+004E (N)
        { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00 },   // U+004F (O)
        { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00 },   // U+0050 (P)
        { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00 },   // U+0051 (Q)
        { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00 },   // U+0052 (R)
        { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00 },   // U+0053 (S)
        { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 },   // U+0054 (T)
        { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00 },   // U+0055 (U)
        { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00 },   // U+0056 (V)
        { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00 },   // U+0057 (W)
        { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00 },   // U+0058 (X)
        { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00 },   // U+0059 (Y)
        { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00 },   // U+005A (Z)
#if !defined(SMALLER_FONT_TABLE)
        // In the interest of reducing the memory requirements for the TFT library, we
        // allow for the use of a smaller font table which eliminates the lower case letters
        // as well as a few symbols. See below conversion of lower case letters to upper case.
        //    Richard Chambers, 04-25-2021
        { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00 },   // U+005B ([)
        { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00 },   // U+005C (\)
        { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00 },   // U+005D (])
        { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00 },   // U+005E (^)
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF },   // U+005F (_)
        { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0060 (`)
        { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00 },   // U+0061 (a)
        { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00 },   // U+0062 (b)
        { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00 },   // U+0063 (c)
        { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00 },   // U+0064 (d)
        { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00 },   // U+0065 (e)
        { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00 },   // U+0066 (f)
        { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F },   // U+0067 (g)
        { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00 },   // U+0068 (h)
        { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 },   // U+0069 (i)
        { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E },   // U+006A (j)
        { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00 },   // U+006B (k)
        { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 },   // U+006C (l)
        { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00 },   // U+006D (m)
        { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00 },   // U+006E (n)
        { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00 },   // U+006F (o)
        { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F },   // U+0070 (p)
        { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78 },   // U+0071 (q)
        { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00 },   // U+0072 (r)
        { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00 },   // U+0073 (s)
        { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00 },   // U+0074 (t)
        { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00 },   // U+0075 (u)
        { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00 },   // U+0076 (v)
        { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00 },   // U+0077 (w)
        { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00 },   // U+0078 (x)
        { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F },   // U+0079 (y)
        { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00 },   // U+007A (z)
        { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00 },   // U+007B ({)
        { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00 },   // U+007C (|)
        { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00 },   // U+007D (})
        { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+007E (~)
#endif
    };
#else
#define FONT_ROW_LEN  16
#if defined(SMALLER_FONT_TABLE)
    static const unsigned char font16_B[59][16] = {
#else
    static const unsigned char font16_B[95][16] = {
#endif
            {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/

我还必须修改字符绘制循环,以便使用 8 列而不是使用 16 列。列数是硬编码的常量,但现在由类变量 font_size 指定,该变量设置为 16 或8 取决于是否定义了常量USE_FONT_8_B

#if defined(USE_FONT_8_B)
        font_size = 8;
#else
        font_size = 16;
#endif

循环看起来像:

    for(char_m = 0; char_m < font_size; char_m++)
    {
        for(char_n = 0; char_n < 8; char_n++)
        {

#if defined(USE_FONT_8_B)
            if (font8_B[char_i][char_m] & 1 << char_n)
#else
            if(font16_B[char_i][char_m] & 1 << char_n)
#endif
            {
               TFT.set_area(now_x, now_y, ++now_x, now_y);
               TFT.w_data(font_color >> 8);
               TFT.w_data(font_color);
            }
            else
            {
              now_x++;
  
            }
         }
         now_y++;
         now_x -= 8;
    }
    now_y -= font_size;
    now_x += 8 + font_interval;

如果我同时使用 8x8 字体和 SMALLER_FONT_TABLE 定义,那么当我编译我的草图时,我会得到以下关于内存使用的编译器输出:

Sketch uses 12390 bytes (38%) of program storage space. Maximum is 32256 bytes.
Global variables use 1084 bytes (52%) of dynamic memory, leaving 964 bytes for local variables. Maximum is 2048 bytes.

这是连接到 Arduino Uno 的 3.5" TFT 显示屏上两种不同尺寸的比较。按钮为 64 x 40 像素。

注意

我已经从 Osoyoo 的 GitHub 上 fork 了 KeDei TFT 库源代码,并开始修改源代码。分叉位于https://github.com/RichardChambers/driver/tree/master/KeDeiTFT

其中一项更改是允许文本为双倍高和/或双倍宽。这张图片是当前版本的扫描仪/比例模拟器,显示了双倍高和双倍宽文本与双倍高文本之间的样式差异。

此更新后的图像显示了目前预期的最终 GUI。它允许更改重量,还允许设置各种状态位以指示秤错误情况,例如容量不足。

为了支持按钮的数量,我重写了Button 类,这样我就可以让按钮共享一些数据,从而每个按钮节省大约 11 个字节。所以这个带有八个按钮的 GUI 使用数据共享功能节省了大约 77 字节的内存,这对于 Arduino 来说是一个显着的节省。

Button 类现在派生自 ButtonShared 类。 ButtonShared 类用于声明具有相同样式的相关按钮组。 ButtonShared 类包含所有按钮机制,Button 对象是具有自己的 ButtonData 成员而不是共享 ButtonData 成员的 ButtonShared 对象。

struct ButtonData {
public:
    ButtonData(unsigned short sizeWidth = 64, unsigned short sizeHigh = 40)
    {
        //the  button size
        x_size = sizeWidth;
        y_size = sizeHigh;
        //the button  abort color
        edge_up_color = 0xffff;    // RGB565 value for white
        edge_down_color = 0x6b4d;
        button_color = 0x4898;
        font_color = 0xffff;    // RGB565 value for white
                                       //the  botton moder 0--cube_button  1--circle_button
        botton_moder = 0;
    }

    //the  button size
    unsigned char   x_size;
    unsigned char   y_size;
    //the  button  abort color
    TFTLCD::TftColor    edge_up_color;
    TFTLCD::TftColor    edge_down_color;
    TFTLCD::TftColor    button_color;
    TFTLCD::TftColor    font_color;
    //the  botton moder 0--cube_button , 1--circle_button
    bool            botton_moder;
};


class  ButtonShared
{
public:
    ButtonShared(ButtonData &buttonData) : myData(&buttonData)
    {
    }

    ButtonShared() : myData(nullptr)
    {
    }

    bool setSharedData(ButtonData &buttonData) { myData = &buttonData; return 1; }
    bool drawButton(unsigned short _x, unsigned short _y, bool _botton_moder, const char *str, Font & myFont);
    bool drawButton(TFTLCD::TftPos &p, bool _botton_moder, const char *str, Font & myFont);
    bool istouch(unsigned short _x, unsigned short _y);
    bool istouch(void);
    bool isTouchState(void);
    bool pendown(void);
    bool penup(void);
    /*if you want  to change the butom size or the color,you can use  the  follow function to achieve your purpose,
    but you  must do it before use the drawbutton() function;also  if you  always change the auto value ,you can change the button() function*/
    void resetsize(unsigned char _x_size, unsigned char _y_size);
    void resetcolor(TFTLCD::TftColor _edge_up_color, TFTLCD::TftColor _edge_down_color, TFTLCD::TftColor _button_color, TFTLCD::TftColor _font_color);

private:
    ButtonData *myData;

    // following data is unique to each button and can not be shared
    // between buttons.
    //the  position(x,y);
    unsigned short  x;
    unsigned short  y;
    unsigned char   penDownFlag;      // set by successful istouch() call or when the pendown() function is called. cleared when the penup() function is called.
};

class  Button : public ButtonShared
{
public:
    Button(unsigned short sizeWidth = 64, unsigned short sizeHigh = 40) : localData(sizeWidth, sizeHigh)
    {
        setSharedData(localData);
    }
    
private:
    ButtonData localData;
};

【讨论】:

  • 还有一点需要注意——如果字体大小有问题,并且您不反对“块状”字符,也许您可​​以在途中通过“2x 放大镜”运行您的 8x8 字符到屏幕上......你仍然会有方形字符,它们会是块状的,但它们会是两倍宽和两倍高。过去我用“更大和像素化”的低分辨率图形做过类似的事情。
  • @TomServo 我添加了一张使用修改后的 KeDei TFT 库在 3.5" TFT LCD 显示器上使用当前库的 UI 的照片。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-08
  • 1970-01-01
相关资源
最近更新 更多