The other half of the adalogger FeatherWing is the SD card. The SD card is how we store long term data. While the Feather may have a permanent EEPROM storage, its only a couple hundred bytes - tiny compared to a 2 gig SD card. SD cards are so cheap and easy to get, its an obvious choice for long term storage so we use them for the 'Wing!
The FeatherWing kit doesn't come with an SD card but we carry one in the shop that is guaranteed to work. Pretty much any SD card should work but be aware that some cheap cards are 'fakes' and can cause headaches.
You'll also need a way to read and write from the SD card. Sometimes you can use your camera and MP3 player - when its plugged in you will be able to see it as a disk. Or you may need an SD card reader. The Wing doesnt have the ability to display the SD card as a 'hard disk' like some MP3 players or games, the Feather does not have the hardware for that, so you will need an external reader!
Formatting under Windows/Mac
If you bought an SD card, chances are it's already pre-formatted with a FAT filesystem. However you may have problems with how the factory formats the card, or if it's an old card it needs to be reformatted. The Arduino SD library we use supports both FAT16 and FAT32 filesystems.
If you have a very small SD card, say 8-32 Megabytes you might find it is formatted FAT12 which isn't supported. You'll have to reformat these card. Either way, it's always good idea to format the card before using, even if it's new! Note that formatting will erase the card so save anything you want first.
Cards above 32GB cannot use FAT16 so try to keep your card use to 32GB and below.
The official SD formatter is available from https://www.sdcard.org/downloads/formatter_4/
Download it and run it on your computer, there's also a manual linked from that page for use
Basic SD Card Test
The Arduino SD Card library has a built in example that will help you test the Wing and your connections
Open the file listfiles example sketch in the SD library:
This sketch will not write any data to the card, just list the contents. This can be very useful when trying to figure out whether an SD card is supported. Before trying out a new card, please try out this sketch!
Scroll to the line where you see SD.begin()
and change the value in the parentheses to match the chip select (CS) pin for your board.
- On ESP8266, the SD CS pin is on GPIO 15
- On Atmel M0, M4, 328p or 32u4 it's on GPIO 10
- On Teensy 3.x it's on GPIO 10
- On STM32F2/WICED, its on PB5
- On ESP32, it's on GPIO 33
- On nRF52832, it's on GPIO 11
- On nRF52840, it's on GPIO 10
- On ESP32-C6, its on GPIO 8
OK, now insert the micro SD card into the FeatherWing and upload the sketch.
Open up the Serial Monitor and you should see a listing of the files and folder layout. The specifics will depend on the card contents, but should look something like:
If you have a bad card, or some other formatting issue, you'll probably see:
It couldn't even initialize the SD card. This can also happen if there's a soldering error or if the card is really damaged
If you're having SD card problems, we suggest using the SD formatter mentioned above first to make sure the card is clean and ready to use!
Next steps!
Once you know the SD card works, check out the SD card library examples, SD library documentation and Notes!
Example logging sketch
If you want to try saving data to the SD card in the simplest sketch, try this example. You can adjust the delay() to set how often analog data is read from pin A0 and saved to the SD card. The red LED will blink if there's an error, and the green LED will blink when data is written to the SD card.
// SPDX-FileCopyrightText: 2019 Limor Fried/ladyada for Adafruit Industries // // SPDX-License-Identifier: MIT // Adalogger FeatherWing data logger, log data on pin A0 #include <SPI.h> #include <SD.h> // Set the pins used, varies depending on the Feather #if defined(ESP8266) #define LED_RED 0 #define SD_CS 15 #elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32C6) #define LED_RED LED_BUILTIN #define SD_CS 8 #elif defined(ESP32) #define LED_RED 13 #define SD_CS 33 #elif defined(ARDUINO_STM32F2_FEATHER) #define LED_RED PB4 #define SD_CS PB5 #elif defined(TEENSYDUINO) #define LED_RED 13 #define SD_CS 10 #elif defined(ARDUINO_FEATHER52832) #define LED_RED 17 #define SD_CS 11 #else // 32u4, M0 or 328 #define LED_RED LED_BUILTIN #define SD_CS 4 #endif File logfile; // blink out an error code void error(uint8_t errnum) { while(1) { uint8_t i; for (i=0; i<errnum; i++) { digitalWrite(LED_RED, HIGH); delay(100); digitalWrite(LED_RED, LOW); delay(100); yield(); } for (i=errnum; i<10; i++) { delay(200); yield(); } } } void setup() { Serial.begin(115200); Serial.println("\r\nAnalog logger test"); pinMode(LED_RED, OUTPUT); // see if the card is present and can be initialized: if (!SD.begin(SD_CS)) { Serial.println("Card init. failed!"); error(2); } Serial.println("SD card OK"); File root = SD.open("/"); printDirectory(root, 0); char filename[15]; strcpy(filename, "/ANALOG00.TXT"); for (uint8_t i = 0; i < 100; i++) { filename[7] = '0' + i/10; filename[8] = '0' + i%10; // create if does not exist, do not open existing, write, sync after write if (! SD.exists(filename)) { break; } } logfile = SD.open(filename, FILE_WRITE); if( ! logfile ) { Serial.print("Couldnt create "); Serial.println(filename); error(3); } Serial.print("Writing to "); Serial.println(filename); Serial.println("Ready!"); } void loop() { digitalWrite(LED_RED, HIGH); // LED onn during logging // Read the data on pin A0 and log it to SD card and to serial logfile.print("A0 = "); logfile.println(analogRead(0)); Serial.print("A0 = "); Serial.println(analogRead(0)); digitalWrite(LED_RED, LOW); // LED off when not actively logging // save the output! logfile.flush(); delay(100); // Change the delay to space out readings } void printDirectory(File dir, int numTabs) { while(true) { File entry = dir.openNextFile(); if (! entry) { // no more files break; } for (uint8_t i=0; i<numTabs; i++) { Serial.print('\t'); } Serial.print(entry.name()); if (entry.isDirectory()) { Serial.println("/"); printDirectory(entry, numTabs+1); } else { // files have sizes, directories do not Serial.print("\t\t"); Serial.println(entry.size(), DEC); } entry.close(); } }
You will need to change the sketch's SD_CS pin to match the SD card's Chip Select pin on your Feather if it is not detected by the code at the beginning of the sketch.
If you really want to make sure you save every data point, ensure there is a
logfile.flush();
right after the logfile.print's. The example does this.
However this will cause the adalogger to draw a lot more power, maybe about 3x as much on average (30mA avg rather than about 10mA).
Page last edited January 22, 2025
Text editor powered by tinymce.