2

我需要减少与用于 Arduino Uno 和 ATmega 2560 的 Osoyoo 3.5" TFT 触摸屏显示扩展板一起使用的KeDei TFT 库所需的内存。当我尝试编写一个使用 KeDei 库的 TFT 显示器的简单 Arduino 应用程序时,大多数Arduino 上的可用内存由库本身占用。

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

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

我所做的一件事是通过消除小写字母并将小写字母转换为大写字母来减少字符数。这会导致表格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.

我可以做些什么来进一步减少显示字体所需的内存?是否有另一种使用较少内存的位图字体?

4

1 回答 1

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,许可证为 Public Domain。

使用预处理器指令选择要使用的字体表并从 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 像素。

照片显示了 8x8 字体和 16x16 字体之间的视觉大小比较。

笔记

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

所做的更改之一是允许文本为双倍高和/或双倍宽。此图像是当前版本的扫描仪/比例模拟器,显示了双倍高和双倍宽的文本以及双倍高的文本之间的样式差异。

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

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

3.5 的图像

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

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;
};
于 2021-04-26T01:54:46.120 回答