Using SD Cards on Arduino Giga?

Hi all,

I am basically a beginner at this. I am planning to build an ebike computer using the arduino GIGA R1 in order to monitor the State of Charge (SoC), voltage, amperage, power, speed, odometer and so on. For some stuff I will need to use an sd card reader, the one from adafruit. This is since I need to update the SoC calculations continuously, every 20 milliseconds to be specific since this involves coulomb counting which involves integration. Ive heard that its bad to use the EEPROM to continuously update sensor values according to the portenta H7 manual which uses the same processor as the GIGA R1.

Now, the issue is that since this doesnt have an ARM processor, I am confused if an SD card will even work with it. There seems to be none or vague topics about this so anyone out there, it would be great to see and test to determine if the Adafruit SD card readers work on the GIGA R1. Someone reading this, please let me know.

there is no problem, just use a SD card module without a 5 V support added.
wire it to the SPI header and a pin for CS

I mean like these: MicroSD card breakout board+ : ID 254 : $7.50 : Adafruit Industries, Unique & fun DIY electronics and kits youre saying this should support the giga right? Also apparent sd cards can draw more than 100 milliamps and arduinos dont output that much power so do I use an external power for the power suplly for the sd card or something?

the Adafruit SD card adapter is the best. the GiGa is a 3.3 V board so it has a good 3.3 V power supply on the 3.3 V pin. but if you want you can power the Adafruit SD adapter over 5 V too.

Hello All,

Please I am new to Arduino. I am trying to build a data logger on a SD module with Arduino giga. I am trying to run an example, but it won’t run on my board . can anybody tell me what the problem is? The Sd module is the digilent Pmod SD module available here Pmod SD: Full-sized SD Card Slot - Digilent and the ardiuno board is the arduino giga R1 wifi

I have wired the SD module on CS to 10, mosi to 11 ,miso to 12 , sclk to 13 gnd to gnd and vcc to 3.3V I ran the sketch below, but it keeps telling me initialisation failed. The sketch is from the examples for Sdfat libraries readwrite .

This sketch ran on the Arduino mega and the uno. But I need it to run on the giga R1 Wifi as the project is to measure and log the environmental conditions in the smart home and then log it in the SD card and also on a IoT cloud platform. The giga is ideal for this project as I can run multiple sensors on it (DHT temperature and humidity sensors , PIR sensor, space utilisation Sensor, C02 levels sensor etc), and not run out of pins and it has inbuilt Wi-Fi for connection to the Arduino cloud platform where the 2nd data logging will occur. ( the first one will be on the sd card) . Any help as to why this isn’t initialising will be appreciated. Thank you very much

The code in question is below

/*
  SD card read/write

 This example shows how to read and write data to and from an SD card file
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13

 created   Nov 2010
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe

 This example code is in the public domain.

 */

#include <SPI.h>
//#include <SD.h>
#include "SdFat.h"
SdFat SD;

