esp32 SD卡读写测试——读取WiFi信息连接网络

编译环境:arduino 编写
开发板选择:esp32 cam开发板

  手里恰好有一块esp32 cam的开发板,随使用了文件系统驱动SD卡,方便后期使用,使用SDMMC接口访问SD卡 。
  在文件读取部分稍微处理了一下,读取SD卡wifi信息进行连接,这样避免配网或者修改wifi信息,示例代码读取WiFi并且连接。
  使用这玩意,SD卡DATA1 和LED灯使用一个I/O口,这就有点离谱,只要有数据读写,灯就被点亮。

此原理图来源esp32 cam开发板:
在这里插入图片描述
外接47K上拉电阻。U0TXD和T0RXD用于烧录固件。

ESP-32S ModuleSD
14(GPIO12)HS2_DATA2(DATA2)
16(GPIO13)HS2_DATA2(CD/DATA3)
23(SDI/SD1)HS2_CMD(CMD)
13(GPIO14)HS2_CLK(CLK)
24(GPIO2)HS2_DATA0(DATA0)
26(GPIO4)HS2_DATA1(DATA1)

1、文件操作常用API

包含在:FS.cpp 文件中,有意向可以查看。
打开文件:
在这里插入图片描述

File FS::open(const String& path, const char* mode)
File FS::open(const char* path, const char* mode)

path:为打开路径,mode:为打开方式,mode可选FILE_READFILE_WRITEFILE_APPEND,即只读模式、写入模式、追加模式;

写入文件:

File print(const char * message)
message:要写入的信息
size_t File::write(uint8_t c)
size_t File::write(const uint8_t *buf, size_t size)

读取文件:
在这里插入图片描述

int File::available()

返回当前指针下可读取字节数;

int File::read()
size_t File::read(uint8_t* buf, size_t size)
size_t readBytes(char *buffer, size_t length)

读取数据,该操作会移动文件指针;

关闭当前文件:
在这里插入图片描述

void File::close()

在不移动文件指针的情况下读取一个字节数据:

int File::peek()

移动文件指针,mode可选SeekSet、SeekCur、SeekEnd,分别为正常移动、移动到文件头、移动到文件尾:

bool File::seek(uint32_t pos, SeekMode mode)

返回当前文件指针位置:

size_t File::position() const

返回当前文件的大小:

size_t File::size() const

返回当前文件是否有效:

File::operator bool() const

返回最后修改文件时间:

time_t File::getLastWrite()

返回当前文件名:

const char* File::name() const

返回当前文件是否为目录:

boolean File::isDirectory(void)

打开下一个文件:

File File::openNextFile(const char* mode)

返回到目录中首文件位置:

void File::rewindDirectory(void)

检查文件或路径是否存在:

bool FS::exists(const char* path)
bool FS::exists(const String& path)

移除文件:
在这里插入图片描述

bool FS::remove(const char* path)
bool FS::remove(const String& path)

重命名文件,依次输入旧的、新的包含完整文件名的路径:
在这里插入图片描述

bool FS::rename(const char* pathFrom, const char* pathTo)
bool FS::rename(const String& pathFrom, const String& pathTo)

创建目录:
在这里插入图片描述

bool FS::mkdir(const char *path)
bool FS::mkdir(const String &path)

删除目录:
在这里插入图片描述

bool FS::rmdir(const char *path)
bool FS::rmdir(const String &path)

判断指定的目录是否是加载点:

void FSImpl::mountpoint(const char * mp)
const char * FSImpl::mountpoint()

如果是挂载点返回0,如果不是就返回非0

2、SPIFFS文件系统

包含在:SD_MMC.h头文件
挂载文件系统:

bool begin(const char * mountpoint="/sdcard", bool mode1bit=false);

取消挂载文件系统:

void end()

检测SD卡大小:

uint64_t cardSize();

格式化文件系统:

bool format()

返回文件系统总字节数:

size_t totalBytes()

返回文件系统已用字节数:

size_t usedBytes()

3 、读取SD卡WiFi并且连接

新建一个“/WiFi/WiFi.txt ”路径用于保存WiFi信息
在这里插入图片描述
写入WiFi信息:
在这里插入图片描述

看清楚自己建立的WiFi信息路径。
首先在代码里面添加变量,保存WiFi信息:


const char* ssid     = "";
const char* password = "";

其次读取SD卡信息:
定义一些变量,处理读取信息。

char seps[]= "\r\n";
char  *stass;
char *buf[3];
int i=0;
String comdata = "";
//stass = NULL;
//读取 文件
void readFile(fs::FS &fs, const char * path){
    Serial.printf("Reading file: %s\n", path);

    File file = fs.open(path,FILE_READ);//FILE_READ 只读模式
    if(!file){
        Serial.println("Failed to open file for reading");
        return;
    }

    Serial.print("Read from file: ");
    while(file.available()){
      comdata += char(file.read());//方便读取使用
      //Serial.write(file.read()); //发送字节
    }
    file.close();
    Serial.println(comdata);
    char * p=(char*)comdata.c_str();
    stass=strtok(p,seps);
    //Serial.println(stass);
    /* 继续获取其他的子字符串 */
   while( stass != NULL ) {
    buf[i] = stass;
    ++i;
    stass = strtok(NULL, seps);
   }
    ssid = buf[0];
    password = buf[1];
   Serial.println(buf[0]);
   Serial.println(buf[1]);
      
}

