Arduino Giga R1 as Datalogger for temperature Data

Hello,
I am a student entrusted with a project to datalog data on an SD card. My problem now is using USB Stick however since I couldn`t initialize SD-card with the SD.h library (error: double declaration in library) or SDFat.h library since just Initialization failed on Serial Monitor after I tried different shields and SD cards.

Now asking my company I can use USB-A port. I tried FileWrite example included PA_15 Output and High for arduino Giga, tried with fat32 formatted mbr partitioned usb stick 16gb and 4gb. always fclose error -5 or just Fail on serial monitor. after some tries microcontroller crashes and red led flashing until i press double reset and ide finds my board again. tried also with SD-Card in USB Card reader. Other thread with same issue was closed. About any ideas or similar problems i would be grateful.

1 Like

Hi @chrisus3 , there can be a number of issues as different USB drives require different configurations, making it hard to troubleshoot.

Some things you could check out that might help:

  • Try locate the DIR* d = opendir("/usb/") line in your sketch. This need to match the name of your USB drive.
  • Try run the sketch located here. This only checks the directory of your USB drive, and prints them out. If this works, likely something is wrong in your write operation. If it fails, it means that you are not able to access the USB drive at all.

Hope this is of any help!

1 Like

Thank you for your reply. I tried it now with a USB Flash Drive "LAETA" 2.0 from the company hama. the filewrite example still gives me an error on the serial monitor saying: fclose error:I/O error (-5); However different from the USB Flash Drive "ROTATE" 2.0 from the same company that gave me the mounting error, or wasn`t accessed at all. On "LAETA" a file number.txt was created however nothing was written inside the file. I then ran the listfile sketch from the link you showed me. 2 Files were found. So it means i can access the USB-Stick.

I couldn`t find the DIR* d = opendir("/usb/") line in the fileWrite example sketch which is as follows:

#include <Arduino_USBHostMbed5.h>
#include <DigitalOut.h>
#include <FATFileSystem.h>

USBHostMSD msd;
mbed::FATFileSystem usb("usb");

// mbed::DigitalOut pin5(PC_6, 0);
mbed::DigitalOut otg(PB_8, 1);

void setup() {
  Serial.begin(115200);
    pinMode(PA_15, OUTPUT);
  digitalWrite(PA_15, HIGH);
  while (!Serial);
  msd.connect();

  while (!msd.connected()) {
    //while (!port.connected()) {
    delay(1000);
  }

  Serial.println("Mounting USB device...");
  int err =  usb.mount(&msd);
  if (err) {
    Serial.print("Error mounting USB device ");
    Serial.println(err);
    while (1);
  }
  Serial.print("read done ");
  mbed::fs_file_t file;
  struct dirent *ent;
  int dirIndex = 0;
  int res = 0;
  Serial.println("Open /usb/numbers.txt");
  FILE *f = fopen("/usb/numbers.txt", "w+");
  for (int i = 0; i < 10; i++) {
    Serial.print("Writing numbers (");
    Serial.print(i);
    Serial.println("/10)");
    fflush(stdout);
    err = fprintf(f, "%d\n", i);
    if (err < 0) {
      Serial.println("Fail :(");
      error("error: %s (%d)\n", strerror(errno), -errno);
    }
  }

  Serial.println("File closing");
  fflush(stdout);
  err = fclose(f);
  if (err < 0) {
    Serial.print("fclose error:");
    Serial.print(strerror(errno));
    Serial.print(" (");
    Serial.print(-errno);
    Serial.print(")");
  } else {
    Serial.println("File closed");
  }
}

void loop() {

}

I would be grateful for every hint

If anyone found a solution please tell me. I accidentaly deleted the only partition on my usb stick with aomei. for recovery ofc they ask money. I used a different opensource tool it couldnt find my partition so i created a new partition with diskpart. Still at the same point. Only this stick has created a file but fclose error. the other give me mounting error suddenly or the MC crashes constantly also always if i try to use a USBHOSTMbed5 version higher than 0.0.3. Why is it working in the youtube video and not here now. I cant buy endless sticks from many companys since its not in the budget. Where is the support of Arduino. I`m about to be fed up with their products.

