0

Adalogger writes not working
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Adalogger writes not working

by qarchitect on Thu Feb 07, 2019 6:59 pm

We have just purchased some of the Adalogger FeatherWing - RTC + SD Add-ons. I am using it with the Adafruit HUZZAH32 – ESP32 Feather Board. I am trying many different SD Card examples to write data and none work.

I have used the recommended SD Card formatter linked in the tutorial to reformat the SDCard but it has not helped. The card is a 16 gig micro SD.

First, using the program in the tutorial for logging to a file it never creates the file and just flashes the LED. However if I modify these lines:
Code: Select all | TOGGLE FULL SIZE
  strcpy(filename, "ANALOG00.TXT");
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = '0' + i/10;
    filename[7] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (! SD.exists(filename)) {
      break;
    }

}

to this:
Code: Select all | TOGGLE FULL SIZE
  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;
    }
  }


It will create the file on the SD card and if I boot again, it will indeed create the next increment of the file ANALOG01.TXT etc.

However, it still will not write any content to the file. I have tried adding
Code: Select all | TOGGLE FULL SIZE
logfile.flush();
after the logfile.prints in the loop function but still get no content in the file.

Thank you for your help.

qarchitect
 
Posts: 11
Joined: Thu Jan 28, 2016 10:44 pm

Re: Adalogger writes not working

by adafruit_support_carter on Thu Feb 07, 2019 7:54 pm

What output do you get on the serial monitor if you run the card info example?
https://learn.adafruit.com/adafruit-ada ... d-info-7-9

adafruit_support_carter
 
Posts: 10430
Joined: Tue Nov 29, 2016 2:45 pm

Re: Adalogger writes not working

by franklin97355 on Thu Feb 07, 2019 8:49 pm

Can you post the code where you write to the card? In fact please post the entire sketch you are trying to run.

franklin97355
 
Posts: 20270
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

Re: Adalogger writes not working

by qarchitect on Thu Feb 07, 2019 9:37 pm

Thanks for your responses. I will answer both request above in this reply.

First, interestingly enough, I skipped this when going through the tutorial and went right to the data logging. Coming back to it now, the CardInfo program gives me these compile errors.

Code: Select all | TOGGLE FULL SIZE
Arduino: 1.8.8 (Mac OS X), Board: "Adafruit ESP32 Feather, 80MHz, 921600, None"

CardInfo:27:1: error: 'Sd2Card' does not name a type
 Sd2Card card;
 ^
CardInfo:28:1: error: 'SdVolume' does not name a type
 SdVolume volume;
 ^
CardInfo:29:1: error: 'SdFile' does not name a type
 SdFile root;
 ^
