今天有人問題一個問題, 覺得有點意思, 所以動手做了一下, 如何在ESP32上同時使用RFID跟SD卡. 兩個介面都是使用 SPI 通訊, 所以重點是在於如何切換 CS 腳. 以前的經驗是, SD 會跟 W5100 網卡衝突, 要自行切換 CS 腳, 不過新版的 SD 驅動已經沒有這個問題了.

使用 arduino 的 SD 範例 ReadWrite 測試, 發現原本在 UNO 可用, 在 ESP32 即使配合更改 CS 接腳, 也是無法使用, 查看編譯過程, 可以看到以下訊息:

使用程式庫SPI、版本1.0,位於資料夾:C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\SPI
使用程式庫SD、版本1.0.5,位於資料夾:C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\SD
使用程式庫FS、版本1.0,位於資料夾:C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\FS

在 arduino IDE 選用 ESP32 晶片時, 會連結 C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\SD  這個程式庫, 此時原本 arduino 的 SD 範例無法正確執行.

順便一提, 如果搜尋相關議題, 會看到有人說要在某隻腳加電阻, 基本上這是錯誤的解法.

以下是本次的修改:

關閉 ESP32 的 SD 程式庫

修改檔案 C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\SD\library.properties, 將 architectures=esp32 這行改成其他字串, 例如 esp88

修改 Arduino 的 SD 程式庫

查看編譯過程, 稍微排版一下看得比較清楚:

 "C:\\Users\\user\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\xtensa-esp32-elf-gcc\\1.22.0-80-g6c4433a-5.2.0/bin/xtensa-esp32-elf-g++"
-DESP_PLATFORM "-DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\""
-DHAVE_CONFIG_H -DGCC_NOT_5_2_0=0
-DWITH_POSIX
"-IC:\\Users\\user\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\1.0.4/tools/sdk/include/config"
"-IC:\\Users\\user\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\1.0.4/tools/sdk/include/app_trace"
"-IC:\\Users\\user\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\1.0.4/tools/sdk/include/app_update"
......

-DF_CPU=240000000L
-DARDUINO=10813
-DARDUINO_ESP32_DEV
-DARDUINO_ARCH_ESP32
"-DARDUINO_BOARD=\"ESP32_DEV\""
"-DARDUINO_VARIANT=\"esp32\""
-DESP32
-DCORE_DEBUG_LEVEL=0
......

可以看到有用 -D 定義了 ARDUINO_ESP32_DEV, ARDUINO_ARCH_ESP32... 等符號.

在這裡可修改檔案: C:\Program Files (x86)\Arduino\libraries\SD\src\utility\Sd2PinMap.h,替 ESP32 定義 SPI 接腳, 這裡選用 ARDUINO_ARCH_ESP32 作為編譯條件判斷:

...

#endif	// Arduino ARC
#elif defined (ARDUINO_ARCH_ESP32)
  #include <Arduino.h>
  // Two Wire (aka I2C) ports
  //uint8_t const SDA_PIN = 21;
  //uint8_t const SCL_PIN = 22;

  // SPI port
  //uint8_t const SS_PIN = 5;
  uint8_t const MOSI_PIN = 23;
  uint8_t const MISO_PIN = 19;
  uint8_t const SCK_PIN = 18;
#else
...

 

從軟體堆疊結構來看, SD 下層是 FS, FS下層才是 SPI, 所以 SPI 使用 ESP32的就可以了

 

原始碼在 https://github.com/ghostyguo/ESP32_RC522_SD
YouTube demo: https://www.youtube.com/watch?v=JWypqkTJkaU

 

 

 

arrow
arrow
    文章標籤
    ESP32
    全站熱搜

    ghostyguo 發表在 痞客邦 留言(0) 人氣()