Creat a file named with a char array

Greeting everyone!
First of all I'm french so sorry if I do some mistakes :smiley:
There is many days I'm on a problem who seems to be basic but make my crazy ^^'
I got a barcode scanner(who act as a usb keyboard) connected to an USB sheild managed with th USB Host Sheild 2.0. It send data to an Arduino nano with a SD card plugged on.
My program act like that:
-The barcode scanner read a 6 character lenth barcode(only numbers ex: "123456")and send it ton the arduino one by one
-The arduino make a char array with the numbers and print it on the serial
-Then the arduino should creat a file named with this char array but it's actally not work...
There is my code :
(I know the code is strange but this is how the library work)
the active code part is void KbdRptParser::OnKeyPressed(uint8_t key) line 35

#include <hidboot.h> 
#include <hiduniversal.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <Usb.h>


#include <SPI.h>
#include <SD.h>
File membre;

uint8_t curseur = 0;
char code[]="000000.txt";
 
USB     Usb;
USBHub     Hub(&Usb); 
HIDUniversal      Hid(&Usb); 

 
class KbdRptParser : public KeyboardReportParser
{
        void PrintKey(uint8_t mod, uint8_t key);             // Add this line to print character in ASCII
protected:
  virtual void OnKeyDown  (uint8_t mod, uint8_t key);
  virtual void OnKeyPressed(uint8_t key);
};
 
void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)  
{
    uint8_t c = OemToAscii(mod, key);
 
    if (c)
        OnKeyPressed(c);
}
 
/* when a character is coming: */
void KbdRptParser::OnKeyPressed(uint8_t key)  
{
 
  if(curseur <= 5){
    code[curseur]=(char)key;//here,(char)key is the recieved character 
    curseur++;
  }
  else if(curseur == 6){
    curseur=0;
    Serial.println(code);
    membre = SD.open(code, FILE_WRITE);
    membre.close();
    if(SD.exists(code)) {
      Serial.println(F("file created"));
    } 
    else {
      Serial.println(F("file can't be creat"));
    }
    
  }
  
};
 
KbdRptParser Prs;
 
void setup()
{
    Serial.begin( 115200 );
    pinMode(9, OUTPUT); 
    Serial.println(F("Start"));
    SD.begin(9);
    if (Usb.Init() == -1) {
        Serial.println(F("OSC did not start."));
    }
 
    delay( 200 );
 
    Hid.SetReportParser(0, (HIDReportParser*)&Prs);
    delay( 200 );
}
 
void loop()
{
  Usb.Task();
  
}

The think wich make me crazy is the fact that when I display the char array on the serial, everithing is OK, it's print like a normal ASCII string but it's not able to crate a file named with...
example of the serial output after some scans :

Start
OK
000000.txt
file can't be creat
123456.txt
file can't be creat
011896.txt
file can't be creat
011679.txt
file can't be creat

so I tried with the exemple "Files" of the library SD

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

File membre;
char code[]="000000.txt";
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(9)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  if (SD.exists(code)) {
    Serial.println("000000.txt exists.");
  } else {
    Serial.println("000000.txt doesn't exist.");
  }

  // open a new file and immediately close it:
  Serial.println("Creating 000000.txt...");
  membre = SD.open(code, FILE_WRITE);
  membre.close();

  // Check to see if the file exists:
  if (SD.exists(code)) {
    Serial.println("000000.txt exists.");
  } else {
    Serial.println("000000.txt doesn't exist.");
  }
}

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

and everything worked perfectly, it was able to create a file with the char:

Initializing SD card...initialization done.
000000.txt doesn't exist.
Creating 000000.txt...
000000.txt exists.

Once I plugged the SD card in my PC I can clearly read the file, I'm lost, I don't know why it's not working, maybe the returned character of the sheild are different ASCII ?? I don't think so but at this point everything is possible^^'
Even if I put a pre-created file with the "Files" program with the same name of the code I want to scan ex: "123456.txt" will not be recognize by my program...
I aslo tried by closing the char array with

code[11]= '\0';

but nothing

I hope I was understandable and hope you could help me !
Thanks :wink:

My only guess is since OnKeyPressed() is a "callback", probably the USB host library didn't de-asserted (pulled to "high" state) the corresponding CS pin beforehand.

Because both SD card and USB host share the same SPI bus, asserting (pulling to "low" state the CS pins) both devices cause a data clash in the MISO line (both devices try to "speak" to the Arduino at the same time), effectively corrupting whatever data was supposed to receive (and thus causing errors to actually every SD card operation, so even the exists() function would have failed anyways).
So that's why I think it isn't working along the USB host.

So you have two ways to solve this:

  • Move the file creation part outside of the OnKeyPressed() callback.
  • Bring the USB host's CS pin to high before the file creation part, then bring it low again afterwards. Like this:
void KbdRptParser::OnKeyPressed(uint8_t key) 
{
 
  if(curseur <= 5){
    code[curseur]=(char)key;//here,(char)key is the recieved character
    curseur++;
  }
  else if(curseur == 6){
    curseur=0;
    Serial.println(code);

    digitalWrite(csUSB, HIGH); // Add this here
    membre = SD.open(code, FILE_WRITE);
    membre.close();
    if(SD.exists(code)) {
      Serial.println(F("file created"));
    }
    else {
      Serial.println(F("file can't be creat"));
    }
    digitalWrite(csUSB, LOW); // Add this here
   
  }
 
};