/var/folders/6s/fqymhk4n27l029_qtg2kcmpcv5tztk/T/arduino_modified_sketch_432499/CardInfo.ino: In function 'void setup()':
CardInfo:50:8: error: 'card' was not declared in this scope
   if (!card.init(SPI_HALF_SPEED, chipSelect)) {
        ^
CardInfo:50:18: error: 'SPI_HALF_SPEED' was not declared in this scope
   if (!card.init(SPI_HALF_SPEED, chipSelect)) {
                  ^
CardInfo:63:11: error: 'card' was not declared in this scope
   switch (card.type()) {
           ^
CardInfo:64:10: error: 'SD_CARD_TYPE_SD1' was not declared in this scope
     case SD_CARD_TYPE_SD1:
          ^
CardInfo:67:10: error: 'SD_CARD_TYPE_SD2' was not declared in this scope
     case SD_CARD_TYPE_SD2:
          ^
CardInfo:70:10: error: 'SD_CARD_TYPE_SDHC' was not declared in this scope
     case SD_CARD_TYPE_SDHC:
          ^
CardInfo:78:8: error: 'volume' was not declared in this scope
   if (!volume.init(card)) {
        ^
CardInfo:78:20: error: 'card' was not declared in this scope
   if (!volume.init(card)) {
                    ^
CardInfo:84:18: error: 'volume' was not declared in this scope
   Serial.println(volume.clusterCount());
                  ^
CardInfo:109:3: error: 'root' was not declared in this scope
   root.openRoot(volume);
   ^
CardInfo:112:11: error: 'LS_R' was not declared in this scope
   root.ls(LS_R | LS_DATE | LS_SIZE);
           ^
CardInfo:112:18: error: 'LS_DATE' was not declared in this scope
   root.ls(LS_R | LS_DATE | LS_SIZE);
                  ^
CardInfo:112:28: error: 'LS_SIZE' was not declared in this scope
   root.ls(LS_R | LS_DATE | LS_SIZE);
                            ^
Multiple libraries were found for "SD.h"
 Used: /Users/username/Library/Arduino15/packages/esp32/hardware/esp32/1.0.1/libraries/SD
 Not used: /Applications/Arduino.app/Contents/Java/libraries/SD
exit status 1
'Sd2Card' does not name a type

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.


I did change the chipSelect line to use 33 as stated for ESP32 in the tutorial documentation
Code: Select all | TOGGLE FULL SIZE
const int chipSelect = 33;


As for the code that is writing, I tried several. First, I will include the code for the Datalogger example from the Arduino example library (with only a change to chipSelect pin# to 33 same as above).

Code: Select all | TOGGLE FULL SIZE
/*
  SD card datalogger

 This example shows how to log data from three analog sensors
 to an SD card using the SD library.

 The circuit:
 * analog sensors on analog ins 0, 1, and 2
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)

 created  24 Nov 2010
 modified 9 Apr 2012
 by Tom Igoe
M
 This example code is in the public domain.

 */

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

const int chipSelect = 33;

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...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
}

void loop() {
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ",";
    }
  }

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

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}



The result from running this does not yield any files on the SD Card and yields this on the serial port monitor repeatedly.
Code: Select all | TOGGLE FULL SIZE
...
error opening datalog.txt
error opening datalog.txt
error opening datalog.txt
...

However, if I change the line
Code: Select all | TOGGLE FULL SIZE
File dataFile = SD.open("datalog.txt", FILE_WRITE);

to include a forward slash before the file name like this
Code: Select all | TOGGLE FULL SIZE
File dataFile = SD.open("/datalog.txt", FILE_WRITE);

I now get a file written to the SD card called "datalog.txt" but it has no contents. Lines like this will also fill the serial port monitor window.
Code: Select all | TOGGLE FULL SIZE
...
502,0,432
3497,0,464
3491,0,468
3501,0,468
...


It would seem from this that the examples are out of date with the actual expectations of the SD library open function.

I also used the code from the tutorial posted at this link near the bottom (Example logging sketch).
https://learn.adafruit.com/adafruit-adalogger-featherwing/using-the-sd-card#example-logging-sketch-7-24
Again I change the chipSelect (or in this example cardSelect) pin# to 33. Again to get the files to actually show up on the card I had to make the changes mentioned above. The full sketch code pasted here with changes.
Code: Select all | TOGGLE FULL SIZE
#include <SPI.h>
#include <SD.h>

// Set the pins used
#define cardSelect 33

File logfile;

// blink out an error code
void error(uint8_t errno) {
  while(1) {
    uint8_t i;
    for (i=0; i<errno; i++) {
      digitalWrite(13, HIGH);
      delay(100);
      digitalWrite(13, LOW);
      delay(100);
    }
    for (i=errno; i<10; i++) {
      delay(200);
    }
  }
}

// This line is not needed if you have Adafruit SAMD board package 1.6.2+
//   #define Serial SerialUSB

void setup() {
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
  // also spit it out
  Serial.begin(115200);
  Serial.println("\r\nAnalog logger test");
  pinMode(13, OUTPUT);


  // see if the card is present and can be initialized:
  if (!SD.begin(cardSelect)) {
    Serial.println("Card init. failed!");
    error(2);
  }
  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);

  pinMode(13, OUTPUT);
  pinMode(8, OUTPUT);
  Serial.println("Ready!");
}

uint8_t i=0;
void loop() {
  digitalWrite(8, HIGH);
  logfile.print("A0 = "); logfile.println(analogRead(0));
  Serial.print("A0 = "); Serial.println(analogRead(0));
  digitalWrite(8, LOW);
 
  delay(100);
}


And I get this output on the serial port monitor.

Code: Select all | TOGGLE FULL SIZE
Analog logger test
Writing to /ANALOG01.TXT
Ready!
A0 = 3643
A0 = 3643
A0 = 3647
A0 = 3645
A0 = 3647
...

And if I hit the reset button, you can see from the output, it does see the file on the file system when I include the forward slash and uses the next increment.
Code: Select all | TOGGLE FULL SIZE
Analog logger test
Writing to /ANALOG02.TXT
Ready!
A0 = 3635
A0 = 3639
A0 = 3645


However, when I take the SD Card out and put it into computer and view the files, they are all empty.

Thanks again for you help with this.

qarchitect
 
Posts: 11
Joined: Thu Jan 28, 2016 10:44 pm

Re: Adalogger writes not working

by qarchitect on Fri Feb 08, 2019 12:25 am

After more pondering, I started to pay more attention to this in the compile errors.

Code: Select all | TOGGLE FULL SIZE
Multiple libraries were found for "SD.h"
 Used: /Users/username/Library/Arduino15/packages/esp32/hardware/esp32/1.0.1/libraries/SD
 Not used: /Applications/Arduino.app/Contents/Java/libraries/SD


At first I thought this just meant that there was an ESP32 specific version but it was still compatible with the SD Library since it seems to have similar interface for writing and tutorial does not mention anything different for ESP32 other than using 33 as chip select.

It seems that the ESP32 supplied SD.h contains a different interface pattern and a different sample. This sample does seem to work if I use chipSelect of 33.

This sample is at "File/Examples/SD(esp32)/SD_Test"

Here is the code from the example sketch
Code: Select all | TOGGLE FULL SIZE
/*
 * Connect the SD card to the following pins:
 *
 * SD Card | ESP32
 *    D2       -
 *    D3       SS
 *    CMD      MOSI
 *    VSS      GND
 *    VDD      3.3V
 *    CLK      SCK
 *    VSS      GND
 *    D0       MISO
 *    D1       -
 */
#include "FS.h"
#include "SD.h"
#include "SPI.h"

void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.println(file.name());
            if(levels){
                listDir(fs, file.name(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("  SIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }
}

void createDir(fs::FS &fs, const char * path){
    Serial.printf("Creating Dir: %s\n", path);
    if(fs.mkdir(path)){
        Serial.println("Dir created");
    } else {
        Serial.println("mkdir failed");
    }
}

void removeDir(fs::FS &fs, const char * path){
    Serial.printf("Removing Dir: %s\n", path);
    if(fs.rmdir(path)){
        Serial.println("Dir removed");
    } else {
        Serial.println("rmdir failed");
    }
}

void readFile(fs::FS &fs, const char * path){
    Serial.printf("Reading file: %s\n", path);

    File file = fs.open(path);
    if(!file){
        Serial.println("Failed to open file for reading");
        return;
    }

    Serial.print("Read from file: ");
    while(file.available()){
        Serial.write(file.read());
    }
    file.close();
}

void writeFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Writing file: %s\n", path);

    File file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }
    if(file.print(message)){
        Serial.println("File written");
    } else {
        Serial.println("Write failed");
    }
    file.close();
}

void appendFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Appending to file: %s\n", path);

    File file = fs.open(path, FILE_APPEND);
    if(!file){
        Serial.println("Failed to open file for appending");
        return;
    }
    if(file.print(message)){
        Serial.println("Message appended");
    } else {
        Serial.println("Append failed");
    }
    file.close();
}

void renameFile(fs::FS &fs, const char * path1, const char * path2){
    Serial.printf("Renaming file %s to %s\n", path1, path2);
    if (fs.rename(path1, path2)) {
        Serial.println("File renamed");
    } else {
        Serial.println("Rename failed");
    }
}

void deleteFile(fs::FS &fs, const char * path){
    Serial.printf("Deleting file: %s\n", path);
    if(fs.remove(path)){
        Serial.println("File deleted");
    } else {
        Serial.println("Delete failed");
    }
}

void testFileIO(fs::FS &fs, const char * path){
    File file = fs.open(path);
    static uint8_t buf[512];
    size_t len = 0;
    uint32_t start = millis();
    uint32_t end = start;
    if(file){
        len = file.size();
        size_t flen = len;
        start = millis();
        while(len){
            size_t toRead = len;
            if(toRead > 512){
                toRead = 512;
            }
            file.read(buf, toRead);
            len -= toRead;
        }
        end = millis() - start;
        Serial.printf("%u bytes read for %u ms\n", flen, end);
        file.close();
    } else {
        Serial.println("Failed to open file for reading");
    }


    file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }

    size_t i;
    start = millis();
    for(i=0; i<2048; i++){
        file.write(buf, 512);
    }
    end = millis() - start;
    Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);
    file.close();
}

