从SD卡读取字体数据
需求
因为NodeMCU自带的闪存实在太小了,顶多存一两张图片就满了,而要把mp3那么多的东西都放到里面显然不合理,所以就决定把东西都放在内存卡里面。sd卡怎么连接nodemcu的文章放在同一个专栏里面了,需要自取。
文件格式设计
要读取文件内容,肯定要设计文件格式,才能写接口来读取。这是我的格式
/ - - - 根目录
- /fonts 存放字体文件,每一个文件名对应该汉字的中文名
- test.txt
- 第一行:字高(height)
- 第二行:字宽(width)
- 剩下的:按十进制存数据(我不会转换16进制),用逗号表示数据结束,最后一个数据后也有逗号
- /imgs 存放图像文件
- /musics 存放音频文件
这个就是我存放的“测”字的数据
读取数据
里面只是单纯把读到的数据全部打印出来,就是这个效果
处理数据
将读取到的数据进行处理,因为是十进制,所以就按照如下代码进行操作,读完存到数据里面,按格式输出即可
#include <SPI.h>
#include <SD.h>
File myFile;
uint8_t testCode[256]{0};
int char_to_int(char c)
{
return int(c-48); //48->0; 57->9
}
int square(int N, int b)
{
int result = 1;
for(int i = 0; i < b; i++)
{
result *= N;
}
return result;
}
int charArr_to_int(char arr[], int num)
{
int result = 0;
int k = square(10,num-1);
for(int i = 0; i < num; i++)
{
result += k * char_to_int(arr[i]);
k /= 10;
}
return result;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println();
Serial.println("Initializing sd card...");
if(!SD.begin(15)) //D8
{
Serial.println("Initialization failed!");
return;
}
Serial.println("reading data...");
if(SD.exists("fonts/test.txt"))
{
myFile = SD.open("fonts/test.txt", FILE_READ);
Serial.println("test.txt:");
int height = 0;
int width = 0;
if(myFile.available())
{
char c1 = myFile.read();
char c2 = myFile.read();
myFile.read(); //read \n
char arr[2] = {c1,c2};
height = charArr_to_int(arr,2);
}
if(myFile.available())
{
char c1 = myFile.read();
char c2 = myFile.read();
myFile.read(); //read \n
char arr[2] = {c1,c2};
width = charArr_to_int(arr,2);
}
int i = 0;
while(myFile.available())
{
int j = 0;
char arr[3];
while(myFile.available())
{
char c = myFile.read();
if((c == '\n') || (c == '\r'))
continue;
else if(c == ',')
break;
else
{
arr[j] = c;
j++;
}
}
testCode[i] = charArr_to_int(arr,j);
i++;
}
myFile.close();
Serial.println("testCode.txt:");
for(int j = 0; j < i; j++)
{
Serial.print(testCode[j]);
Serial.print('\t');
if((j % 8) == 0)
Serial.println();
}
}
else
{
Serial.println("File not exists, print the file system structure");
File root = SD.open("/");
printDirectory(root,0);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
由于printDirectory是库里面自己写的函数,对我这个程序也没什么影响,定义部分就被我删了。代码里面的一些处理都是归纳出来的,没想到一次成功!