4、完整示例代码

  完整代码包含文件夹的创建、文件夹删除、文件读取、文件写入、文件名修改、移除文件,WiFi信息读取连接。

#include "Arduino.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include <time.h> 
#include <WiFi.h>

const char* ssid     = "";
const char* password = "";

long timezone = 1; 
byte daysavetime = 1;

// 显示全部文件名称
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.print (file.name());
            time_t t= file.getLastWrite();
            struct tm * tmstruct = localtime(&t);
            Serial.printf("  LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec);
            if(levels){
                listDir(fs, file.name(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("  SIZE: ");
            Serial.print(file.size());
            time_t t= file.getLastWrite();
            struct tm * tmstruct = localtime(&t);
            Serial.printf("  LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec);
        }
        file = root.openNextFile();
    }
}

//新建文件夹
void createDir(fs::FS &fs, const char * path){
    Serial.printf("Creating Dir: %s\n", path);
    if(fs.mkdir(path)){
        Serial.println("Dir created");
    } else {
        Serial.println("mkdir failed");
    }
}
// 移除文件夹
void removeDir(fs::FS &fs, const char * path){
    Serial.printf("Removing Dir: %s\n", path);
    if(fs.rmdir(path)){
        Serial.println("Dir removed");
    } else {
        Serial.println("rmdir failed");
    }
}
char seps[]= "\r\n";
char  *stass;
char *buf[3];
int i=0;
String comdata = "";
//stass = NULL;
//读取 文件
void readFile(fs::FS &fs, const char * path){
    Serial.printf("Reading file: %s\n", path);

    File file = fs.open(path,FILE_READ);//FILE_READ 只读模式
    if(!file){
        Serial.println("Failed to open file for reading");
        return;
    }

    Serial.print("Read from file: ");
    while(file.available()){
      comdata += char(file.read());//方便读取使用
      //Serial.write(file.read()); //发送字节
    }
    file.close();
    Serial.println(comdata);
    //char string[]=comdata;
    char * p=(char*)comdata.c_str();
    stass=strtok(p,seps);
    //Serial.println(stass);
    /* 继续获取其他的子字符串 */
   while( stass != NULL ) {
    buf[i] = stass;
    ++i;
    stass = strtok(NULL, seps);
   }
    ssid = buf[0];
    password = buf[1];
   Serial.println(buf[0]);
   Serial.println(buf[1]);
      
}

//写入文件
void writeFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Writing file: %s\n", path);

    File file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }
    if(file.print(message)){
        Serial.println("File written");
    } else {
        Serial.println("Write failed");
    }
    file.close();
}
// 追加文件
void appendFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Appending to file: %s\n", path);

    File file = fs.open(path, FILE_APPEND);
    if(!file){
        Serial.println("Failed to open file for appending");
        return;
    }
    if(file.print(message)){
        Serial.println("Message appended");
    } else {
        Serial.println("Append failed");
    }
    file.close();
}
// 修改名字
void renameFile(fs::FS &fs, const char * path1, const char * path2){
    Serial.printf("Renaming file %s to %s\n", path1, path2);
    if (fs.rename(path1, path2)) {
        Serial.println("File renamed");
    } else {
        Serial.println("Rename failed");
    }
}
// 删除
void deleteFile(fs::FS &fs, const char * path){
    Serial.printf("Deleting file: %s\n", path);
    if(fs.remove(path)){
        Serial.println("File deleted");
    } else {
        Serial.println("Delete failed");
    }
}

void setup(){
    Serial.begin(115200);
    // We start by connecting to a WiFi network
    Serial.println();
    
    
    if(!SD_MMC.begin()){
        Serial.println("Card Mount Failed");
        return;
    }
    uint8_t cardType = SD_MMC.cardType();

    if(cardType == CARD_NONE){
        Serial.println("No SD card attached");
        return;
    }

    Serial.print("SD Card Type: ");
    //输出SD卡类型
    if(cardType == CARD_MMC){
        Serial.println("MMC");
    } else if(cardType == CARD_SD){
        Serial.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
    } else {
        Serial.println("UNKNOWN");
    }

    uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024);
    Serial.printf("SD Card Size: %lluMB\n", cardSize);
    listDir(SD_MMC, "/", 0);
    removeDir(SD_MMC, "/mydir");
    createDir(SD_MMC, "/mydir");
    deleteFile(SD_MMC, "/mydir/hello.txt");
    writeFile(SD_MMC, "/mydir/hello.txt", "Hello World!\r\n");
    appendFile(SD_MMC, "/mydir/hello.txt", "Moonbeam");
	  listDir(SD_MMC, "/", 0);
    readFile(SD_MMC, "/WiFi/WiFi.txt");
    SD_MMC.end();// 取消挂载SD卡
    pinMode(4, OUTPUT); //Light
    digitalWrite(4, LOW);
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    Serial.println("Contacting Time Server");
    configTime(3600*timezone, daysavetime*3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
    struct tm tmstruct ;
    delay(2000);
    tmstruct.tm_year = 0;
    getLocalTime(&tmstruct, 5000);
    Serial.printf("\nNow is : %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct.tm_year)+1951,( tmstruct.tm_mon)+1, (tmstruct.tm_mday)+25,(tmstruct.tm_hour)+13 , (tmstruct.tm_min)+36, tmstruct.tm_sec);
    Serial.println("");
}
void loop(){

}

5、效果展示

在这里插入图片描述

  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值