void setup(){
    Serial.begin(115200);
    if(!SD.begin(33)){
        Serial.println("Card Mount Failed");
        return;
    }
    uint8_t cardType = SD.cardType();

    if(cardType == CARD_NONE){
        Serial.println("No SD card attached");
        return;
    }

    Serial.print("SD Card Type: ");
    if(cardType == CARD_MMC){
        Serial.println("MMC");
    } else if(cardType == CARD_SD){
        Serial.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
    } else {
        Serial.println("UNKNOWN");
    }

    uint64_t cardSize = SD.cardSize() / (1024 * 1024);
    Serial.printf("SD Card Size: %lluMB\n", cardSize);

    listDir(SD, "/", 0);
    createDir(SD, "/mydir");
    listDir(SD, "/", 0);
    removeDir(SD, "/mydir");
    listDir(SD, "/", 2);
    writeFile(SD, "/hello.txt", "Hello ");
    appendFile(SD, "/hello.txt", "World!\n");
    appendFile(SD, "/hello.txt", "More Text!\n");
    appendFile(SD, "/hello.txt", "And more text!\n");
    readFile(SD, "/hello.txt");
    deleteFile(SD, "/foo.txt");
    renameFile(SD, "/hello.txt", "/foo.txt");
    readFile(SD, "/foo.txt");
    testFileIO(SD, "/test.txt");
    Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
    Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));
}

