当前位置:   article > 正文

Arduino 合宙 ESP32 S3 + OV2640 实现低成本SD存储卡相机(ESP32连接SD模块引脚)_esp 32 sd卡如何改引脚

esp 32 sd卡如何改引脚

合宙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连接

  1. //SDCard
  2. #include <SD.h>
  3. #include <SPI.h>
  4. SPIClass sdSPI(HSPI); // 使用vspi模式会报错
  5. #define SD_MISO 17
  6. #define SD_MOSI 16
  7. #define SD_SCLK 18
  8. #define SD_CS 14
  9. void SDCheck() { // 测试SD卡连接
  10. uint8_t cardType = SD.cardType();
  11. if (cardType == CARD_NONE)
  12. {
  13. Serial.println("未连接存储卡");
  14. return;
  15. }
  16. else if (cardType == CARD_MMC)
  17. {
  18. Serial.println("挂载了MMC卡");
  19. }
  20. else if (cardType == CARD_SD)
  21. {
  22. Serial.println("挂载了SDSC卡");
  23. }
  24. else if (cardType == CARD_SDHC)
  25. {
  26. Serial.println("挂载了SDHC卡");
  27. }
  28. else
  29. {
  30. Serial.println("挂载了未知存储卡");
  31. }
  32. Serial.printf("存储卡总大小是: %lluMB \n", SD.cardSize() / (1024 * 1024)); // "/ (1024 * 1024)"可以换成">> 20"
  33. Serial.printf("文件系统总大小是: %lluB \n", SD.totalBytes());
  34. Serial.printf("文件系统已用大小是: %lluB \n", SD.usedBytes());
  35. }
  36. void setup() {
  37. bool SDstart = false;
  38. Serial.begin(115200);
  39. sdSPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
  40. if (!SD.begin(SD_CS, sdSPI))
  41. {
  42. Serial.println("存储卡挂载失败");
  43. return;
  44. }
  45. SDCheck();

 相机部分配置:

  1. //Cam
  2. #include "esp_camera.h"
  3. #include "esp_timer.h"
  4. #include "soc/soc.h" // Disable brownour problems
  5. #include "soc/rtc_cntl_reg.h" // Disable brownour problems
  6. //cam gpio
  7. #define PWDN_GPIO_NUM -1
  8. #define RESET_GPIO_NUM -1
  9. #define XCLK_GPIO_NUM 39
  10. #define SIOD_GPIO_NUM 21
  11. #define SIOC_GPIO_NUM 46
  12. #define Y2_GPIO_NUM 34
  13. #define Y3_GPIO_NUM 47
  14. #define Y4_GPIO_NUM 48
  15. #define Y5_GPIO_NUM 33
  16. #define Y6_GPIO_NUM 35
  17. #define Y7_GPIO_NUM 37
  18. #define Y8_GPIO_NUM 38
  19. #define Y9_GPIO_NUM 40
  20. #define VSYNC_GPIO_NUM 42
  21. #define HREF_GPIO_NUM 41
  22. #define PCLK_GPIO_NUM 36
  23. void setup() { // 相机配置
  24. camera_config_t config;
  25. config.ledc_channel = LEDC_CHANNEL_0;
  26. config.ledc_timer = LEDC_TIMER_0;
  27. config.pin_d0 = Y2_GPIO_NUM;
  28. config.pin_d1 = Y3_GPIO_NUM;
  29. config.pin_d2 = Y4_GPIO_NUM;
  30. config.pin_d3 = Y5_GPIO_NUM;
  31. config.pin_d4 = Y6_GPIO_NUM;
  32. config.pin_d5 = Y7_GPIO_NUM;
  33. config.pin_d6 = Y8_GPIO_NUM;
  34. config.pin_d7 = Y9_GPIO_NUM;
  35. config.pin_xclk = XCLK_GPIO_NUM;
  36. config.pin_pclk = PCLK_GPIO_NUM;
  37. config.pin_vsync = VSYNC_GPIO_NUM;
  38. config.pin_href = HREF_GPIO_NUM;
  39. config.pin_sccb_sda = SIOD_GPIO_NUM;
  40. config.pin_sccb_scl = SIOC_GPIO_NUM;
  41. config.pin_pwdn = PWDN_GPIO_NUM;
  42. config.pin_reset = RESET_GPIO_NUM;
  43. config.xclk_freq_hz = 20000000;
  44. config.frame_size = FRAMESIZE_SVGA;
  45. config.pixel_format = PIXFORMAT_JPEG;
  46. // config.grab_mode = CAMERA_GRAB_LATEST;
  47. config.grab_mode = config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
  48. config.fb_location = CAMERA_FB_IN_DRAM;
  49. config.jpeg_quality = 30;
  50. config.fb_count = 1; // 没有psram建议写1
  51. // Camera init
  52. esp_err_t err = esp_camera_init(&config);
  53. if (err != ESP_OK) {
  54. Serial.printf("Camera init failed with error 0x%x", err);
  55. return;
  56. }
  57. }

获取图片帧函数:

  1. void getimg(){
  2. camera_fb_t *fb = NULL;
  3. fb = esp_camera_fb_get();
  4. // if (!fb)
  5. // {
  6. // Serial.println("Camera capture failed");
  7. // return;
  8. // }
  9. // else
  10. // {
  11. // Serial.println("Camera Captured");
  12. // }
  13. String filePath = dirPath + "/" + String(count) + ".jpg";
  14. // Serial.println(filePath);
  15. File file = SD.open(filePath,FILE_WRITE);
  16. if(file){
  17. file.write(fb->buf,fb -> len);
  18. }
  19. file.close();
  20. count ++;
  21. esp_camera_fb_return(fb);
  22. fb = NULL;
  23. }

SD卡中文件夹存储代码,合宙这块板貌似没有板载RTC,获取不了准确的时间,而且不连接WiFi,所以只能计数命名

  1. void setup() {
  2. bool SDstart = false;
  3. Serial.begin(115200);
  4. sdSPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
  5. if (!SD.begin(SD_CS, sdSPI))
  6. {
  7. Serial.println("存储卡挂载失败");
  8. return;
  9. }else{
  10. while (!SD.exists("/Camera")) {
  11. SD.mkdir("/Camera");
  12. SDstart = true;
  13. Serial.print(".");
  14. }
  15. if(!SPIFFS.begin()){
  16. Serial.println("mount SPIFFS failed!");
  17. }else {
  18. if(!SPIFFS.exists("/Statue")){
  19. SPIFFS.mkdir("/Statue");
  20. File file = SPIFFS.open("/Statue",FILE_WRITE);
  21. file.write(1);
  22. file.close();
  23. }
  24. File file = SPIFFS.open("/Statue",FILE_READ);
  25. if(file.read() == 1){
  26. file = SPIFFS.open("/Statue",FILE_WRITE);
  27. file.write(0);
  28. file.close();
  29. Serial.println("start");
  30. } else {
  31. file = SPIFFS.open("/Statue",FILE_WRITE);
  32. file.write(1);
  33. file.close();
  34. Serial.println("stop");
  35. while (1);
  36. }
  37. if(SDstart == true){
  38. file = SPIFFS.open("/count.txt",FILE_WRITE);
  39. file.println("1");
  40. file.close();
  41. }else{
  42. if(!SPIFFS.exists("/count.txt")){
  43. Serial.println("create file Success!");
  44. file = SPIFFS.open("/count.txt",FILE_WRITE);
  45. file.println((String)fileCount);
  46. Serial.println(fileCount);
  47. file.close();
  48. }else{
  49. Serial.println("file exist!");
  50. File file = SPIFFS.open("/count.txt",FILE_READ);
  51. fileCount = atoi(file.readStringUntil('\n').c_str());
  52. file.close();
  53. Serial.println(fileCount);
  54. file = SPIFFS.open("/count.txt",FILE_WRITE);
  55. file.println(String(++fileCount));
  56. file.close();
  57. }
  58. }
  59. }
  60. SPIFFS.end();
  61. dirPath = "/Camera/" + (String)fileCount;
  62. while (!SD.exists(dirPath.c_str())) {
  63. SD.mkdir(dirPath.c_str());
  64. Serial.print(".");
  65. }
  66. }

完整代码:

  1. //SDCard
  2. #include <SD.h>
  3. #include <SPI.h>
  4. //File
  5. #include "SPIFFS.h"
  6. //Cam
  7. #include "esp_camera.h"
  8. #include "esp_timer.h"
  9. #include "soc/soc.h" // Disable brownour problems
  10. #include "soc/rtc_cntl_reg.h" // Disable brownour problems
  11. SPIClass sdSPI(HSPI);
  12. #define SD_MISO 17
  13. #define SD_MOSI 16
  14. #define SD_SCLK 18
  15. #define SD_CS 14
  16. //cam gpio
  17. #define PWDN_GPIO_NUM -1
  18. #define RESET_GPIO_NUM -1
  19. #define XCLK_GPIO_NUM 39
  20. #define SIOD_GPIO_NUM 21
  21. #define SIOC_GPIO_NUM 46
  22. #define Y2_GPIO_NUM 34
  23. #define Y3_GPIO_NUM 47
  24. #define Y4_GPIO_NUM 48
  25. #define Y5_GPIO_NUM 33
  26. #define Y6_GPIO_NUM 35
  27. #define Y7_GPIO_NUM 37
  28. #define Y8_GPIO_NUM 38
  29. #define Y9_GPIO_NUM 40
  30. #define VSYNC_GPIO_NUM 42
  31. #define HREF_GPIO_NUM 41
  32. #define PCLK_GPIO_NUM 36
  33. String dirPath;
  34. uint32_t count = 0;
  35. uint16_t fileCount = 1;
  36. void getimg(){
  37. camera_fb_t *fb = NULL;
  38. fb = esp_camera_fb_get();
  39. String filePath = dirPath + "/" + String(count) + ".jpg";
  40. // Serial.println(filePath);
  41. File file = SD.open(filePath,FILE_WRITE);
  42. if(file){
  43. file.write(fb->buf,fb -> len);
  44. }
  45. file.close();
  46. count ++;
  47. esp_camera_fb_return(fb);
  48. fb = NULL;
  49. }
  50. void setup() {
  51. bool SDstart = false;
  52. Serial.begin(115200);
  53. sdSPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
  54. if (!SD.begin(SD_CS, sdSPI))
  55. {
  56. Serial.println("存储卡挂载失败");
  57. return;
  58. }else{
  59. while (!SD.exists("/Camera")) {
  60. SD.mkdir("/Camera");
  61. SDstart = true;
  62. Serial.print(".");
  63. }
  64. if(!SPIFFS.begin()){
  65. Serial.println("mount SPIFFS failed!");
  66. }else {
  67. if(!SPIFFS.exists("/Statue")){
  68. SPIFFS.mkdir("/Statue");
  69. File file = SPIFFS.open("/Statue",FILE_WRITE);
  70. file.write(1);
  71. file.close();
  72. }
  73. File file = SPIFFS.open("/Statue",FILE_READ);
  74. if(file.read() == 1){
  75. file = SPIFFS.open("/Statue",FILE_WRITE);
  76. file.write(0);
  77. file.close();
  78. Serial.println("start");
  79. } else {
  80. file = SPIFFS.open("/Statue",FILE_WRITE);
  81. file.write(1);
  82. file.close();
  83. Serial.println("stop");
  84. while (1);
  85. }
  86. if(SDstart == true){
  87. file = SPIFFS.open("/count.txt",FILE_WRITE);
  88. file.println("1");
  89. file.close();
  90. }else{
  91. if(!SPIFFS.exists("/count.txt")){
  92. Serial.println("create file Success!");
  93. file = SPIFFS.open("/count.txt",FILE_WRITE);
  94. file.println((String)fileCount);
  95. Serial.println(fileCount);
  96. file.close();
  97. }else{
  98. Serial.println("file exist!");
  99. File file = SPIFFS.open("/count.txt",FILE_READ);
  100. fileCount = atoi(file.readStringUntil('\n').c_str());
  101. file.close();
  102. Serial.println(fileCount);
  103. file = SPIFFS.open("/count.txt",FILE_WRITE);
  104. file.println(String(++fileCount));
  105. file.close();
  106. }
  107. }
  108. }
  109. SPIFFS.end();
  110. dirPath = "/Camera/" + (String)fileCount;
  111. while (!SD.exists(dirPath.c_str())) {
  112. SD.mkdir(dirPath.c_str());
  113. Serial.print(".");
  114. }
  115. }
  116. camera_config_t config;
  117. config.ledc_channel = LEDC_CHANNEL_0;
  118. config.ledc_timer = LEDC_TIMER_0;
  119. config.pin_d0 = Y2_GPIO_NUM;
  120. config.pin_d1 = Y3_GPIO_NUM;
  121. config.pin_d2 = Y4_GPIO_NUM;
  122. config.pin_d3 = Y5_GPIO_NUM;
  123. config.pin_d4 = Y6_GPIO_NUM;
  124. config.pin_d5 = Y7_GPIO_NUM;
  125. config.pin_d6 = Y8_GPIO_NUM;
  126. config.pin_d7 = Y9_GPIO_NUM;
  127. config.pin_xclk = XCLK_GPIO_NUM;
  128. config.pin_pclk = PCLK_GPIO_NUM;
  129. config.pin_vsync = VSYNC_GPIO_NUM;
  130. config.pin_href = HREF_GPIO_NUM;
  131. config.pin_sccb_sda = SIOD_GPIO_NUM;
  132. config.pin_sccb_scl = SIOC_GPIO_NUM;
  133. config.pin_pwdn = PWDN_GPIO_NUM;
  134. config.pin_reset = RESET_GPIO_NUM;
  135. config.xclk_freq_hz = 20000000;
  136. config.frame_size = FRAMESIZE_SVGA;
  137. config.pixel_format = PIXFORMAT_JPEG;
  138. config.grab_mode = config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
  139. config.fb_location = CAMERA_FB_IN_DRAM;
  140. config.jpeg_quality = 30;
  141. config.fb_count = 1;
  142. // Camera init
  143. esp_err_t err = esp_camera_init(&config);
  144. if (err != ESP_OK) {
  145. Serial.printf("Camera init failed with error 0x%x", err);
  146. return;
  147. }
  148. }
  149. void loop() {
  150. getimg();
  151. delay(100);
  152. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/471133
推荐阅读
相关标签
  

闽ICP备14008679号