Have you tried the DirList example?

That's where you will find the command DIR* d = opendir("/usb/");

yes thank you, of course i tried it. it works. it shows a file numbers.txt created. if i open the file nothing is in there.

In your file open statement, try using the append method like,

FILE *f = fopen("/usb/numbers.txt", "a+");


That's what I use for my data logging to a USB flash drive with Arduino Giga R1.

Also, try moving the fflush(stdout); statement out of the loop. Put right after the file open statement.

I put my file writing code into a separate function, which is listed below.

My main code generates a single long string by converting all my numeric data and then function puts the string into a character array for writing to the file after I have it write a single float value and a comma,

Maybe you see something here that will help.

void WriteToFile() {
  mbed::fs_file_t file;
  struct dirent *ent;
  int dirIndex = 0;
  int res = 0;

// Serial.println("Opening file..");
  
    FILE *f = fopen("/usb/logwww.txt", "a+");

    fflush(stdout);

    stringLength  = logString.length() + 1;    //The +1 is for the 0x00h Terminator
    char  CharArray[stringLength];
    logString.toCharArray(CharArray, stringLength);

    err = fprintf(f, "%5.2f", dayHours);
    err = fprintf(f, "%s", ",");
    for(int v = 0; v < stringLength; v++) {
      err = fprintf(f, "%c", CharArray[v]);
    }
    
    err = fprintf(f, "%s", "\n");

    if (err < 0) {
      Serial.println("Fail :(");
      error("error: %s (%d)\n", strerror(errno), -errno);
    }
    
// --------------
//  Serial.println("File closing");
  fflush(stdout);
  err = fclose(f);

  if (err < 0) {
    Serial.print("fclose error:");
    Serial.print(strerror(errno));
    Serial.print(" (");
    Serial.print(-errno);
    Serial.print(")");
  } else {
    delay(1);
    // Serial.println("File closed");
  }
}

Thank you I will study this in detail later.