void loop(){

}


Should I be using this calling convention instead? It does seem to work so far. I will do more testing.

qarchitect
 
Posts: 11
Joined: Thu Jan 28, 2016 10:44 pm

Re: Adalogger writes not working

by adafruit2 on Fri Feb 08, 2019 2:26 pm

hiya yeah thats just a filename thing ESP32 wants - try this new script here
https://learn.adafruit.com/admin/guides ... ditor/8117
we added the leading '/' and changed the numbers to match

adafruit2
Site Admin
 
Posts: 18242
Joined: Fri Mar 11, 2005 7:36 pm

Re: Adalogger writes not working

by qarchitect on Fri Feb 08, 2019 3:09 pm

I cannot get to the link provided. I get this message.

"You are unauthorized to view this content"

qarchitect
 
Posts: 11
Joined: Thu Jan 28, 2016 10:44 pm

Re: Adalogger writes not working

by adafruit2 on Fri Feb 08, 2019 3:13 pm


adafruit2
Site Admin
 
Posts: 18242
Joined: Fri Mar 11, 2005 7:36 pm

Re: Adalogger writes not working

by qarchitect on Fri Feb 08, 2019 3:59 pm

Ah, I see. However, this does not completely solve the problem. This allows it to create files and see files on the file system but it still does not work for writing content to the files. It does compile for sure, but when running, it still does not write data to the files.

In order to get data written to the files, I have to use the calling conventions from the ESP32 example called SD_Test that can be found here in the Arduino IDE. "File/Examples/SD(esp32)/SD_Test". You can read more on my comments above about this.

Thanks

qarchitect
 
Posts: 11
Joined: Thu Jan 28, 2016 10:44 pm

Re: Adalogger writes not working

by adafruit2 on Fri Feb 08, 2019 4:08 pm

