赞
踩
合宙ESP32 S3 板载16M flash,8m psram和一个FPC相机接口,价格却不到30元,无疑比价格将近50元的第三方ESP32 S3和将近30的ESP32 Cam更具性价比。
但是虽然板载FPC,由于接口冲突,导致相机与psram不能同时开启,作为ESP32 Cam的替代品来看,还缺少了板载SD卡,而且作为一块发布不久的开发板,网上资料资料非常少,甚至连乐鑫的ESP32 S3开发板关于如何用Arduino配置连接SD卡模块的资料都很少。
但是经过多次试错终于发现了连接方法,Arduino ESP32中默认使用VSPI模式连接,而且官方示例中也没有怎么定义引脚,但是S3中用VSPI模式连接会报错,只能用HSPI连接
- //SDCard
- #include <SD.h>
- #include <SPI.h>
-
- SPIClass sdSPI(HSPI); // 使用vspi模式会报错
- #define SD_MISO 17
- #define SD_MOSI 16
- #define SD_SCLK 18
- #define SD_CS 14
-
- void SDCheck() { // 测试SD卡连接
- uint8_t cardType = SD.cardType();
-
- if (cardType == CARD_NONE)
- {
- Serial.println("未连接存储卡");
- return;
- }
- else 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("挂载了未知存储卡");
- }
- Serial.printf("存储卡总大小是: %lluMB \n", SD.cardSize() / (1024 * 1024)); // "/ (1024 * 1024)"可以换成">> 20"
- Serial.printf("文件系统总大小是: %lluB \n", SD.totalBytes());
- Serial.printf("文件系统已用大小是: %lluB \n", SD.usedBytes());
- }
-
- void setup() {
- bool SDstart = false;
- Serial.begin(115200);
- sdSPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
- if (!SD.begin(SD_CS, sdSPI))
- {
- Serial.println("存储卡挂载失败");
- return;
- }
-
- SDCheck();

相机部分配置:
- //Cam
- #include "esp_camera.h"
- #include "esp_timer.h"
- #include "soc/soc.h" // Disable brownour problems
- #include "soc/rtc_cntl_reg.h" // Disable brownour problems
-
- //cam gpio
- #define PWDN_GPIO_NUM -1
- #define RESET_GPIO_NUM -1
- #define XCLK_GPIO_NUM 39
- #define SIOD_GPIO_NUM 21
- #define SIOC_GPIO_NUM 46
-
- #define Y2_GPIO_NUM 34
- #define Y3_GPIO_NUM 47
- #define Y4_GPIO_NUM 48
- #define Y5_GPIO_NUM 33
- #define Y6_GPIO_NUM 35
- #define Y7_GPIO_NUM 37
- #define Y8_GPIO_NUM 38
- #define Y9_GPIO_NUM 40
-
- #define VSYNC_GPIO_NUM 42
- #define HREF_GPIO_NUM 41
- #define PCLK_GPIO_NUM 36
-
- void setup() { // 相机配置
- camera_config_t config;
- config.ledc_channel = LEDC_CHANNEL_0;
- config.ledc_timer = LEDC_TIMER_0;
- config.pin_d0 = Y2_GPIO_NUM;
- config.pin_d1 = Y3_GPIO_NUM;
- config.pin_d2 = Y4_GPIO_NUM;
- config.pin_d3 = Y5_GPIO_NUM;
- config.pin_d4 = Y6_GPIO_NUM;
- config.pin_d5 = Y7_GPIO_NUM;
- config.pin_d6 = Y8_GPIO_NUM;
- config.pin_d7 = Y9_GPIO_NUM;
- config.pin_xclk = XCLK_GPIO_NUM;
- config.pin_pclk = PCLK_GPIO_NUM;
- config.pin_vsync = VSYNC_GPIO_NUM;
- config.pin_href = HREF_GPIO_NUM;
- config.pin_sccb_sda = SIOD_GPIO_NUM;
- config.pin_sccb_scl = SIOC_GPIO_NUM;
- config.pin_pwdn = PWDN_GPIO_NUM;
- config.pin_reset = RESET_GPIO_NUM;
- config.xclk_freq_hz = 20000000;
- config.frame_size = FRAMESIZE_SVGA;
- config.pixel_format = PIXFORMAT_JPEG;
- // config.grab_mode = CAMERA_GRAB_LATEST;
- config.grab_mode = config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
- config.fb_location = CAMERA_FB_IN_DRAM;
- config.jpeg_quality = 30;
- config.fb_count = 1; // 没有psram建议写1
-
- // Camera init
- esp_err_t err = esp_camera_init(&config);
- if (err != ESP_OK) {
- Serial.printf("Camera init failed with error 0x%x", err);
- return;
- }
- }

获取图片帧函数:
- void getimg(){
- camera_fb_t *fb = NULL;
- fb = esp_camera_fb_get();
-
- // if (!fb)
- // {
- // Serial.println("Camera capture failed");
- // return;
- // }
- // else
- // {
- // Serial.println("Camera Captured");
- // }
-
- String filePath = dirPath + "/" + String(count) + ".jpg";
-
- // Serial.println(filePath);
-
- File file = SD.open(filePath,FILE_WRITE);
- if(file){
- file.write(fb->buf,fb -> len);
- }
- file.close();
- count ++;
- esp_camera_fb_return(fb);
- fb = NULL;
- }

SD卡中文件夹存储代码,合宙这块板貌似没有板载RTC,获取不了准确的时间,而且不连接WiFi,所以只能计数命名
- void setup() {
- bool SDstart = false;
- Serial.begin(115200);
- sdSPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
- if (!SD.begin(SD_CS, sdSPI))
- {
- Serial.println("存储卡挂载失败");
- return;
- }else{
- while (!SD.exists("/Camera")) {
- SD.mkdir("/Camera");
- SDstart = true;
- Serial.print(".");
- }
- if(!SPIFFS.begin()){
- Serial.println("mount SPIFFS failed!");
- }else {
- if(!SPIFFS.exists("/Statue")){
- SPIFFS.mkdir("/Statue");
- File file = SPIFFS.open("/Statue",FILE_WRITE);
- file.write(1);
- file.close();
- }
- File file = SPIFFS.open("/Statue",FILE_READ);
- if(file.read() == 1){
- file = SPIFFS.open("/Statue",FILE_WRITE);
- file.write(0);
- file.close();
- Serial.println("start");
- } else {
- file = SPIFFS.open("/Statue",FILE_WRITE);
- file.write(1);
- file.close();
- Serial.println("stop");
- while (1);
- }
- if(SDstart == true){
- file = SPIFFS.open("/count.txt",FILE_WRITE);
- file.println("1");
- file.close();
- }else{
- if(!SPIFFS.exists("/count.txt")){
- Serial.println("create file Success!");
- file = SPIFFS.open("/count.txt",FILE_WRITE);
- file.println((String)fileCount);
- Serial.println(fileCount);
- file.close();
- }else{
- Serial.println("file exist!");
- File file = SPIFFS.open("/count.txt",FILE_READ);
- fileCount = atoi(file.readStringUntil('\n').c_str());
- file.close();
- Serial.println(fileCount);
- file = SPIFFS.open("/count.txt",FILE_WRITE);
- file.println(String(++fileCount));
- file.close();
- }
- }
- }
- SPIFFS.end();
- dirPath = "/Camera/" + (String)fileCount;
- while (!SD.exists(dirPath.c_str())) {
- SD.mkdir(dirPath.c_str());
- Serial.print(".");
- }
- }

完整代码:
- //SDCard
- #include <SD.h>
- #include <SPI.h>
- //File
- #include "SPIFFS.h"
- //Cam
- #include "esp_camera.h"
- #include "esp_timer.h"
- #include "soc/soc.h" // Disable brownour problems
- #include "soc/rtc_cntl_reg.h" // Disable brownour problems
-
- SPIClass sdSPI(HSPI);
- #define SD_MISO 17
- #define SD_MOSI 16
- #define SD_SCLK 18
- #define SD_CS 14
-
- //cam gpio
- #define PWDN_GPIO_NUM -1
- #define RESET_GPIO_NUM -1
- #define XCLK_GPIO_NUM 39
- #define SIOD_GPIO_NUM 21
- #define SIOC_GPIO_NUM 46
-
- #define Y2_GPIO_NUM 34
- #define Y3_GPIO_NUM 47
- #define Y4_GPIO_NUM 48
- #define Y5_GPIO_NUM 33
- #define Y6_GPIO_NUM 35
- #define Y7_GPIO_NUM 37
- #define Y8_GPIO_NUM 38
- #define Y9_GPIO_NUM 40
-
- #define VSYNC_GPIO_NUM 42
- #define HREF_GPIO_NUM 41
- #define PCLK_GPIO_NUM 36
-
- String dirPath;
- uint32_t count = 0;
- uint16_t fileCount = 1;
-
- void getimg(){
- camera_fb_t *fb = NULL;
- fb = esp_camera_fb_get();
- String filePath = dirPath + "/" + String(count) + ".jpg";
- // Serial.println(filePath);
- File file = SD.open(filePath,FILE_WRITE);
- if(file){
- file.write(fb->buf,fb -> len);
- }
- file.close();
- count ++;
- esp_camera_fb_return(fb);
- fb = NULL;
- }
-
- void setup() {
- bool SDstart = false;
- Serial.begin(115200);
- sdSPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
- if (!SD.begin(SD_CS, sdSPI))
- {
- Serial.println("存储卡挂载失败");
- return;
- }else{
- while (!SD.exists("/Camera")) {
- SD.mkdir("/Camera");
- SDstart = true;
- Serial.print(".");
- }
- if(!SPIFFS.begin()){
- Serial.println("mount SPIFFS failed!");
- }else {
- if(!SPIFFS.exists("/Statue")){
- SPIFFS.mkdir("/Statue");
- File file = SPIFFS.open("/Statue",FILE_WRITE);
- file.write(1);
- file.close();
- }
- File file = SPIFFS.open("/Statue",FILE_READ);
- if(file.read() == 1){
- file = SPIFFS.open("/Statue",FILE_WRITE);
- file.write(0);
- file.close();
- Serial.println("start");
- } else {
- file = SPIFFS.open("/Statue",FILE_WRITE);
- file.write(1);
- file.close();
- Serial.println("stop");
- while (1);
- }
- if(SDstart == true){
- file = SPIFFS.open("/count.txt",FILE_WRITE);
- file.println("1");
- file.close();
- }else{
- if(!SPIFFS.exists("/count.txt")){
- Serial.println("create file Success!");
- file = SPIFFS.open("/count.txt",FILE_WRITE);
- file.println((String)fileCount);
- Serial.println(fileCount);
- file.close();
- }else{
- Serial.println("file exist!");
- File file = SPIFFS.open("/count.txt",FILE_READ);
- fileCount = atoi(file.readStringUntil('\n').c_str());
- file.close();
- Serial.println(fileCount);
- file = SPIFFS.open("/count.txt",FILE_WRITE);
- file.println(String(++fileCount));
- file.close();
- }
- }
- }
- SPIFFS.end();
- dirPath = "/Camera/" + (String)fileCount;
- while (!SD.exists(dirPath.c_str())) {
- SD.mkdir(dirPath.c_str());
- Serial.print(".");
- }
- }
- camera_config_t config;
- config.ledc_channel = LEDC_CHANNEL_0;
- config.ledc_timer = LEDC_TIMER_0;
- config.pin_d0 = Y2_GPIO_NUM;
- config.pin_d1 = Y3_GPIO_NUM;
- config.pin_d2 = Y4_GPIO_NUM;
- config.pin_d3 = Y5_GPIO_NUM;
- config.pin_d4 = Y6_GPIO_NUM;
- config.pin_d5 = Y7_GPIO_NUM;
- config.pin_d6 = Y8_GPIO_NUM;
- config.pin_d7 = Y9_GPIO_NUM;
- config.pin_xclk = XCLK_GPIO_NUM;
- config.pin_pclk = PCLK_GPIO_NUM;
- config.pin_vsync = VSYNC_GPIO_NUM;
- config.pin_href = HREF_GPIO_NUM;
- config.pin_sccb_sda = SIOD_GPIO_NUM;
- config.pin_sccb_scl = SIOC_GPIO_NUM;
- config.pin_pwdn = PWDN_GPIO_NUM;
- config.pin_reset = RESET_GPIO_NUM;
- config.xclk_freq_hz = 20000000;
- config.frame_size = FRAMESIZE_SVGA;
- config.pixel_format = PIXFORMAT_JPEG;
- config.grab_mode = config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
- config.fb_location = CAMERA_FB_IN_DRAM;
- config.jpeg_quality = 30;
- config.fb_count = 1;
-
- // Camera init
- esp_err_t err = esp_camera_init(&config);
- if (err != ESP_OK) {
- Serial.printf("Camera init failed with error 0x%x", err);
- return;
- }
- }
-
- void loop() {
- getimg();
- delay(100);
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。