{"id":16958,"date":"2022-12-23T14:29:04","date_gmt":"2022-12-23T14:29:04","guid":{"rendered":"https:\/\/wolles-elektronikkiste.de\/?p=16958"},"modified":"2023-03-01T22:29:16","modified_gmt":"2023-03-01T22:29:16","slug":"sd-cards-and-sd-card-modules","status":"publish","type":"post","link":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules","title":{"rendered":"SD cards and SD card modules"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">About this post<\/h2>\n\n<p>In this article, I explain how to handle SD cards and SD card modules. Among other aspects, I will discuss the differences in using Arduino, ESP8266 and ESP32 boards.<\/p>\r\n<p>These are the topics I will cover: <\/p>\r\n<ul>\r\n<li><a href=\"#why_sd_cards\">Why do you need SD cards?<\/a><\/li>\r\n<li><a href=\"#sd_cards_formats_and_classes\">SD card formats, classes and modules<\/a><\/li>\r\n<li><a href=\"#preparations\">Preparations<\/a><\/li>\r\n<li><a href=\"#write_and_read\">Writing and reading<\/a><\/li>\r\n<li><a href=\"#files_and_folders\">Create \/ delete \/ display files and directories<\/a><\/li>\r\n<li><a href=\"#further_functions\">Further functions of the classes SD and File<\/a><\/li>\r\n<li><a href=\"#speed_test\">Testing the writing speed<\/a>\r\n<ul>\r\n<li><a href=\"#write_acceleration\">Write acceleration for Arduino boards<\/a><\/li>\r\n<\/ul>\r\n<\/li>\r\n<li><a href=\"#data_logger\">SD cards as data logger<\/a><\/li>\r\n<li><a href=\"#multiple_sd_cards\">Using multiple SD card modules<\/a><\/li>\r\n<\/ul>\r\n\n<h2 class=\"wp-block-heading\" id=\"why_sd_cards\">Why do you need SD cards?<\/h2>\n\n<p>There are many ways to store data using microcontrollers:<\/p>\r\n<ul>\r\n<li>Smaller amounts of data ranging from a few hundred bytes to a few kilobytes can be stored on the internal EEPROM. That is what I have described <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/li>\r\n<li>For somewhat larger amounts of data up to ~1 megabyte you can use external EEPROMs. These are characterized by low space and power requirements. I described external, I2C-controlled EEPROMs <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-2-external-i2c-eeproms\" target=\"_blank\" rel=\"noopener\">here<\/a>. An article about the faster, SPI-based representatives can be found <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-3-external-spi-eeproms\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/li>\r\n<li>If you use an ESP32 or ESP8266 based board, you can store several megabytes of data using LittleFS (formerly SPIFFS = SPI Flash File Storage).<\/li>\r\n<li>Finally, there are various options for storing data in the cloud or sending it via a network to a PC, for example.<\/li>\r\n<\/ul>\r\n<p><strong>Why do you need SD cards then?<\/strong> There can be several reasons:<\/p>\r\n<ol>\r\n<li>The SD cards are characterized by high storage capacities in the range of gigabytes.<\/li>\r\n<li>The data is conveniently transportable. This allows you to read and evaluate the stored data with a card reader on your PC, while your devices (MCU, sensors, etc.) remain on site.<\/li>\r\n<li>Unlike online storage methods, you are not dependent on network availability.<\/li>\r\n<\/ol>\r\n\n<h2 class=\"wp-block-heading\" id=\"sd_cards_formats_and_classes\">SD card formats, classes and modules<\/h2>\n\n<p>SD cards (&#8220;<strong>S<\/strong>ecure <strong>D<\/strong>igital memory cards&#8221;) differ among others in:<\/p>\r\n<ul>\r\n<li>their dimensions,<\/li>\r\n<li>their maximum storage capacity and<\/li>\r\n<li>their minimum write speed.<\/li>\r\n<\/ul>\r\n<p>Strictly speaking, the term &#8220;SD card&#8221; means the large models with dimensions of 24 mm x 32 mm x 2.1 mm and a maximum storage capacity of 2 gigabytes. The somewhat clunky SD card has been replaced by the small microSD card in the 11 mm \u00d7 15 mm \u00d7 1.0 mm format in most applications. Regarding the size, there are still the rarely used miniSD cards in between.<\/p>\r\n<p>Regarding the maximum storage capacities, a distinction is made between SD, SDHC, SDXC and SDUC cards. Especially for the SD and the microSD\/microSDHC cards there are cheap modules for Arduino and other boards, for example these:&nbsp;<\/p>\r\n<p>&nbsp;<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/sd_holder_and_sd_cards-1024x378.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"378\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/sd_holder_and_sd_cards-1024x378.jpg\" alt=\"Left: microSD\/microSDHC module up to max. 32 GB, right: SD card module up to 2 GB. \" class=\"wp-image-16710\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/sd_holder_and_sd_cards-1024x378.jpg 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/sd_holder_and_sd_cards-300x111.jpg 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/sd_holder_and_sd_cards-768x284.jpg 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/sd_holder_and_sd_cards-1536x567.jpg 1536w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/sd_holder_and_sd_cards-1320x488.jpg 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/sd_holder_and_sd_cards.jpg 1800w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Left: microSD\/microSDHC module up to max. 32 GB, right: SD card module up to 2 GB. <\/figcaption><\/figure>\n<p>With a maximum of 32 gigabytes, SDHC cards have a much higher storage capacity than SD cards.<\/p>\r\n<p>The minimum writing speed can be derived from the class of the SD card. This is the small number (2 to 10) in the unclosed circle. The number specifies the speed in megabytes per second.<\/p>\r\n\n<h4 class=\"wp-block-heading\">Power consumption<\/h4>\n\n<p>I determined a power consumption of 1.8 milliamps in idle mode for the microSDHC card module. For battery-powered projects, this is quite high. You could consider switching the module on and off as needed via a transistor, or better via a <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/the-mosfet-as-switch\" target=\"_blank\" rel=\"noopener\">MOSFET<\/a>. During writing, the power consumption is just under 40 milliamperes.<\/p>\r\n\n<h4 class=\"wp-block-heading\">microSD Shield for the Wemos D1 mini<\/h4>\n\n<p>A particularly practical solution is available for the Wemos D1 Mini Board, namely a microSD card shield:<\/p>\r\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/wemos_d1_mini_sd_card_shield-1024x442.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/wemos_d1_mini_sd_card_shield-1024x442.jpg\" alt=\"Wemos D1 Mini microSD Shield\" class=\"wp-image-16678\" width=\"512\" height=\"221\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/wemos_d1_mini_sd_card_shield-1024x442.jpg 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/wemos_d1_mini_sd_card_shield-300x130.jpg 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/wemos_d1_mini_sd_card_shield-768x332.jpg 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/wemos_d1_mini_sd_card_shield-1536x663.jpg 1536w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/wemos_d1_mini_sd_card_shield-1320x570.jpg 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/wemos_d1_mini_sd_card_shield.jpg 1800w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/a><figcaption class=\"wp-element-caption\">Wemos D1 Mini microSD Shield<\/figcaption><\/figure><\/div>\n<h2 class=\"wp-block-heading\" id=\"preparations\">Preparations<\/h2>\n\n<h3 class=\"wp-block-heading\">Formatting SD cards<\/h3>\n\n<p>If you buy an SD card, it will be pre-formatted. The format <em>can<\/em> harmonize with the memory card modules, but it does not <em>have to<\/em>. But even if you want to recycle an old SD card, e.g. from a camera, this is not possible without further ado, since manufacturer-specific formats are sometimes used there.<\/p>\r\n<p>For the use in the SD card modules, you need the FAT16 or FAT32 format. You can do the formatting on your PC or laptop. If you don&#8217;t have an SD card slot, then you should get a USB SD card reader for about 10 Euros.&nbsp;<\/p>\r\n<p>As software, I recommend the free program SD Card Formatter, which you can get <a href=\"https:\/\/www.sdcard.org\/downloads\/formatter\/\" target=\"_blank\" rel=\"noopener\">here<\/a>. You have to &#8220;unzip&#8221; the installation file, and then you can install the program.<\/p>\r\n<p>SD Card Formatter, with its few settings, is about the simplest program I have ever used. The SD card is automatically detected by the program. Select the option &#8220;Overwrite format&#8221; and click on &#8220;Format&#8221;. The process takes a few minutes. And that&#8217;s it.<\/p>\r\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/04\/SD_Card_Formatter.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"391\" height=\"429\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/04\/SD_Card_Formatter.jpg\" alt=\"Formatting SD cards - SD Card Formatter program interface\" class=\"wp-image-1083\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/04\/SD_Card_Formatter.jpg 391w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/04\/SD_Card_Formatter-273x300.jpg 273w\" sizes=\"auto, (max-width: 391px) 100vw, 391px\" \/><\/a><figcaption class=\"wp-element-caption\">SD Card Formatter program interface<\/figcaption><\/figure><\/div>\n<h3 class=\"wp-block-heading\">The SD library<\/h3>\n\n<p>The SD library is part of the basic Arduino IDE and therefore does not need to be installed via the library manager. Strictly speaking, there is not &#8220;the one&#8221; SD library, but different versions for different boards. Especially the version for the ESP32 has a few peculiarities, which I will discuss later.<\/p>\r\n<p>Depending on the board you have set, you will find different example sketches. Unfortunately, the &#8220;Examples for any Board&#8221; are not hidden when using ESP32 based boards, although they do not work with them. Go to the ESP32 examples \u2192 SD(esp32) instead.&nbsp;<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/arduino_sd_examples-1024x417.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"417\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/arduino_sd_examples-1024x417.png\" alt=\"Selection of example sketches for different boards\" class=\"wp-image-16670\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/arduino_sd_examples-1024x417.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/arduino_sd_examples-300x122.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/arduino_sd_examples-768x313.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/arduino_sd_examples.png 1115w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Selection of example sketches for different boards<\/figcaption><\/figure>\n<h3 class=\"wp-block-heading\">Connecting the microcontroller<\/h3>\n\n<p>The permissible supply voltage for SD cards is usually 2.7 &#8211; 3.6 volts. Some SD cards can also tolerate 1.8 volts. Most SD card modules have voltage regulators and can therefore be operated with 5 volts. The microSD card module I use (absurdly) does not have a 3 volt pin, so it <em>must<\/em> be powered by 5 volts.<\/p>\r\n<p>The communication with the microcontroller takes place via SPI. So, MISO is connected to MISO, MOSI to MOSI, SCK to SCK and CS to CS. You can set the CS pin yourself on most boards.<\/p>\r\n<p>For the Arduino Nano the wiring looks like this:<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/SD_Card_Wiring-1024x347.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"347\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/SD_Card_Wiring-1024x347.png\" alt=\"A microSD card module on the Arduino Nano\" class=\"wp-image-16636\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/SD_Card_Wiring-1024x347.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/SD_Card_Wiring-300x102.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/SD_Card_Wiring-768x260.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/SD_Card_Wiring-1320x447.png 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/SD_Card_Wiring.png 1477w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">A microSD card module on the Arduino Nano<\/figcaption><\/figure>\n<h3 class=\"wp-block-heading\">Check your setup<\/h3>\n\n<p>If you are using an Arduino board, then you can check the circuit and the SD card with the CardInfo sketch from the examples. Do not forget to adjust the CS pin if necessary.<\/p>\r\n<p>The sketch tells you the SD card type, format, storage capacity and the directories and files present:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_cardinfo.png\"><img loading=\"lazy\" decoding=\"async\" width=\"827\" height=\"410\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_cardinfo.png\" alt=\"Output of CardInfo.ino\" class=\"wp-image-16675\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_cardinfo.png 827w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_cardinfo-300x149.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_cardinfo-768x381.png 768w\" sizes=\"auto, (max-width: 827px) 100vw, 827px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of CardInfo.ino<\/figcaption><\/figure>\n<p>CardInfo does not work on ESP32 or ESP8266 boards. As a first test for an ESP32 based board, I recommend instead the example sketch SD_Test.ino and for an ESP8266 board the sketch listfiles.ino.<\/p>\r\n\n<h2 class=\"wp-block-heading\" id=\"write_and_read\">Writing and reading<\/h2>\n\n<p>Now let&#8217;s have a look at a few functions of the SD library and start with simple read and write operations.<\/p>\r\n\n<h3 class=\"wp-block-heading\">Writing<\/h3>\n\n<p>The following example sketch writes an integer array to the SD card. Again, (but for the last time in this post) the hint: You may have to adjust the CS pin. <\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"sd_card_write.ino\" data-enlighter-title=\"sd_card_write.ino\">#include &lt;SD.h&gt;\r\nconst int chipSelect = 10; \/\/ choose an appropriate pin for your board\r\n\r\nvoid setup(){\r\n  String myFile = \"integers.txt\"; \/\/ for ESP32: \"\/integers.txt\";\r\n  int intArray[10] = {42, 424, 4242, 17, 1234, 56, 1967, 299, 3333, 5678};\r\n  Serial.begin(9600);\r\n\/\/  while(!Serial){} \/\/ needed for some boards\r\n\/\/  delay(1000); \/\/ helps in case of incomplete output on serial monitor\r\n  \r\n  if(!SD.begin(chipSelect)){\r\n    Serial.println(\"SD-Card not connected!\");\r\n    while(1);\r\n  }\r\n  else{\r\n    Serial.println(\"SD-Card initialized\");\r\n  }\r\n  \r\n  SD.remove(myFile);\r\n  File dataFile = SD.open(myFile, FILE_WRITE);\r\n\r\n  if(dataFile){\r\n    for(int i = 0; i &lt; 10; i++){\r\n      dataFile.println(intArray[i]);\r\n    }\r\n    dataFile.close();\r\n    Serial.println(\"Data written\");\r\n  }\r\n  else{\r\n    Serial.println(\"Could not open file\");\r\n  }\r\n}\r\n\r\nvoid loop(){}<\/pre>\r\n\n<h4 class=\"wp-block-heading\">Explanations for sd_card_write.ino <\/h4>\n\n<p>The SD library is included with <code>#include &lt;SD.h&gt;<\/code>. The initialization is done with <code>SD.begin(chipSelectPin)<\/code>. If this process works, then <code>SD.begin()<\/code> returns the value <code>true<\/code>, otherwise <code>false<\/code>. You do not need to create an SD object unless you want to use two or more SD cards (see last chapter).<\/p>\r\n<p>The file we create and fill is called &#8220;integers.txt&#8221;. We store the name in the string variable &#8220;myFile&#8221;. Only 8 characters are allowed for the file name, plus 3 characters for the file extension &#8211; welcome to the last millennium!<\/p>\r\n<p>The instruction <code>SD.remove(myFile);<\/code> deletes the file myFile (or &#8220;integers.txt&#8221;) if it should exist. Without this measure, the data to be saved would be appended to the end of the file again with each program run (except with the ESP32).&nbsp;<\/p>\r\n<p>Line 20 appears inconspicuous, but there is much behind it:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-lineoffset=\"20\">File dataFile = SD.open(myFile, FILE_WRITE);<\/pre>\r\n\n<p>For understanding (or confusion?):<\/p>\r\n<ul>\r\n<li>SD is an object of SDClass. This is not obvious since you did not have to create SD yourself.<\/li>\r\n<li>File is a property of SDClass.&nbsp;<\/li>\r\n<li><code>SD.open(myFile)<\/code> opens the path to &#8220;myFile&#8221;. The function returns an object of the File class, i.e. a file object, which is given the name dataFile. The FILE_WRITE parameter specifies that the file is opened for writing.<\/li>\r\n<li>So &#8220;myFile&#8221; contains only the filename or the path to the file. In contrast, &#8220;dataFile&#8221; is the actual file object.\r\n<ul>\r\n<li>Consequently, <code>dataFile.name()<\/code> returns the content of the variable &#8220;myFile&#8221;, in this case &#8220;integers.txt&#8221;. You can try that out.<\/li>\r\n<\/ul>\r\n<\/li>\r\n<\/ul>\r\n<p>The instructions for writing are <code>print()<\/code>, <code>println()<\/code> or alternatively <code>write()<\/code>. The similarities to Serial functions are not accidental because File and Serial are relatives, namely &#8220;children&#8221; of the Stream class.<\/p>\r\n<p>Finally, you complete the writing process with <code>close()<\/code>.<\/p>\r\n\n<h4 class=\"wp-block-heading\">Peculiarities of the ESP32 <\/h4>\n\n<p>For the ESP32 you need to consider:<\/p>\r\n<ul>\r\n<li>The names of files and directories must be preceded by a slash (&#8220;\/&#8221;).<\/li>\r\n<li>If &#8220;FILE_WRITE&#8221; is applied to an existing file, then its contents will be overwritten. You can append content using the FILE_APPEND parameter. The SD library for Arduino boards does not know the parameter &#8220;FILE_APPEND&#8221; and appends the content automatically.<\/li>\r\n<li><code>SD.begin()<\/code> can be called without CS Pin. In this case the default GPIO5 is used.<\/li>\r\n<\/ul>\r\n\n<h3 class=\"wp-block-heading\">Read<\/h3>\n\n<p>The following sketch reads the just saved data from the SD card:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"sd_card_read.ino\" data-enlighter-title=\"sd_card_read.ino\">#include &lt;SD.h&gt;\r\nconst int chipSelect = 10; \/\/ choose an appropriate pin for your board\r\n\r\nvoid setup(){\r\n  char myFile[] = \"integers.txt\"; \/\/ for ESP32: \"\/integers.txt\";\r\n  Serial.begin(9600);\r\n\/\/  while(!Serial){} \/\/ needed for some Boards\r\n\/\/  delay(1000); \/\/ helps in case of incomplete output on serial monitor\r\n  \r\n  if(!SD.begin(chipSelect)){\r\n    Serial.println(\"SD-Card not connected!\");\r\n    while(1);\r\n  }\r\n  else{\r\n    Serial.println(\"SD-Card initialized\");\r\n  }\r\n\r\n  File dataFile = SD.open(myFile);\r\n\r\n  if(dataFile){\r\n    while(dataFile.available()){\r\n      String line = dataFile.readStringUntil('\\n');\r\n      Serial.println(line);\r\n    }\r\n\/\/    Alternative: read as Integer\r\n\/\/    while(dataFile.available()){\r\n\/\/      int readInt = dataFile.parseInt();\r\n\/\/      Serial.println(readInt);\r\n\/\/    }\r\n    dataFile.close();\r\n  }\r\n  else{\r\n    Serial.println(\"Could not open file\");\r\n  }\r\n}\r\n\r\nvoid loop(){}\r\n<\/pre>\r\n\n<h4 class=\"wp-block-heading\">Explanations for sd_card_read.ino<\/h4>\n\n<p>Much of this is similar to the writing sketch discussed earlier. I will only go into the main differences.<\/p>\r\n<ul>\r\n<li>This time I defined &#8220;myFile&#8221; as a character array. The reason is merely to show that it can be done.<\/li>\r\n<li>By calling <code>SD.open(myFile)<\/code> without &#8220;FILE_WRITE&#8221;, the file can only be read.<\/li>\r\n<li>There are two options for reading the data:\r\n<ul>\r\n<li><code>readStringUntil('\\n')<\/code> reads all characters up to the next line break as a string.<\/li>\r\n<li>To read out the data as an integer, the practical function <code>parseInt()<\/code> can be used. For floating-point numbers, <code>parseFloat()<\/code> would be available.<\/li>\r\n<\/ul>\r\n<\/li>\r\n<\/ul>\r\n<p>Finally, the file is closed again with <code>close()<\/code>.<\/p>\r\n\n<p>The output should not surprise:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_sd_card_read.png\"><img loading=\"lazy\" decoding=\"async\" width=\"827\" height=\"381\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_sd_card_read.png\" alt=\"Output of sd_card_read.ino\" class=\"wp-image-16744\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_sd_card_read.png 827w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_sd_card_read-300x138.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_sd_card_read-768x354.png 768w\" sizes=\"auto, (max-width: 827px) 100vw, 827px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of sd_card_read.ino<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\" id=\"files_and_folders\">Creating \/ deleting \/ displaying files and directories <\/h2>\n\n<p>You have just seen how to create and delete files. Now let&#8217;s look at how you do the same with directories and how you display entire directory structures, including the files preserved in them. First here is the sketch which also works on an ESP8266 but not on an ESP32:<\/p>\r\n\n<div class=\"scroll-paragraph\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"add_remove_list_files_and_folders.ino\" data-enlighter-title=\"add_remove_list_files_and_folders.ino\">\/* Based on:\r\n  listfiles.ino, created Nov 2010 by David A. Mellis;\r\n  modified 9 Apr 2012 by Tom Igoe\r\n  modified 2 Feb 2014 by Scott Fitzgerald\r\n*\/\r\n#include &lt;SD.h&gt;\r\nconst int chipSelectPin = 10;\r\n\r\nvoid setup() {\r\n  Serial.begin(9600);\r\n  while (!Serial) {}\r\n  \r\n  Serial.print(\"Initializing SD card...\");\r\n\r\n  if (!SD.begin(chipSelectPin)) {\r\n    Serial.println(\"initialization failed!\");\r\n    while (1);\r\n  }\r\n  Serial.println(\"initialization done.\");\r\n\r\n  Serial.println(\"Adding files:\");\r\n  SD.mkdir(\"New_Fold\"); \/\/ make new folder\r\n  File dataFile = SD.open(\"file_1.txt\", FILE_WRITE);\r\n  dataFile.println(\"Some Content\");\r\n  dataFile.close();\r\n\r\n  dataFile = SD.open(\"new_fold\/file_2.txt\", FILE_WRITE);\r\n  dataFile.println(\"Some other Content\");\r\n  dataFile.close();\r\n\r\n  File root = SD.open(\"\/\");\r\n  printDirectory(root, 0);\r\n\r\n  Serial.println();\r\n  Serial.println(\"After removing files:\");\r\n  SD.remove(\"file_1.txt\");\r\n  SD.remove(\"new_fold\/file_2.txt\");\r\n  SD.rmdir(\"new_fold\");\r\n\r\n  root = SD.open(\"\/\");\r\n  printDirectory(root, 0);\r\n\r\n  Serial.println(\"done!\");\r\n}\r\n\r\nvoid loop() {}\r\n\r\nvoid printDirectory(File &amp;dir, int numTabs) {\r\n  while (true) {\r\n\r\n    File entry =  dir.openNextFile();\r\n    if (! entry) {\r\n      \/\/ no more files\r\n      break;\r\n    }\r\n    for (uint8_t i = 0; i &lt; numTabs; i++) {\r\n      Serial.print('\\t');\r\n    }\r\n    Serial.print(entry.name());\r\n    if (entry.isDirectory()) {\r\n      Serial.println(\"\/\");\r\n      printDirectory(entry, numTabs + 1);\r\n    } else {\r\n      \/\/ files have sizes, directories do not\r\n      Serial.print(\"\\t\\t\");\r\n      Serial.println(entry.size(), DEC);\r\n    }\r\n    entry.close();\r\n  }\r\n}<\/pre>\r\n<p>&nbsp;<\/p>\r\n<\/div>\r\n\n<h3 class=\"wp-block-heading\">Explanations for add_remove_list_files_and_folders.ino<\/h3>\n\n<h4 class=\"wp-block-heading\">The setup()<\/h4>\n\n<ul>\r\n<li><code>SD.mkdir(\"New_Fold\")<\/code> creates a directory with the name &#8220;New_Fold&#8221;.<\/li>\r\n<li>We create the file &#8220;file_1.txt&#8221; only to have something more to display.<\/li>\r\n<li><code>SD.open(\"New_Fold\/file_2.txt\", FILE_WRITE);<\/code> creates the file &#8220;file_2.txt&#8221; in the folder &#8220;New_Fold&#8221;.<\/li>\r\n<li>The assignment <code>File root = SD.open(\"\/\");<\/code> is perhaps a little surprising, since a file object called &#8220;root&#8221; is created, which represents the main directory. Users of Linux or Unix should be less surprised because for these systems a directory is just a special file.&nbsp;<\/li>\r\n<li>The files and directories are displayed using the <code>printDirectory()<\/code> function. We&#8217;ll get to that in a moment.<\/li>\r\n<li>We remove the added files and directories with <code>SD.remove()<\/code> and <code>SD.rmdir()<\/code> respectively.<\/li>\r\n<li>After that, the content of the SD card is output once again.<\/li>\r\n<\/ul>\r\n\n<h4 class=\"wp-block-heading\">The printDirectory() function<\/h4>\n\n<p>The function <code>printDirectory()<\/code> is passed a file object (on the first call this is root) and the number of tabs. The number of tabs is used for formatting and represents the current directory depth.<\/p>\r\n<p><code>File entry = dir.openNextFile();<\/code> opens the next file found on the SD card and creates the file object &#8220;entry&#8221; from it. Three scenarios are possible:<\/p>\r\n<ul>\r\n<li>There is no other file or directory (<code>!entry<\/code>). The loop is canceled.<\/li>\r\n<li>Another entry is available and it is a directory (<code>entry.isDirectory()<\/code>). In that case, <code>printDirectory()<\/code> is executed again, and the current directory depth is increased by 1. This is a nice example of a recursive call.&nbsp;<\/li>\r\n<li>Another entry is present and it is a file. In this case the file size is queried and output with <code>entry.size()<\/code>. After that, the while loop continues.&nbsp;<\/li>\r\n<\/ul>\r\n\n<p>Here is the output:<\/p>\r\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_add_remove_list_files_and_folders.png\"><img loading=\"lazy\" decoding=\"async\" width=\"827\" height=\"422\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_add_remove_list_files_and_folders.png\" alt=\"Output of add_remove_list_files_and_folders.ino\" class=\"wp-image-16666\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_add_remove_list_files_and_folders.png 827w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_add_remove_list_files_and_folders-300x153.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_add_remove_list_files_and_folders-768x392.png 768w\" sizes=\"auto, (max-width: 827px) 100vw, 827px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of add_remove_list_files_and_folders.ino<\/figcaption><\/figure><\/div>\n<p>A few things stand out:<\/p>\r\n<ul>\r\n<li>SYSTEM~1 is the SystemVolumeInformation directory. It is created automatically by Windows. Since its name has more than eight letters, it is abbreviated.\r\n<ul>\r\n<li>You can delete the directory without hesitation because it is not needed for FAT16\/FAT32. However, you must first delete the two files in this directory. <code>SD.rmdir()<\/code> works only with empty directories.<\/li>\r\n<li>If you then read the SD card again with a reader on the PC, the directory and its contents will be recreated.<\/li>\r\n<\/ul>\r\n<\/li>\r\n<li>The SD library converts all file and directory names to uppercase.<\/li>\r\n<\/ul>\r\n\n<h3 class=\"wp-block-heading\">add_remove_list_files_and_folders for the ESP32<\/h3>\n\n<p>The corresponding sketch for the ESP32 does basically the same. Here, however, the directory depth (&#8220;noOfFolderLevels&#8221;) must be specified. A value greater than the actual directory depth (which you may not know) does no harm.<\/p>\r\n<p>The sketch is based on parts of the example sketch SD_Test.ino. The original sketch is a little more complex than it needs to be because the SD object is also passed to the functions there. But this is not necessary.&nbsp;<\/p>\r\n<p>In addition, the sketch provides general information about the SD card, namely type and size.<\/p>\r\n\n<div class=\"scroll-paragraph\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"add_remove_list_files_and_folders_esp32.ino\" data-enlighter-title=\"add_remove_list_files_and_folders_esp32.ino\">#include \"SD.h\"\r\n\r\nvoid setup(){\r\n  int noOfFolderLevels = 3;\r\n  Serial.begin(115200);\r\n  delay(1000);\r\n  if(!SD.begin()){\r\n    Serial.println(\"Card Mount Failed\");\r\n    return;\r\n  }\r\n  uint8_t cardType = SD.cardType();\r\n\r\n  if(cardType == CARD_NONE){\r\n    Serial.println(\"No SD card attached\");\r\n    return;\r\n  }\r\n\r\n  Serial.print(\"SD Card Type: \");\r\n  if(cardType == CARD_MMC){\r\n    Serial.println(\"MMC\");\r\n  } else if(cardType == CARD_SD){\r\n      Serial.println(\"SDSC\");\r\n  } else if(cardType == CARD_SDHC){\r\n      Serial.println(\"SDHC\");\r\n  } else {\r\n      Serial.println(\"UNKNOWN\");\r\n  }\r\n  uint64_t cardSize = SD.cardSize() \/ (1024 * 1024);\r\n  Serial.printf(\"SD Card Size: %lluMB\\n\", cardSize);\r\n\r\n  Serial.println(\"Adding files:\");\r\n  SD.mkdir(\"\/new_fold\"); \/\/ make new folder\r\n  File dataFile = SD.open(\"\/file_1.txt\", FILE_WRITE);\r\n  dataFile.println(\"Some Content\");\r\n  dataFile.close();\r\n\r\n  dataFile = SD.open(\"\/new_fold\/file_2.txt\", FILE_WRITE);\r\n  dataFile.println(\"Some other Content\");\r\n  dataFile.close();\r\n  \r\n  listDir(\"\/\", noOfFolderLevels);\r\n\r\n  Serial.println();\r\n  Serial.println(\"After removing files:\");\r\n  SD.remove(\"\/file_1.txt\");\r\n  SD.remove(\"\/new_fold\/file_2.txt\");\r\n  SD.rmdir(\"\/new_fold\");\r\n\r\n  listDir(\"\/\", noOfFolderLevels);\r\n}\r\n\r\nvoid loop(){}\r\n\r\nvoid listDir(const char * dirname, uint8_t levels){\r\n  Serial.printf(\"Listing directory: \");\r\n  Serial.println(dirname);\r\n   \r\n  File root = SD.open(dirname);\r\n  if(!root){\r\n    Serial.println(\"Failed to open directory\");\r\n    return;\r\n  }\r\n  if(!root.isDirectory()){\r\n    Serial.println(\"Not a directory\");\r\n    return;\r\n  }\r\n\r\n  File file = root.openNextFile();\r\n  while(file){\r\n    if(file.isDirectory()){\r\n      Serial.print(\"  DIR : \");\r\n      Serial.println(file.name());\r\n      if(levels){\r\n        listDir(file.name(), levels -1);\r\n      }\r\n    } else {\r\n        Serial.print(\"  FILE: \");\r\n        Serial.print(file.name());\r\n        Serial.print(\"  SIZE: \");\r\n        Serial.println(file.size());\r\n    }\r\n    file = root.openNextFile();\r\n  }\r\n}<\/pre>\r\n<p>&nbsp;<\/p>\r\n<\/div>\r\n\n<p>And this is what the output looks like:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_add_remove_list_files_and_folders_esp32.png\"><img loading=\"lazy\" decoding=\"async\" width=\"936\" height=\"540\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_add_remove_list_files_and_folders_esp32.png\" alt=\"\" class=\"wp-image-16672\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_add_remove_list_files_and_folders_esp32.png 936w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_add_remove_list_files_and_folders_esp32-300x173.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/output_add_remove_list_files_and_folders_esp32-768x443.png 768w\" sizes=\"auto, (max-width: 936px) 100vw, 936px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of add_remove_list_files_and_folders_esp32.ino<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\" id=\"further_functions\">Further functions of the classes SD and File<\/h2>\n\n<p>Many functions classes SD and File we have already discussed. A complete listing can be found <a href=\"https:\/\/www.arduino.cc\/reference\/en\/libraries\/sd\/\" target=\"_blank\" rel=\"noopener\">here<\/a> on the Arduino pages.<\/p>\r\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/file_sd_class_functions.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/file_sd_class_functions.png\" alt=\"The functions of the classes SD and File\" class=\"wp-image-16658\" width=\"800\" height=\"401\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/file_sd_class_functions.png 800w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/file_sd_class_functions-300x150.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/file_sd_class_functions-768x385.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><figcaption class=\"wp-element-caption\">The functions of the classes SD and File<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\" id=\"speed_test\">Testing the writing speed<\/h2>\n\n<p>To check the writing speed, I wrote the following sketch. It writes 1000 integer values to a file. Two variants are being tested. First, the file is opened, and the values are written &#8220;in one go&#8221; to numbersa.txt. In a second pass, the file is opened again for each write operation (to numbersb.txt).<\/p>\r\n\n<div class=\"scroll-paragraph\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"sd_card_speed_test.ino\" data-enlighter-title=\"sd_card_speed_test.ino\">#include &lt;SD.h&gt;\r\nconst int chipSelect = 10;\r\n\r\nvoid setup(){\r\n  String myFile = \"numbersa.txt\";\r\n  Serial.begin(9600);\r\n  SD.begin(chipSelect);\r\n  SD.remove(myFile);\r\n  unsigned long startTime = millis();\r\n\r\n  \/\/ Continuous writing:\r\n  File dataFile = SD.open(myFile, FILE_WRITE);\r\n  for (int i=0; i&lt;1000; i++){\r\n    dataFile.println(i);\r\n  }\r\n  dataFile.close();\r\n  \r\n  unsigned long writingTime = millis() - startTime;\r\n  Serial.println(\"Writing 1000 integers took: \");\r\n  Serial.print(writingTime);\r\n  Serial.println(\" [ms],\");\r\n  Serial.println(\"when keeping file open\");\r\n  Serial.println();\r\n\r\n  \/\/ Discontinuous writing: n x (open, write, close)\r\n  myFile = \"numbersb.txt\";\r\n  SD.remove(myFile);\r\n  startTime = millis();\r\n  for (int i=0; i&lt;1000; i++){\r\n    dataFile = SD.open(myFile, FILE_WRITE); \/\/ FILE_APPEND for ESP32\r\n    dataFile.println(i);\r\n    dataFile.close();\r\n  }\r\n  \r\n  writingTime = millis() - startTime;\r\n  Serial.println(\"Writing 1000 integers took: \");\r\n  Serial.print(writingTime);\r\n  Serial.println(\" [ms],\");\r\n  Serial.println(\"when reopening the file for every entry\");\r\n  Serial.println();\r\n  delay(1000);\r\n}\r\n\r\nvoid loop(){}<\/pre>\r\n<p>&nbsp;<\/p>\r\n<\/div>\r\n\n<p>Here is the result using an Arduino&nbsp; Nano:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/12\/output_sd_card_speed_test.png\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"225\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/12\/output_sd_card_speed_test.png\" alt=\"Output of sd_card_speed_test.ino\" class=\"wp-image-16857\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/12\/output_sd_card_speed_test.png 800w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/12\/output_sd_card_speed_test-300x84.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/12\/output_sd_card_speed_test-768x216.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of sd_card_speed_test.ino<\/figcaption><\/figure>\n<p>The result speaks for itself: Opening and closing the file takes a few milliseconds each, while the actual writing of a single integer value takes place in the microsecond range. So, if speed is important, you should leave the file open.<\/p>\r\n<p>The file numbersa.txt is 4.77 kilobytes in size. We needed 0.266 seconds for this, which results in a write speed of 17.9 KB\/s. But wasn&#8217;t the minimum writing speed of SD cards in the range of a few MB\/s? This is true, but the bottleneck here is data processing and transmission.<\/p>\r\n<p>The write process on a Wemos D1 Mini board was considerably faster. It only took 57 (!) milliseconds. For an ESP32 development board, I determined 75 milliseconds.<\/p>\r\n<p>Moreover, the speed depends on the SD card. I determined the above values with a 16 GB microSDHC card. The time required to write the 1000 integer values, on the other hand, was 60 to 100 milliseconds higher when using a 2 GB microSD card (without &#8220;HC&#8221;).<\/p>\r\n\n<h3 class=\"wp-block-heading\" id=\"write_acceleration\">Acceleration for Arduino AVR Boards<\/h3>\n\n<p>If you want to write larger amounts of data, it is more effective to store them temporarily in a buffer and then transfer the buffer in one go. At least this is true when using an AVR-based Arduino board. Using this sketch (based on the nonBlockingWrite example sketch), I was able to reduce the write time for 1000 integers from 266 milliseconds to 141 milliseconds.<\/p>\r\n\n<div class=\"scroll-paragraph\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"fast_write.ino\" data-enlighter-title=\"fast_write.ino\">#include &lt;SD.h&gt;\r\n\r\nconst char filename[] = \"demo.txt\";\r\nFile txtFile;\r\nunsigned long lastMillis = 0;\r\n\r\nvoid setup() {\r\n    Serial.begin(115200);\r\n    while (!Serial);\r\n\r\n    \/\/ reserve memory for a String used as a buffer\r\n    String buffer;\r\n    buffer.reserve(288);  \/\/ reserve memory for the buffer (slightly bigger than the chunk size)\r\n\r\n    if (!SD.begin(10)) {\r\n        Serial.println(\"Card failed, or not present\");\r\n        \/\/ don't do anything more:\r\n    while (1);\r\n    }\r\n    \/\/ If you want to start from an empty file,\r\n    \/\/ uncomment the next line:\r\n    SD.remove(filename);\r\n    \r\n    txtFile = SD.open(filename, FILE_WRITE);\r\n    if (!txtFile) {\r\n        Serial.print(\"error opening \");\r\n        Serial.println(filename);\r\n        while (1);\r\n    }\r\n    \r\n    int counter = 0;\r\n    unsigned long startingTime = millis();\r\n    \r\n    while(counter &lt; 1000){\r\n        fastWrite(buffer, counter);\r\n        counter++;\r\n    }\r\n    txtFile.write(buffer.c_str()); \/\/ write what is left in the buffer\r\n    unsigned long writingTime = millis() - startingTime;\r\n    txtFile.close(); \r\n    Serial.print(\"Writing Time [ms]: \");\r\n    Serial.println(writingTime);\r\n}\r\n\r\nvoid loop() {}\r\n\r\nvoid fastWrite(String &amp;buf, int counter){\r\n    const unsigned int chunkSize = 256;\r\n    char charBuf[10]; \/\/ buffer for t\r\n    dtostrf(counter, 1, 0, charBuf); \/\/ convert counter char array\r\n    buf += charBuf;\r\n    buf += \"\\r\\n\";  \/\/ add carriage return and line feed\r\n    if ((buf.length() &gt;= chunkSize)) {\r\n        txtFile.write(buf.c_str(), chunkSize); \/\/ write chunk\r\n        buf.remove(0, chunkSize); \/\/ remove from buffer what's already written\r\n    }\r\n}<\/pre>\r\n<p>&nbsp;<\/p>\r\n<\/div>\r\n\n<p>The sketch is quite substantial. But to keep the article from getting too long, I&#8217;ll just explain it in broad terms:<\/p>\r\n<ul>\r\n<li><code>buffer<\/code> is the buffer memory for the numbers to be written. Its capacity must be slightly higher than the size of the chunks to be written.<\/li>\r\n<li><code>dtostrf()<\/code> converts the number to be written into a character array which is written to the end of the buffer memory.<\/li>\r\n<li>If the buffer is larger than the chunk size, the buffer is written to the SD card and reduced accordingly. After that, the buffer is filled again.<\/li>\r\n<li>At the end, the rest of the buffer is written to the SD card.<\/li>\r\n<\/ul>\r\n\n<p>For the Wemos D1 Mini Board, I could not achieve an increase in writing speed with it. It does not work on the ESP32, but further explanation would lead too far.<\/p>\r\n\n<h2 class=\"wp-block-heading\" id=\"data_logger\">SD cards as data loggers <\/h2>\n\n<p>One of the main applications for SD cards with microcontrollers is as data loggers. In the examples, you will find a simple sketch. I go one step further and control the recording of the values temporally via an alarm of a <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/ds3231-real-time-clock\" target=\"_blank\" rel=\"noopener\">DS3231 RTC<\/a> module. This has the advantage that you can record the date and time of your measurement. Furthermore, you can send your microcontroller to sleep meanwhile and wake it up by the DS3231. Here is the basic circuit:<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Datalogger_Wiring-1024x489.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"489\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Datalogger_Wiring-1024x489.png\" alt=\"Data logger with the DS3231\" class=\"wp-image-16702\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Datalogger_Wiring-1024x489.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Datalogger_Wiring-300x143.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Datalogger_Wiring-768x367.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Datalogger_Wiring-1536x734.png 1536w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Datalogger_Wiring-1320x631.png 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Datalogger_Wiring.png 1572w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Data logger with the DS3231<\/figcaption><\/figure>\n<p>To measure just anything, I connected a potentiometer to the analog input A1. You can replace that with something more exciting. This is the sketch:<\/p>\r\n\n<div class=\"scroll-paragraph\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"data_logger.ino\" data-enlighter-title=\"data_logger.ino\">#include &lt;RTClib.h&gt;\r\n#include &lt;Wire.h&gt;\r\n#include &lt;SD.h&gt;\r\n#include &lt;avr\/sleep.h&gt; \/\/ comment if you don't use an AVR based Board\r\nconst int chipSelectPin = 10;\r\nconst int clockInterruptPin = 2;\r\nconst int analogPin = A1;\r\nString myFile = \"data_log.csv\";\r\n\r\nRTC_DS3231 rtc;\r\n\r\nvoid setup() {\r\n  Serial.begin(9600);\r\n  pinMode(analogPin, INPUT);\r\n  \r\n  SD.begin(chipSelectPin); \r\n  SD.remove(myFile); \r\n  File dataFile = SD.open(myFile, FILE_WRITE);\r\n  dataFile.println(\"Time;analogRead\"); \/\/ you my need a \",\" instead of \";\"\r\n  dataFile.close();\r\n  \r\n  rtc.begin();\r\n  rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); \/\/ set time to system at when compiling    \r\n  rtc.disable32K(); \/\/disable 32K pin\r\n  rtc.clearAlarm(1); \/\/ in case there's still an alarm \r\n  rtc.clearAlarm(2);\r\n  rtc.writeSqwPinMode(DS3231_OFF); \/\/ we use the SQW pin for interrupts\r\n  rtc.disableAlarm(2); \/\/ we don't need alarm 2\r\n  rtc.setAlarm1(rtc.now() + TimeSpan(10), DS3231_A1_Second);  \/\/ alarm in 10 seconds\r\n\r\n  pinMode(clockInterruptPin, INPUT_PULLUP);\r\n  attachInterrupt(digitalPinToInterrupt(clockInterruptPin), onAlarm, FALLING);\r\n}\r\n\r\nvoid loop() {\r\n  if(rtc.alarmFired(1)) {\r\n    unsigned int measuredValue = analogRead(analogPin);\r\n    char date[18] = \"DD.MM.YY hh:mm:ss\";\r\n    rtc.now().toString(date);\r\n    rtc.clearAlarm(1);\r\n    \r\n    Serial.println(date);\r\n    Serial.print(\"Analog Read: \"); \r\n    Serial.println(measuredValue);\r\n    File dataFile = SD.open(myFile, FILE_WRITE); \/\/ FILE_APPEND for ESP32\r\n    dataFile.print(date);\r\n    dataFile.print(\";\");\r\n    dataFile.println(measuredValue);\r\n    dataFile.close();\r\n    rtc.setAlarm1(rtc.now() + TimeSpan(10),DS3231_A1_Second);\r\n    delay(100); \/\/ give some time for Serial.print() \/ Data.print() to complete\r\n      \r\n    set_sleep_mode(SLEEP_MODE_PWR_DOWN); \/\/ choose power down mode, comment if you don't use an AVR based Board\r\n    sleep_mode(); \/\/ sleep now! \/\/ comment if you don't use an AVR based Board\r\n  }  \r\n}\r\n\r\nvoid onAlarm() {\r\n    Serial.print(\"Alarm at: \");\r\n}<\/pre>\r\n<p>&nbsp;<\/p>\r\n<\/div>\r\n\n<h4 class=\"wp-block-heading\">Explanations for data_logger.ino<\/h4>\n\n<p>In order not to make the article too long, I will not go into the details of the DS3231 control. Please have a look at <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/ds3231-real-time-clock\" target=\"_blank\" rel=\"noopener\">this article<\/a>. In broad terms, here&#8217;s what the sketch does:<\/p>\r\n<ul>\r\n<li>Every 10 seconds, the DS3231 triggers an alarm.<\/li>\r\n<li>The alarm wakes up the Arduino, which then takes a measurement.<\/li>\r\n<li>The measured value is written to the SD card in the data_log.csv file, together with the date and time. The format is: &#8220;DD.MM.YY hh:mm:ss;measured value&#8221;.<\/li>\r\n<li>The first line in data_log.csv is &#8220;Time;analogRead&#8221; and serves as a header.<\/li>\r\n<li>Measured value and time are also output on the serial monitor, which is only for control purposes.<\/li>\r\n<li>The Arduino is sent to sleep and everything starts over again.<\/li>\r\n<\/ul>\r\n<p>This is what the output looked like on the serial monitor:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_serrial_monitor.png\"><img loading=\"lazy\" decoding=\"async\" width=\"868\" height=\"449\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_serrial_monitor.png\" alt=\"Output from data_logger.ino\" class=\"wp-image-16546\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_serrial_monitor.png 868w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_serrial_monitor-300x155.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_serrial_monitor-768x397.png 768w\" sizes=\"auto, (max-width: 868px) 100vw, 868px\" \/><\/a><figcaption class=\"wp-element-caption\">Output from data_logger.ino<\/figcaption><\/figure>\n<h3 class=\"wp-block-heading\">Display \/ evaluate the data in Excel <\/h3>\n\n<p>The nice thing about &#8220;.csv&#8221; files is that you can evaluate them in Excel, as long as they are properly formatted. Properly formatted means:<\/p>\r\n<ul>\r\n<li>One set of values per line.<\/li>\r\n<li>The values are separated by a separator, in Germany a semicolon.<\/li>\r\n<li>Excel can read &#8220;.csv&#8221; files if they contain a maximum of 1,048,576 (=2<sup>20<\/sup>) lines.<\/li>\r\n<\/ul>\r\n<p>The separator is not defined in Excel, but in the operating system. In Windows 11 you can change this under: Settings \u2192 Time and Language \u2192 Language and Region \u2192 Administrative Language Settings \u2192 Tab: Formats \u2192 Other Settings \u2192 List Separator. Well hidden!<\/p>\r\n\n<p>So you take your &#8220;.csv&#8221; file and import it into Excel:<\/p>\r\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_raw_in_excel.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_raw_in_excel.png\" alt=\"data_log.csv after import into Excel\" class=\"wp-image-16548\" width=\"510\" height=\"222\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_raw_in_excel.png 1019w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_raw_in_excel-300x131.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_raw_in_excel-768x335.png 768w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/a><figcaption class=\"wp-element-caption\">data_log.csv after import into Excel<\/figcaption><\/figure><\/div>\n<p>Don&#8217;t worry, the seconds have not disappeared. If you click in the individual lines, they will be displayed.<\/p>\r\n<p>And now you can make statistical evaluations or use the many options for graphical representation, for example like this:<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_in_excel-1024x377.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"377\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_in_excel-1024x377.png\" alt=\"Display of the measurement data in Excel\" class=\"wp-image-16550\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_in_excel-1024x377.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_in_excel-300x110.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_in_excel-768x283.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/datalogger_in_excel.png 1215w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Display of the measurement data in Excel<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\" id=\"multiple_sd_cards\">Using multiple SD card modules<\/h2>\n\n<p>You want to use multiple SD card modules? No problem. You just have to create a separate SDClass object for each SD card or SD card module and assign a CS pin. The SD cards share the MISO, MOSI and SCK lines. This is what it would look like for two modules:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"sd_card_two_sds.ino\" data-enlighter-title=\"sd_card_two_sds.ino\">#include &lt;SD.h&gt;\r\nconst int csPin_1 = 9;\r\nconst int csPin_2 = 10;\r\n\r\nSDClass mySD_1;\r\nSDClass mySD_2;\r\n\r\nvoid setup(){\r\n  Serial.begin(9600);  \r\n  if(!mySD_1.begin(csPin_1)){\r\n    Serial.println(\"SD-Card 1 not connected!\");\r\n    while(1);\r\n  }\r\n  else{\r\n    Serial.println(\"SD-Card 1 initialized\");\r\n  }\r\n\r\n  if(!mySD_2.begin(csPin_2)){\r\n    Serial.println(\"SD-Card 2 not connected!\");\r\n    while(1);\r\n  }\r\n  else{\r\n    Serial.println(\"SD-Card 2 initialized\");\r\n  }\r\n}\r\n\r\nvoid loop(){}<\/pre>\r\n\n<p>On an ESP32, you could alternatively use two separate SPI interfaces.<\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>SD cards are the medium of choice for storing large amounts of data. I show how to control SD card modules with the Arduino.<\/p>\n","protected":false},"author":1,"featured_media":16644,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[565],"tags":[556,1967,1961,1044,655,1662,1963,1964,1962,1965,1971,1970,1969,1959,1960,1966,1968],"class_list":["post-16958","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-other-parts","tag-arduino-en-2","tag-csv-en","tag-data-logger-en","tag-esp32-en","tag-esp8266-en","tag-excel-en","tag-fat16-en","tag-fat32-en","tag-formatting","tag-microsd-en","tag-multiple-sd-cards","tag-power-consumption-en","tag-read","tag-sd-en","tag-sd-card","tag-shield-en","tag-write"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>SD cards and SD card modules &#8226; Wolles Elektronikkiste<\/title>\n<meta name=\"description\" content=\"SD cards are the medium of choice for storing large amounts of data. I show how to control SD card modules with the Arduino.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SD cards and SD card modules &#8226; Wolles Elektronikkiste\" \/>\n<meta property=\"og:description\" content=\"SD cards are the medium of choice for storing large amounts of data. I show how to control SD card modules with the Arduino.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules\" \/>\n<meta property=\"og:site_name\" content=\"Wolles Elektronikkiste\" \/>\n<meta property=\"article:published_time\" content=\"2022-12-23T14:29:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-03-01T22:29:16+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Postimage_SD_Card_Modules.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1000\" \/>\n\t<meta property=\"og:image:height\" content=\"1000\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Wolfgang Ewald\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Wolfgang Ewald\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"22 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules\"},\"author\":{\"name\":\"Wolfgang Ewald\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"headline\":\"SD cards and SD card modules\",\"datePublished\":\"2022-12-23T14:29:04+00:00\",\"dateModified\":\"2023-03-01T22:29:16+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules\"},\"wordCount\":3086,\"commentCount\":7,\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/Postimage_SD_Card_Modules.jpg\",\"keywords\":[\"Arduino\",\"csv\",\"data logger\",\"ESP32\",\"ESP8266\",\"Excel\",\"FAT16\",\"FAT32\",\"Formatting\",\"microSD\",\"multiple SD cards\",\"power consumption\",\"read\",\"SD\",\"SD card\",\"shield\",\"write\"],\"articleSection\":[\"Other parts\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules\",\"name\":\"SD cards and SD card modules &#8226; Wolles Elektronikkiste\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/Postimage_SD_Card_Modules.jpg\",\"datePublished\":\"2022-12-23T14:29:04+00:00\",\"dateModified\":\"2023-03-01T22:29:16+00:00\",\"description\":\"SD cards are the medium of choice for storing large amounts of data. I show how to control SD card modules with the Arduino.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules#primaryimage\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/Postimage_SD_Card_Modules.jpg\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/Postimage_SD_Card_Modules.jpg\",\"width\":1000,\"height\":1000},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/sd-cards-and-sd-card-modules#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SD cards and SD card modules\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\",\"name\":\"Wolles Elektronikkiste\",\"description\":\"Die wunderbare Welt der Elektronik\",\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\",\"name\":\"Wolfgang Ewald\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"width\":512,\"height\":512,\"caption\":\"Wolfgang Ewald\"},\"logo\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"SD cards and SD card modules &#8226; Wolles Elektronikkiste","description":"SD cards are the medium of choice for storing large amounts of data. I show how to control SD card modules with the Arduino.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules","og_locale":"en_US","og_type":"article","og_title":"SD cards and SD card modules &#8226; Wolles Elektronikkiste","og_description":"SD cards are the medium of choice for storing large amounts of data. I show how to control SD card modules with the Arduino.","og_url":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules","og_site_name":"Wolles Elektronikkiste","article_published_time":"2022-12-23T14:29:04+00:00","article_modified_time":"2023-03-01T22:29:16+00:00","og_image":[{"width":1000,"height":1000,"url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Postimage_SD_Card_Modules.jpg","type":"image\/jpeg"}],"author":"Wolfgang Ewald","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Wolfgang Ewald","Est. reading time":"22 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules#article","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules"},"author":{"name":"Wolfgang Ewald","@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"headline":"SD cards and SD card modules","datePublished":"2022-12-23T14:29:04+00:00","dateModified":"2023-03-01T22:29:16+00:00","mainEntityOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules"},"wordCount":3086,"commentCount":7,"publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Postimage_SD_Card_Modules.jpg","keywords":["Arduino","csv","data logger","ESP32","ESP8266","Excel","FAT16","FAT32","Formatting","microSD","multiple SD cards","power consumption","read","SD","SD card","shield","write"],"articleSection":["Other parts"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules","url":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules","name":"SD cards and SD card modules &#8226; Wolles Elektronikkiste","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#website"},"primaryImageOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules#primaryimage"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Postimage_SD_Card_Modules.jpg","datePublished":"2022-12-23T14:29:04+00:00","dateModified":"2023-03-01T22:29:16+00:00","description":"SD cards are the medium of choice for storing large amounts of data. I show how to control SD card modules with the Arduino.","breadcrumb":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules#primaryimage","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Postimage_SD_Card_Modules.jpg","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/11\/Postimage_SD_Card_Modules.jpg","width":1000,"height":1000},{"@type":"BreadcrumbList","@id":"https:\/\/wolles-elektronikkiste.de\/en\/sd-cards-and-sd-card-modules#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/wolles-elektronikkiste.de\/en"},{"@type":"ListItem","position":2,"name":"SD cards and SD card modules"}]},{"@type":"WebSite","@id":"https:\/\/wolles-elektronikkiste.de\/en#website","url":"https:\/\/wolles-elektronikkiste.de\/en","name":"Wolles Elektronikkiste","description":"Die wunderbare Welt der Elektronik","publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wolles-elektronikkiste.de\/en?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46","name":"Wolfgang Ewald","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","width":512,"height":512,"caption":"Wolfgang Ewald"},"logo":{"@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png"}}]}},"_links":{"self":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/16958","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/comments?post=16958"}],"version-history":[{"count":0,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/16958\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media\/16644"}],"wp:attachment":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media?parent=16958"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/categories?post=16958"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/tags?post=16958"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}