隨著接觸越來越多的感測器,在 Arduino 紀錄感測元件接收的數值的同時,把數值儲存下來已經是非常重要的需求。除了透過網路模組送出以外,Arduino 開發板本身並不像 Raspberry Pi 有外接 SD 或 Micro SD 卡的介面,可以儲存在記憶卡上,要寫入資料到 SD卡上,就必須透過 SPI 的介面,才能將感測的資料寫入 SD卡。
- 接線圖
- SD 卡模組連接線路
-
SD 卡模組 Arduino GND GND +5V 5V CS Pin 4 MOSI Pin 11 SCK(CLK) Pin 13 MISO Pin 12 SPI匯流排規定了 4 個保留邏輯訊號介面:(維基百科)
- SCLK (Serial Clock):串行時鐘,由主機發出
- MOSI (Master Output,Slave Input):主機輸出從機輸入訊號,由主機發出
- MISO (Master Input,Slave Output):主機輸入從機輸出訊號,由從機發出
- SS (Slave Selected) 或 Chip Select (CS):由主機發出,低電位有效
- SD Library
-
SD Class
- 初始設定 SD卡及函式庫:SD.begin(cspin)
- cspin (選項):Arduino 連接SD卡模組 SS 或 CS的 Pin腳
- 檢查括號內的檔案名稱是否存在:exists()
- 建立目錄:SD.mkdir(filename)
- 開啟檔案:SD.open(filepath, mode)
- mode:檔案開啟模式
FILE_READ 開啟唯讀檔案,從檔案開始處讀取
FILE_WRITE 開啟讀寫檔案,從檔案最後處開始寫入 - 移除檔案:SD.remove(filename)
- 移除目錄:SD.rmdir(filename)
File Class
- 關閉檔案:file.close()
- 將 data 字串寫到檔案中,不跳行:file.print(data)
- 將 data 字串寫到檔案中,不跳行:file.println(data)
- 將 data 字串寫入檔案中:file.write(data)
- 程式碼
-
#include <SPI.h> #include <SD.h> //--- #include <SdFat.h> //--- SD.h 與 SdFat.h 為不同 Library 所提供,使用時擇一使用 File myFile; //--- SdFat SD; //--- 必須與 SdFat.h 搭配使用 //--- 設定 SD library 功能變數: Sd2Card card; SdVolume volume; SdFile root; const int chipSelect = 4; void setup() { Serial.begin(9600); //--- 開啟通訊串列埠開啟 while (!Serial) {} //--- 等待串列埠連線 //--- 寫入檔案 Serial.print("\nWaiting for SD card ready..."); if (!SD.begin(4)) { Serial.println("Fail!"); return; } kSerial.println("Success!"); //--- 開啟檔案,一次僅能開啟一個檔案 myFile = SD.open("card.txt", FILE_WRITE if (myFile) { //--- 檔案開啟正常 Serial.print("Write to card.txt..."); myFile.println("Test to write data to SD card..."); //--- 繼續寫在檔案後面 myFile.close(); //--- 關閉檔案 Serial.println("Completed!"); } else { // 無法開啟時顯示錯誤 Serial.println("\n open file error"); } //--- 顯示 SD 卡資訊 if (!card.init(SPI_HALF_SPEED, chipSelect)) { Serial.println("initialization failed. Check: SD Card"); return; } else { Serial.println("============= Card Information =================="); } //--- 顯示 SD 卡類型 Serial.print("Card type: "); switch (card.type()) { case SD_CARD_TYPE_SD1: Serial.println("SD1"); break; case SD_CARD_TYPE_SD2: Serial.println("SD2"); break; case SD_CARD_TYPE_SDHC: Serial.println("SDHC"); break; default: Serial.println("Unknow"); } //--- Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32 if (!volume.init(card)) { Serial.println("Could not find FAT16/FAT32 partition."); return; } //--- 顯示類型和 FAT 空間大小 uint32_t volumesize; Serial.print("Volume type is FAT"); Serial.println(volume.fatType(), DEC); Serial.println(); volumesize = volume.blocksPerCluster(); // clusters are collections of blocks volumesize *= volume.clusterCount(); // we'll have a lot of clusters volumesize *= 512; // SD card blocks are always 512 bytes Serial.print("Volume size (bytes): "); Serial.println(volumesize); Serial.print("Volume size (Kbytes): "); volumesize /= 1024; Serial.println(volumesize); Serial.print("Volume size (Mbytes): "); volumesize /= 1024; Serial.println(volumesize); Serial.println("\nFiles found on the card (name, date and size in bytes): "); root.openRoot(volume); //--- list all files in the card with date and size root.ls(LS_R | LS_DATE | LS_SIZE); Serial.println("================= Finished ====================="); } void loop() {} //--- 在Setup()執行完成後,就等結束
- SD Library Documents
-
- SD.h Library
The SD library allows for reading from and writing to SD cards, e.g. on the Arduino Ethernet Shield. It is built on sdfatlib by William Greiman. The library supports FAT16 and FAT32 file systems on standard SD cards and SDHC cards. It uses short 8.3 names for files. The file names passed to the SD library functions can include paths separated by forward-slashes, /, e.g. "directory/filename.txt". Because the working directory is always the root of the SD card, a name refers to the same file whether or not it includes a leading slash (e.g. "/file.txt" is equivalent to "file.txt"). As of version 1.0, the library supports opening multiple files.
The communication between the microcontroller and the SD card uses SPI, which takes place on digital pins 11, 12, and 13 (on most Arduino boards) or 50, 51, and 52 (Arduino Mega). Additionally, another pin must be used to select the SD card. This can be the hardware SS pin - pin 10 (on most Arduino boards) or pin 53 (on the Mega) - or another pin specified in the call to SD.begin(). Note that even if you don't use the hardware SS pin, it must be left as an output or the SD library won't work.
- SdFat.h Librry
The Arduino SdFat Library is a minimal implementation of FAT16 and FAT32 file systems on SD flash memory cards. Standard SD and high capacity SDHC cards are supported.
- The SdFat only supports short 8.3 names.
- The main classes in SdFat are Sd2Card, SdVolume, and SdFile.
The Sd2Card class supports access to standard SD cards and SDHC cards. Most applications will only need to call the Sd2Card::init() member function.
The SdVolume class supports FAT16 and FAT32 partitions. Most applications will only need to call the SdVolume::init() member function.
The SdFile class provides file access functions such as open(), read(), remove(), write(), close() and sync(). This class supports access to the root directory and subdirectories. A number of example are provided in the SdFat/examples folder. These were developed to test SdFat and illustrate its use. SdFat was developed for high speed data recording. SdFat was used to implement an audio record/play class, WaveRP, for the Adafruit Wave Shield. This application uses special Sd2Card calls to write to contiguous files in raw mode. These functions reduce write latency so that audio can be recorded with the small amount of RAM in the Arduino.
- Arduino SD記憶卡模組之讀與寫
- SD.h Library