I don't know the pin number connected to the CS (aka SS) of the USB host chip, so I called it csUSB in my proposal.

Hello !
I think it's the source of the problem so I tried both of your solutions :
Here I tried to manually silence the USB sheild :
(my csUSB is 10 and my csSD is 9)

#include <hidboot.h>                           
#include <hiduniversal.h>                
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <Usb.h>


#include <SPI.h>
#include <SD.h>
File membre;

uint8_t curseur = 0;
char code[]="000000.txt";
 
USB     Usb;
USBHub     Hub(&Usb);                                          
HIDUniversal      Hid(&Usb);                                  

 
class KbdRptParser : public KeyboardReportParser
{
        void PrintKey(uint8_t mod, uint8_t key);             
protected:
  virtual void OnKeyDown  (uint8_t mod, uint8_t key);
  virtual void OnKeyPressed(uint8_t key);
};
void KbdRptParser::PrintKey(uint8_t m, uint8_t key)
{
  MODIFIERKEYS mod;
  *((uint8_t*)&mod) = m;
  PrintHex<uint8_t>(key, 0x80);
};
void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)  
{
    uint8_t c = OemToAscii(mod, key);
    if (c)
        OnKeyPressed(c);
}
 
/* what to do when symbol arrives */
void KbdRptParser::OnKeyPressed(uint8_t key)  
{
  if(curseur <= 5){
    code[curseur]=(char)key;
    curseur++;
  }
  else if(curseur == 6){
    curseur=0;
    Serial.println(code);
    digitalWrite(10, HIGH); // Add this here
    membre = SD.open(code, FILE_WRITE);
    membre.close();
    if(SD.exists(code)) {
      Serial.println(F("file created"));
    } 
    else {
      Serial.println(F("file can't be created"));
    }
    digitalWrite(10, LOW); // Add this here
  }
  
}
 
KbdRptParser Prs;
 
void setup()
{
    Serial.begin( 115200 );
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    Serial.println(F("Start"));
    SD.begin(9);
    Serial.println(F("OK"));
  
    if (Usb.Init() == -1) {
        Serial.println(F("OSC did not start."));
    }
 
    delay( 200 );
 
    Hid.SetReportParser(0, (HIDReportParser*)&Prs);       
    delay( 200 );
}
 
void loop()
{
  Usb.Task();
  
}

But that didn't worked, I also tried to add a manual silence to the SD more but nothing...
So i tried to run my SD code out of the usb function :

#include <hidboot.h>                          
#include <hiduniversal.h>                  
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <Usb.h>


#include <SPI.h>
#include <SD.h>
File membre;

uint8_t curseur = 0;
char code[]="000000.txt";
bool codeOK = false;
USB     Usb;
USBHub     Hub(&Usb);                                          
HIDUniversal      Hid(&Usb);                                  

 
class KbdRptParser : public KeyboardReportParser
{
        void PrintKey(uint8_t mod, uint8_t key);             
protected:
  virtual void OnKeyDown  (uint8_t mod, uint8_t key);
  virtual void OnKeyPressed(uint8_t key);
};
void KbdRptParser::PrintKey(uint8_t m, uint8_t key)
{
  MODIFIERKEYS mod;
  *((uint8_t*)&mod) = m;
  PrintHex<uint8_t>(key, 0x80);
};
void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)  
{
    uint8_t c = OemToAscii(mod, key);
    if (c)
        OnKeyPressed(c);
}
 
/* what to do when symbol arrives */
void KbdRptParser::OnKeyPressed(uint8_t key)  
{
  if(curseur <= 5){
    code[curseur]=(char)key;
    curseur++;
  }
  else if( curseur == 6){
    codeOK = true;
    curseur = 0;
    }

}
 
KbdRptParser Prs;
 
void setup()
{
    Serial.begin( 115200 );
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT); 
    Serial.println(F("Start"));
    SD.begin(9);
    Serial.println(F("OK"));
  
    if (Usb.Init() == -1) {
        Serial.println(F("OSC did not start."));
    }
 
    delay( 200 );
 
    Hid.SetReportParser(0, (HIDReportParser*)&Prs);        //Here I change  "Keyboard" for "Hid"
    delay( 200 );
}
 
void loop()
{
  Usb.Task();
   if(codeOK == true){
    Serial.println(code);
    membre = SD.open(code, FILE_WRITE);
    membre.close();
    if(SD.exists(code)) {
      Serial.println(F("file created"));
    } 
    else {
      Serial.println(F("file can't be creat"));
    }
    codeOK = false;
  }
  
}

But still nothing even if I add the manual silence ...
I think we are close to the succes !
I hope you will find something, I'm looking for my side
Thanks !

I finally found !
The probleme is that the USB library use the pins 7,8,9,10,11,12 and 13 so i changed my csSD by 2 and everuthing worked!!

So I was kinda close, nice! :slight_smile: