arduino-libraries / Arduino_USBHostMbed5

Apache License 2.0
4 stars 11 forks source link

Error writing to file/closing file #20

Closed jessestevens5b closed 11 months ago

jessestevens5b commented 1 year ago

I followed the example provided to write files using a Portenta Machine Control board but I'm having no luck actually writing to files.

As you can see in my code below I've mashed together the directory read example and the file writing example so I could test whether it was a general problem with my USB connection/drive but I can read the files in the directory properly, but cannot seem to write.

You'll see also below in the console print out there is no issue with the writing inside the for loop to write the numbers, only when it's time to close.

When I check the USB in my computer there is no data written to that file (it's a file I've created previously. If I delete it no new file is created).

My code:

/*
  Portenta - FileWrite

  The sketch shows how to mount an usb storage device and how to
  write a file, eventually overwriting the original content.

  The circuit:
   - Portenta H7

  This example code is in the public domain.
*/
#include <Arduino_MachineControl.h>
#include <Arduino_USBHostMbed5.h>  //https://github.com/arduino-libraries/Arduino_USBHostMbed5
#include <DigitalOut.h>
//#include <FATFileSystem.h>

using namespace machinecontrol;

// Redirect log output from MbedOS and low-level libraries to Serial
REDIRECT_STDOUT_TO(Serial);

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

//to enable thte usb otg power:
mbed::DigitalOut otg(PB_14, 0);

int err = 0;

void setup() {
  //usb_controller.powerEnable();

  Serial.begin(115200);
  //while (!Serial);

  delay(2000);

  Serial.print("Trying MSD connect");

  while (!msd.connect()) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("success");

  Serial.println("Mounting USB device...");
  err = usb.mount(&msd);
  if (err) {
    Serial.print("Error mounting USB device ");
    Serial.println(err);
    while (1)
      ;
  }
  Serial.print("read done ");

  dirRead();
  fileWrite();
}

void loop() {

   delay(1000);
    // handle disconnection and reconnection
    if (!msd.connected()) {
        msd.connect();
    }

}

void fileWrite() {
  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+"); //w+ = create a new file for update. See: https://os.mbed.com/users/berntzen/notebook/writing-files/
  printf("%s\n", (!f ? "Fail :(" : "OK"));

  for (int i = 1; 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);
    }
    //do we need to go a bit more slowly?
    delay(100);
  }

  delay(1000);

  Serial.println("closing file..");

  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 dirRead() {
  char buf[256];

  // Display the root directory
  Serial.print("Opening the root directory... ");
  DIR* d = opendir("/usb/");
  Serial.println(!d ? "Fail :(" : "Done");
  if (!d) {
    snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
    Serial.print(buf);
  }
  Serial.println("done.");

  Serial.println("Root directory:");
  unsigned int count{ 0 };
  while (true) {
    struct dirent* e = readdir(d);
    if (!e) {
      break;
    }
    count++;
    snprintf(buf, sizeof(buf), "    %s\r\n", e->d_name);
    Serial.print(buf);
  }
  Serial.print(count);
  Serial.println(" files found!");

  snprintf(buf, sizeof(buf), "Closing the root directory... ");
  Serial.print(buf);
  fflush(stdout);
  err = closedir(d);
  snprintf(buf, sizeof(buf), "%s\r\n", (err < 0 ? "Fail :(" : "OK"));
  Serial.print(buf);
  if (err < 0) {
    snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
    Serial.print(buf); delay(1000);
    // handle disconnection and reconnection
    if (!msd.connected()) {
        msd.connect();
    }
  }
}

And the console print out:

Trying MSD connect.success
Mounting USB device...
read done Opening the root directory... Done
done.
Root directory:
    numbers.txt
1 files found!
Closing the root directory... OK
Open /usb/numbers.txt
OK
Writing numbers (1/10)
Writing numbers (2/10)
Writing numbers (3/10)
Writing numbers (4/10)
Writing numbers (5/10)
Writing numbers (6/10)
Writing numbers (7/10)
Writing numbers (8/10)
Writing numbers (9/10)
Writing numbers (10/10)
closing file..
fclose error:I/O error (-5)
jessestevens5b commented 1 year ago

My apologies for the mess above, seems my copy/paste was doing some wild stuff whilst trying to get the code and output into the above post (hopefully all fixed now)

jessestevens5b commented 1 year ago

I should also say here that I've tested with both FAT32 and FAT16 of various sizes and physical USB drives with the same behaviour

azolli commented 1 year ago

Same error with Arduino Giga R1 and a 4GB FAT32 (MBR) usb

Sarah26-10 commented 1 year ago

I have the same error with the Portenta Machine control and FAT32.

Has anyone found a solution yet? Please :)

alrvid commented 1 year ago

We're aware of this problem and I'm working on it right now. So far I've only been able to replicate it with one particular USB thumb drive. I've also tried the sketch above with a SanDisk Ultra USB 3.0 32 GB and a Kingston DataTraveler Exodia 32 GB multiple times, but without any error occurring. It would be helpful to hear from you which USB thumb drive models have worked and which ones have not. Until there's a fix, you might have success with using a different brand of USB thumb drive as a temporary workaround.

jessestevens5b commented 1 year ago

@alrvid yes mine were mostly Kingston, but I went on to try with several (at least 5) others of random/no name type with exactly the same problem.

Ideally it would be great to be able to see what the actual error is/means or a deeper level of debug to know what the problem is?

alrvid commented 1 year ago

Thank you for your feedback! I've created a pull request (https://github.com/arduino-libraries/Arduino_USBHostMbed5/pull/23) with several fixes, including one for the I/O errors. When that's merged, I hope your code will start working. I think the merge will happen in a few days if no problems are found during the review. Please let me know if the problems persist after the fix or if they're gone.

sebromero commented 1 year ago

@jessestevens5b @azolli @Sarah26-10 Hi! We've merged a few fixes since you commented here. Could you kindly try if the latest version from the main branch solves your issue?

Sarah26-10 commented 11 months ago

@sebromero Hi and sorry for the long delay. I have tried it now and it works without any problems. Thanks for the update!

sebromero commented 11 months ago

Closing this as this seems to be solved with the latest fixes.