FILE *f = fopen(FILE *f = fopen("/usb/numbers.txt", "w+");
is in my example program. I don`t know why its a+ istead of w+ however

Yes thank you. Actually I have an update: I found an old Stick from Quimonda the 2009 bankrupt fallen subsidiary of Infineon. The example filewrite worked on it without any modifications.

I might try your suggestions on the other stick LAETA from hama that didn`t accept the file closing.

Now my problem is that I dont need a terminated logging of 10 numbers but a continous logging of data until the moment the usb stick is unplugged and plugged to a notebook to see the logged data. So basically I need the filewriting as an endless loop. however that way its impossible to close the file or do I have to close the file after each reading and create a new file for every value that is also not the goal.

Therefore I removed the whole fclose section from the code. I could upload it. I pulled the stick and the readings are on the stick until the moment i unplugged the stick. but the arduino crashed few seconds later.

As I mentioned I tried before using SD card shield and for datalogging the data I planned to use the code walkthrough from adafruit for datalogging: Code Walkthrough | Adafruit Data Logger Shield | Adafruit Learning System

In their code they create a file with a different command. However I don`t know if that command only exist in the SDFAT library:

File logfile;
logfile = SD.open(filename, FILE_WRITE); 
or if that goes analog for USB sticks or if FILE_WRITE exists outside of the library.

Anyway the writing to the file happens in the loop function without ever closing the file.
So I would like to know the difference or if that only applies for Sd cards and the board won`t crash since they are plugged into SD Shields and not directly on the board.

Hello, It seems you are making progress with your project. That's good.

In my case, I write data to the USB Stick every 233 seconds, so about 371 times per day. Because the data write takes only a fraction of a second, I adopted the practice of closing the file after each write operation and then opening it again for the next one.

My device also has a micro-SD card break-out board and I write to it as well. I use it for longer time periods for recording my data. You are correct in noting that writing to micro-SD and to USB Stick requires 2 different command formats.

You mention your Arduino crashes when you unplug the stick. Maybe that is a result of it trying to write to a memory device that's no longer there.

1 Like

Same issue. No resolution. Multiple similar suggestions. Why can't it work with all flashdrive and usb SD card reader and everything which allows it to make a file and is a flash storage. Has anyone tried using Arduino unified library for all data storage?

1 Like

I am at zero again. My teacher said I cant use that stick since its my own stick and not available anymore to purchase. Also my company allowed me to find the solution with the arduino mega so I was back to SD-cards. I used the datalogger shield with included RTC from azdelivery. It didnt work. My research showed it was different from the adafruit shield somehow similar to the old adafruit shield then I found an explanation from azdelivery to have to solder some pins and connect some wires as their shield only works for arduino uno and mega/giga uses differen chips. I did that didnt work as for others in their comment section. someone from their team commented to have to remove some pins. I cut them. Still didnt work. Dont know why. Cantt reattach the pins however so now a part my company paid is useless unless I remove all the solder and replace the pins. It doesn`t matter.

I tried then with the microsdcard shields from azdelivery which I ordered myself. Still used the updated sd.h library from github as adafruit and azdelivery said to be able to use a different methods to include pin 10,11,12,13.

while (!card.init(SPI_HALF_SPEED, 10, 11, 12, 13))

i ran sdinfo example software and see the sdcard was recognized. but here my luck stopped. I tried to run the datalogger example from the library, i added the code for reading my temperature sensor. with or without my code it stops in the setup in that line

 if (! dataFile) {
    Serial.println("error opening datalog.txt");
    // Wait forever since we cant write data
    while (1) ;
  }

it prints error opening datalog.txt since the file was never created. So my card can be recognized but no file is created. the card is formatted fat32 nothing wrong with it.

I mean im still in the beginning since i have to include the rtc and have to send the temperature data to a display too and have to write a 40 page paper about it and submit until the end of april. Its impossible to do all that with that speed of results. My whole course is about to fail. Like what can I do. building a switch cabinet for a machine as a project would have been easier since it`s not as error prone as the whole arduino thing.

#include <SPI.h>
#include <SD.h>
#include "max6675.h"

Sd2Card card;
SdVolume volume;
SdFile root;
// Define the pins for the MAX6675 sensor
const int thermoDO2 = 40;
const int thermoCS2 = 42;
const int thermoCLK2 = 44;

// Define the chip select pin for the SD card shield
const int chipSelect = 10;

// Create an instance of the MAX6675 library
MAX6675 thermocouple(thermoCLK2, thermoCS2, thermoDO2);

void setup() {
  // Initialize serial communication
  Serial.begin(9600);

  // Initialize the SD card
  while (!card.init(SPI_HALF_SPEED, 10, 11, 12, 13))  {
    Serial.println("SD card initialization failed!");
    while (1); // Halt execution
  }
  Serial.println("SD card initialized successfully.");
}

void loop() {
  // Read temperature from MAX6675
  double temperatureC = thermocouple.readCelsius();
  if (isnan(temperatureC)) {
    Serial.println("Error reading temperature!");
    return;
  }

  // Open the SD card file for appending
  File dataFile = SD.open("temperature_log.txt", FILE_WRITE);
  if (dataFile) {
    dataFile.print(temperatureC);
    dataFile.println(" °C");
    dataFile.close();
    Serial.println("Temperature logged successfully.");
  } else {
    Serial.println("Error opening file for writing!");
  }

  delay(1000); // Log temperature every second
}

this code was created by bing copilot
i get error opening file



#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include "max6675.h"
#include <SPI.h>

Sd2Card card;
SdVolume volume;
SdFile root;
/*int thermoDO1 = 48;
int thermoCS1 = 50;
int thermoCLK1 = 52; */

int thermoDO2 = 40;
int thermoCS2 = 42;
int thermoCLK2 = 44;

/*int thermoDO3 = 32;
int thermoCS3 = 34;
int thermoCLK3 = 36;

int thermoDO4 = 24;
int thermoCS4 = 26;
int thermoCLK4 = 28;

int thermoDO5 = 49;
int thermoCS5 = 51;
int thermoCLK5 = 53;*/

/*MAX6675 thermocouple1(thermoCLK1, thermoCS1, thermoDO1);*/
MAX6675 thermocouple2(thermoCLK2, thermoCS2, thermoDO2);
/*MAX6675 thermocouple3(thermoCLK3, thermoCS3, thermoDO3);
MAX6675 thermocouple4(thermoCLK4, thermoCS4, thermoDO4);
MAX6675 thermocouple5(thermoCLK5, thermoCS5, thermoDO5);*/

const int chipSelect = 10;

File dataFile;


void setup() {
  Serial.begin(9600);
  Serial.println("MAX6675 test");  // wait for MAX chip to stabilize
  
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(SS, OUTPUT);
  
  // see if the card is present and can be initialized:
  while (!card.init(SPI_HALF_SPEED, 10, 11, 12, 13)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card is inserted?");
    Serial.println("* Is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
  } 
  Serial.println("card initialized.");
  
  // Open up the file we're going to log to!
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (! dataFile) {
    Serial.println("error opening datalog.txt");
    // Wait forever since we cant write data
    while (1) ;
  }

  delay(500);
  
  }

  
  


void loop() {

  dataFile.println(thermocouple2.readCelsius());

 Serial.print("Element1 C = ");
  Serial.println(thermocouple2.readCelsius());
  /*Serial.print("\tElement2 C = ");
  Serial.print(thermocouple2.readCelsius());
  Serial.print("\tElement3 C = ");
  Serial.print(thermocouple3.readCelsius());
  Serial.print("\tElement4 C = ");
  Serial.print(thermocouple4.readCelsius());
  Serial.print("\tElement5 C = ");
  Serial.println(thermocouple5.readCelsius());*/
  dataFile.flush();
  delay(1000);

  
}

this is the code from the sd.h library example "datalogger"

error opening datalog.txt

so something with the sd.open doesn`t work here

in github sd library had to use card.init instead of sd.begin

Trying to use the datalogger shield again.

I found for the adafruit sd.h library on github a recommendation from adafruit as following:

Arduino Mega 2560 R3 or Mega ADK
The RTC is compatible. For the SD card, the following may be tried, in decreasing order of recommendation:

Use the Adafruit SD library, specifying pin 10 for chip select, 11 for MOSI, 12 for MISO and 13 for SCK.
Edit the file utility/Sd2Card.h in the default Arduino SD library, changing line 42 to read "#define MEGA_SOFT_SPI 1" (default is 0).

When i changed MEGA_SOFT_SPI 0 to MEGA_SOFT_SPI 1 i got those compiler error  error: 'SPI' was not declared in this scope
   SPI.setClockDivider(v);
   ^~~

Data Logging Shield (Assembled) | Adafruit Shield Compatibility Guide | Adafruit Learning System

however the shield from azdelivery I removed as said before pin 11,12,13 on the shield and connected them by wires with 51,50 and 52 as suggested by the company azdelivery themselves ( Daten Logger Shield am MEGA R3 (az-delivery.de) and specified it in my code. Why pin 4 and 5 was supposed to be removed from the shield is without any explanation. First trying to initialize and failed. Then changed the Sd2Card.h as suggested from adafruit to MEGA Soft spi 1 with the error

For what it’s worth I have done some playing with sd on GIGA.
For example in the thread.

I would personally use SdFat library you can install using library manager. Also better luck with Sd adapters without level converters. More in other thread. Also a good thread by the author of SdFat

Thank you for your reply.

It`s been months now but I started with arduino Giga and sd cards. so i figured as much by reading your posts in the other threads that on giga only the sdfat library is working, and i also used the spi1 header in the middle still the initialization failed.

maybe i should order the exact sparkfun shield you are using. I don`t know if I have level shifters and what they do.

I will do some experimenting and then upload pictures of my setup later

this is the spi reader shield i used :
SPI Reader EN.pdf (634,7 KB)

The reader you linked to, has TTL level shifters, to convert from/to 5v signals from the Arduino UNO to 3.3v for the SD Card. Note: I am a retired software guy... So take my EE stuff with grain of salt.
But on your reader I am pretty sure:
image
Where I drew the green arrow is the level sifter IC. With some boards like this you can connect a 3.3v pin into the VCC and it will work. That is the level shift then from 3.3v to 3.3v... But that might depend on what Voltage regulator they use to convert the VCC input to 3.3v..

The GIGA is a 3.3v processor. I could easily be wrong, but I don't believe that the IO pins are 5v tolerant. Which if they are not, placing a 5v signal onto them could damage the board. But it also depends on how these adapter boards handle output back to your board. Some simply pass the 3.3v signals back to you and others level shift them back to the voltage you passed in on VIN...

So several companies like SparkFun, Adafruit sell a couple of different adapters.

Sparkfun:
Without level shifter: SparkFun microSD Transflash Breakout - BOB-00544 - SparkFun Electronics

With level shifter: SparkFun Level Shifting microSD Breakout - DEV-13743 - SparkFun Electronics

Adafruit:
Without level shifter:
Adafruit Micro SD SPI or SDIO Card Breakout Board - 3V ONLY! : ID 4682 : Adafruit Industries, Unique & fun DIY electronics and kits

With level shifter
MicroSD card breakout board+ : ID 254 : Adafruit Industries, Unique & fun DIY electronics and kits
(This one I have had some luck using on 3.3v circuits)

Thank you.

The MISO Output is 3 Volts measured with my multimeter. So I don`t think my board pins are damaged. Thank you for the links, however I would like to order as fast as possible and all of them seem to not be located in my country.

So now I connected my sd board to the spi 1 header. however I need a code again. Do I understand correctly that the sdfat library has to be adjusted?

Can you elaborate to when to use dedicated spi and when shared spi

 #include <SPI.h>
  #include <SdFat.h>

SdFat SD;
File ZahlenZeigen;

// Definieren Sie die Pins für den SPI-Header
#define MISO_PIN 89  // CIPO
#define MOSI_PIN 90  // COPI
#define SCK_PIN 91   // SCK
#define CS_PIN 52     // CS

void setup() {
  Serial.begin(9600);
  while (!Serial) { ; };

  // Setzen Sie die Pins für den SPI-Header
  pinMode(MISO_PIN, INPUT);
  pinMode(MOSI_PIN, OUTPUT);
  pinMode(SCK_PIN, OUTPUT);
  pinMode(CS_PIN, OUTPUT);

  Serial.print("Initialisiere SD-Karte...");

  if (!SD.begin(CS_PIN)) {
    Serial.println("Initialisierung fehlgeschlagen!");
    return;
  }

  Serial.println("Initialisierung abgeschlossen.");

 Serial.println("Datei schreiben mit 's', Dateien entfernen mit 'l'");
}  

void loop() {
  while (Serial.available() > 0) {
    char Eingabe = Serial.read();  
    if (Eingabe == 'l') {
      if (SD.exists("Zahlen.txt")) {
        SD.remove("Zahlen.txt");
        Serial.println("Datei Zahlen.txt entfernt!");
      } else {
        Serial.println("Datei Zahlen.txt existiert nicht!");
      }
    }
  }
}

This is a code I found in my folder generated by bings copilot, it could be compiled however it still said initialization failed

I made the code like this correct?

#include <SPI.h>
  #include <SdFat.h>

SdFat SD;
File ZahlenZeigen;

// Definieren Sie die Pins für den SPI-Header
#define SD_FAT_TYPE 3
#define SPI_CLOCK SD_SCK_MHZ(30)
#define SD_CONFIG SdSpiConfig(CS_SD, DEDICATED_SPI, SPI_CLOCK)
#define MISO_PIN 89  // CIPO
#define MOSI_PIN 90  // COPI
#define SCK_PIN 91   // SCK
#define CS_PIN 52     // CS

void setup() {
  Serial.begin(9600);
  while (!Serial) { ; };

  // Setzen Sie die Pins für den SPI-Header
  pinMode(MISO_PIN, INPUT);
  pinMode(MOSI_PIN, OUTPUT);
  pinMode(SCK_PIN, OUTPUT);
  pinMode(CS_PIN, OUTPUT);

  Serial.print("Initialisiere SD-Karte...");

  if (!SD.begin(SD_CONFIG)) {
    Serial.println("Initialisierung fehlgeschlagen!");
    return;
  }

  Serial.println("Initialisierung abgeschlossen.");

 Serial.println("Datei schreiben mit 's', Dateien entfernen mit 'l'");
}