#define SD_CS_PIN 10
File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  if (!SD.begin(SD_CS_PIN)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop() {
  // nothing happens after setup
}


sequel to the above, i have purchased a adafruit microsd breakout board seen here https://www.amazon.co.uk/Adafruit-254-MicroSD-Breakout-Board/dp/B084QH2TXN/ref=sr_1_9?crid=1P67BX9O1MOQR&keywords=Adafruit+MicroSD+Card+Breakout+Board%2B+Adapter&qid=1699534972&sprefix=adafruit+microsd+card+breakout+board%2B+adapter%2Caps%2C80&sr=8-9
still it hasnt worked. can anyone help?

I have not tried this yet with these boards, but I believe you need to do something like:
Change the line:

if (!SD.begin(SD_CS_PIN)) {

To something like:

if (!SD.begin(SdSpiConfig(SD_CS_PIN, SHARED_SPI, SD_SCK_MHZ(16), &SPI1))) {

If it works, you might try changing the clock speed mentioned to something higher...

1 Like

Thanks for the suggestion @KurtE , i just tried it . it didnt work

Quick and dirty setup:
image

I modified the directory function example for SDFat... Note I have the Adafruit fork of it, so not sure how different...

/*
 * Example use of chdir(), ls(), mkdir(), and  rmdir().
 */
#include "SdFat.h"
#include "sdios.h"

// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
#define SD_FAT_TYPE 1
/*
  Change the value of SD_CS_PIN if you are using SPI and
  your hardware does not use the default value, SS.
  Common values are:
  Arduino Ethernet shield: pin 4
  Sparkfun SD shield: pin 8
  Adafruit SD shields and modules: pin 10
*/

// SDCARD_SS_PIN is defined for the built-in SD on some boards.
const uint8_t SD_CS_PIN = 10;

// Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
#define SPI_CLOCK SD_SCK_MHZ(50)

#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK, &SPI1)
//------------------------------------------------------------------------------

#if SD_FAT_TYPE == 0
SdFat sd;
File file;
File root;
#elif SD_FAT_TYPE == 1
SdFat32 sd;
File32 file;
File32 root;
#elif SD_FAT_TYPE == 2
SdExFat sd;
ExFile file;
ExFile root;
#elif SD_FAT_TYPE == 3
SdFs sd;
FsFile file;
FsFile root;
#endif  // SD_FAT_TYPE

// Create a Serial output stream.
ArduinoOutStream cout(Serial);
//------------------------------------------------------------------------------
// Store error strings in flash to save RAM.
#define error(s) sd.errorHalt(&Serial, F(s))
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);

  // Wait for USB Serial
  while (!Serial) {
    yield();
  }
  delay(1000);
  cout << F("Type any character to start\n");
  while (!Serial.available()) {
    yield();
  }

  // Initialize the SD card.
  if (!sd.begin(SD_CONFIG)) {
    sd.initErrorHalt(&Serial);
  }
  if (sd.exists("Folder1")
    || sd.exists("Folder1/file1.txt")
    || sd.exists("Folder1/File2.txt")) {
    error("Please remove existing Folder1, file1.txt, and File2.txt");
  }

  int rootFileCount = 0;
  if (!root.open("/")) {
    error("open root");
  }
  while (file.openNext(&root, O_RDONLY)) {
    if (!file.isHidden()) {
      rootFileCount++;
    }
    file.close();
    if (rootFileCount > 10) {
      error("Too many files in root. Please use an empty SD.");
    }
  }
  if (rootFileCount) {
    cout << F("\nPlease use an empty SD for best results.\n\n");
    delay(1000);
  }
  // Create a new folder.
  if (!sd.mkdir("Folder1")) {
    error("Create Folder1 failed");
  }
  cout << F("Created Folder1\n");

  // Create a file in Folder1 using a path.
  if (!file.open("Folder1/file1.txt", O_WRONLY | O_CREAT)) {
    error("create Folder1/file1.txt failed");
  }
  file.close();
  cout << F("Created Folder1/file1.txt\n");

  // Change volume working directory to Folder1.
  if (!sd.chdir("Folder1")) {
    error("chdir failed for Folder1.\n");
  }
  cout << F("chdir to Folder1\n");

  // Create File2.txt in current directory.
  if (!file.open("File2.txt", O_WRONLY | O_CREAT)) {
    error("create File2.txt failed");
  }
  file.close();
  cout << F("Created File2.txt in current directory\n");

  cout << F("\nList of files on the SD.\n");
  sd.ls("/", LS_R);

  // Remove files from current directory.
  if (!sd.remove("file1.txt") || !sd.remove("File2.txt")) {
    error("remove failed");
  }
  cout << F("\nfile1.txt and File2.txt removed.\n");

  // Change current directory to root.
  if (!sd.chdir()) {
    error("chdir to root failed.\n");
  }

  cout << F("\nList of files on the SD.\n");
  sd.ls(LS_R);

  // Remove Folder1.
  if (!sd.rmdir("Folder1")) {
    error("rmdir for Folder1 failed\n");
  }
  cout << F("\nFolder1 removed.\n");
  cout << F("\nList of files on the SD.\n");
  sd.ls(LS_R);
  cout << F("Done!\n");
}
//------------------------------------------------------------------------------
// Nothing happens in loop.
void loop() {}

I put in an SD Card that I had just formatted on my PC, as this sketch wants an empty card...

Type any character to start
Created Folder1
Created Folder1/file1.txt
chdir to Folder1
Created File2.txt in current directory

List of files on the SD.
Folder1/
  file1.txt
  File2.txt

file1.txt and File2.txt removed.

List of files on the SD.
Folder1/

Folder1 removed.

List of files on the SD.
Done!

Note: My SD Adapter is one from Sparkfun,
SparkFun microSD Transflash Breakout - BOB-00544 - SparkFun Electronics

I used it as it did not have Level shifters on it. As the GIGA is a 3.3v IOs.

I pulled out another version that does have level shifters on board, but you need to be careful as I don't believe the GIGA likes 5v signals on the IO pins.

As the Sparkfun getting started guide for the level shifted version mentioned:

The SparkFun Shifting microSD Breakout is quite similar to the SparkFun microSD Transflash Breakout, but with the additional feature of being 5.0V tolerant for ease of use. No more discrete level shifting is required! If you are using a 3.3V device, we recommend using the microSD Transflash Breakout without the level translation.

EDIT: It looks like the Adafruit adapter might be OK. It does level shifting Down from the CS, MOSI and SCLK pins, and it leaves the MISO pin unchanged going back, which would be 3.3v.

Other potential gotchas, include, if you have multiple SPI devices connected, and you don't have external Pull UP resistors on the CS pins, then there is the potential that other devices might see their CS pin as logically low and the two devices will compete for the data at startup.

In cases like that, either add external PU resistors, or in your sketch before you start the begin methods like on the SD, add code like:
pinMode(CS_PIN1, OUTPUT); digitalWrite(CS_PIN1, HIGH);
in for each of those pins...

1 Like

i ran this sketch and it gave me the following error:

Type any character to start
begin() failed
Do not reformat the SD.
No card, wrong chip select pin, or wiring error?
SdError: 0X1,0XFF

Maybe show a picture of your setup.

It might help to spot if there are any differences in the wiring or some obvious issue.

Also what SD cards have you tried? How were they formatted?

I use SparkFun OpenLog modules. Very simple setup, runs at 3.3v or 5v, connects over serial ports and logs to the sd card everything sent over the TX pin. There is a command mode that allows you to tailor the functionality.

please note that the same set up has run on the arduino uno and the arduino Mega with no problems.

i have used 3 sd cards: the first 32 gb , the second 4 gb , one being tried now is 2gb

@anon6971307 have you run this datalogger with the arduino Giga?

like i said before, this works with ardino uno and mega , i just doesnt work with the giga. i suspect this is a problem with the giga either a driver or a library or something which i cant see to figure out.

i have also formatted the sd card with the sd card formatter that i downloaded to my local machine.

It works just as well on the giga as the mega. There is no library to install so, as long as the uarts are working, the openlog will too.

I could be wrong, but I believe your setup has the potential to fry the SD cards and maybe the IO pins on your GIGA. As SD Cards are setup to run on 3.3v and likewise for your MEGA, and you are feeding 5v to the the adapter

Again I believe you said that you are usign one of:
Pmod SD: Full-sized SD Card Slot - Digilent
Which appears to match your Photo.
From looking at the photos, plus their documentation:
Using the Pmod SD with Arduino Uno - Hackster.io

You see the setup to use this board with an Arduino UNO which is 5v.

:crossed_fingers: nothing is hurt.

But try moving the VCC pin from the 5v to the 3.3v pin and see if that helps

i tried 3.3v it didnt work. the wiring diagram i am using comes from the Pmod packaging as below

Sorry not sure what else I can say, hopefully someone from Arduino will comment on it.

If you look at their schematic:
PmodSD.sch (digilent.com)

You will see that the VCC pins go directly to the SD adapter, plus there are 10K PU resistors on most all of the IO pins. So it is feeding the VCC back to the IO pins on the GIGA.
Which the logic level is 3.3v and I am pretty sure that the pins are not 5v tolerant.

If it were me, I would probably do a quick and dirty test to make those IO pins appear to be working OK...
I usually run something like:

//#define PINS_TO_TEST NUM_DIGITAL_PINS
#define PINS_TO_TEST 14  // maybe just pins 0-13

#define digitalWriteFast digitalWrite
#define digitalReadFast digitalRead

void setup() {
  Serial.begin(115200);
  while (!Serial && millis() < 10000)
    ;
  Serial.print("Num Digital Pins: ");
  Serial.println(NUM_DIGITAL_PINS, DEC);
  if (PINS_TO_TEST != NUM_DIGITAL_PINS) {
    Serial.print("Count testing Digital Pins: ");
    Serial.println(PINS_TO_TEST, DEC);
  }

  Serial.flush();

  testForShorts();
}

void loop() {
  allPinTest();
}

uint32_t pinLast[NUM_DIGITAL_PINS];
void allPinTest() {
  uint32_t ii;
  Serial.print("PULLUP Start Vals:\n  ");
  Serial.print("PULLUP :: TEST to GND\n  ");
  for (ii = 0; ii < PINS_TO_TEST; ii++) {
    pinMode(ii, INPUT_PULLUP);
    delayMicroseconds(5);
    pinLast[ii] = digitalReadFast(ii);
    if (!pinLast[ii]) {
      Serial.print("\nd#=");
      Serial.print(ii);
      Serial.print(" val=");
    }
    Serial.print(pinLast[ii]);
    Serial.print(',');
  }
  Serial.println();
  Serial.println();
  while (1) {
    uint32_t jj, dd = 0, cc = 0, ee = 4;
    cc = 0;
    for (ii = 0; ii < PINS_TO_TEST; ii++) {
      jj = digitalReadFast(ii);
      if (jj != pinLast[ii]) {
        dd = 1;
        cc++;
        pinLast[ii] = jj;
        Serial.print("d#=");
        Serial.print(ii);
        if (pinLast[ii]) Serial.print("\t");
        Serial.print(" val=");
        Serial.print(pinLast[ii]);
        Serial.print(',');
      }
      if (cc > 1 && ee) {
        Serial.println(">>> MULTI CHANGE !!");
        ee--;
      }
    }
    if (dd) {
      dd = 0;
      Serial.println();
      delay(50);
    }
  }
}

void testForShorts() {
  uint32_t ii;
  Serial.print("Quick Test for Shorts to adjacent pin");
  Serial.println("\n try Pull up and see if setting low follow");
  for (ii = 0; ii < PINS_TO_TEST - 1; ii++) {
    pinMode(ii + 1, INPUT_PULLUP);
    pinMode(ii, OUTPUT);
    digitalWrite(ii, LOW);
    delayMicroseconds(5);
    if (!digitalRead(ii + 1)) {
      Serial.print(ii, DEC);
      Serial.print(":");
      Serial.println(ii + 1, DEC);
    }
  }
  Serial.println();
}

This is extracted from another version that I run on other boards... I have it limited to just the first pins...

Once running, I then have jumper wire, one end to ground, and I touch the different IO pins which the code setup as high (INPUT_PULLUP). And if a pin changes state, it prints the new state...
And I see output like:

Num Digital Pins: 103
Count testing Digital Pins: 14
Quick Test for Shorts to adjacent pin
 try Pull up and see if setting low follow

PULLUP Start Vals:
  PULLUP :: TEST to GND
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,

d#=0 val=0,
d#=0	 val=1,
d#=1 val=0,
d#=1	 val=1,
d#=2 val=0,
d#=2	 val=1,
d#=3 val=0,
d#=3	 val=1,
d#=4 val=0,
d#=4	 val=1,
d#=13 val=0,
d#=13	 val=1,

Note I often run something like this to verify that the pins I think are connected, actually are...

Beyond that, not sure what else to try.

Hello tosky67,
Have you resolved the issue?

In the Giga documentation it says The GIGA R1 features two separate SPI (Serial Peripheral Interface) buses, one is configured on the 6 pin header (ICSP) labelled SPI, and the other is broken out into pin connections on the board. From the photos you posted, your setup uses SPI1.
I am using a micro-SD break out board and have it connected to the 6-pin ICSP header on the GIGA and it works just fine with code similar to what you have.

https://docs.arduino.cc/tutorials/giga-r1-wifi/cheat-sheet#spi

Hope this helps.