hmm odd - ok do you know what particular line is different? sorry don't have an ESP32 right now to check against

you could also open/close the file for 'appending' before after each write. that would force it to flush the data!

adafruit2
Site Admin
 
Posts: 18242
Joined: Fri Mar 11, 2005 7:36 pm

Re: Adalogger writes not working

by qarchitect on Fri Feb 08, 2019 4:52 pm

I did try both flush after each write and in another iteration I tried reopening/write or append/close repeatedly in the loop() function. Still I got no content in the file when reading it from my PC.

I have not yet figured out what key change or changes from the ESP32-SD_Test allow it work there while it does not work in the SD library Datalogger example or the tutorial example. I will post back if I find anything.

qarchitect
 
Posts: 11
Joined: Thu Jan 28, 2016 10:44 pm

Re: Adalogger writes not working

by adafruit2 on Fri Feb 08, 2019 4:57 pm

very odd - i wonder what they changed :/ also check you have the very latest ESP32 board package

adafruit2
Site Admin
 
Posts: 18242
Joined: Fri Mar 11, 2005 7:36 pm

Re: Adalogger writes not working

by qarchitect on Fri Feb 08, 2019 5:40 pm

Okay, I found a particular calling procedure that works.

Oh, but as to your question on version. I have these versions;
Arduino version: 1.8.8
ESP32 Espressif library version: 1.0.1

And, not that it is using it, I have;
SD Library version: 1.2.3

So, here is the code modifications to the tutorial that actually works.

Code: Select all | TOGGLE FULL SIZE
#include <SPI.h>
#include <SD.h>

// Set the pins used
#define cardSelect 33

// blink out an error code
void error(uint8_t errno) {
  while(1) {
    uint8_t i;
    for (i=0; i<errno; i++) {
      digitalWrite(13, HIGH);
      delay(100);
      digitalWrite(13, LOW);
      delay(100);
    }
    for (i=errno; i<10; i++) {
      delay(200);
    }
  }
}

// This line is not needed if you have Adafruit SAMD board package 1.6.2+
//   #define Serial SerialUSB

char filename[15];

void setup() {
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
  // also spit it out
  Serial.begin(115200);
  Serial.println("\r\nAnalog logger test");
  pinMode(13, OUTPUT);


  // see if the card is present and can be initialized:
  if (!SD.begin(cardSelect)) {
    Serial.println("Card init. failed!");
    error(2);
  }
  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;
    }
  }

  File logfile = SD.open(filename, FILE_WRITE);
  if( ! logfile ) {
    Serial.print("Couldnt create ");
    Serial.println(filename);
    error(3);
  }
  logfile.close();
  Serial.print("Writing to ");
  Serial.println(filename);

  pinMode(13, OUTPUT);
  pinMode(8, OUTPUT);
  Serial.println("Ready!");
}

void loop() {
  digitalWrite(8, HIGH);

  File logfile;
  logfile = SD.open(filename, FILE_APPEND);
  logfile.print("A0 = "); logfile.println(analogRead(0));
  Serial.print("A0 = "); Serial.println(analogRead(0));
  logfile.close();
  digitalWrite(8, LOW);
 
  delay(100);
}


In the documentation for SD Library open function
https://www.arduino.cc/en/Reference/SDopen
It lists only FILE_WRITE and FILE_READ and explicitly states that FILE_WRITE will open for appending.
It seems however that the Espressif version adds FILE_APPEND. However, in my tests, it is not enough to just open with FILE_APPEND at the beginning and in the loop write, nor does adding a flush after the write work in append mode. The only path I have had success with is first opening with FILE_WRITE, closing and then in every loop iteration, open with FILE_APPEND and close it. See above.

qarchitect
 
Posts: 11
Joined: Thu Jan 28, 2016 10:44 pm

Re: Adalogger writes not working

by adafruit2 on Fri Feb 08, 2019 5:52 pm

aweosme, thanks - we'll update the guide!

adafruit2
Site Admin
 
Posts: 18242
Joined: Fri Mar 11, 2005 7:36 pm

Please be positive and constructive with your questions and comments.