A place users can post their projects. If you have a small project and would like your own dedicated place to post and have others chat about it then this is your spot.

User avatar
By GalactusX31
#93395 Since I haven't found any way around the problem of using special characters in file and directory names (and haven't found any help either), I'm going to have to use another type of nomenclature when naming files/directories. , using "English" as the base language, and varying the rest a bit.
User avatar
By GalactusX31
#93414 Thanks for the reply, I think due to this issue I'm going to have to rethink the way the name generation for directories/files are created.

Instead of naming the directories / files with their "word", I will do it using their language CODE, example:
CODE: es; word: ingles
CODE: en; word: english
CODE: fr; word: anglais

Inside the file "languages.txt", I have added its code at the beginning of each language / word, in this way it does not complicate anything for me to "use" the first 2 characters to generate the names, and the rest of the captured text, used to generate the audio.

Code: Select alles-esespañol,eninglés,frfrancés,
en-esspanish,enenglish,frfrench,
fr-esespagnol,enanglais,frfrançais,

Therefore, the first part of the line "en-" would indicate the language code to use, and in the following sections of the line, separated by "commas", the first 2 characters of each sub string, would be used to name directories and files, in this way, the use of special characters is avoided, unless they are used to be displayed by other means, such as screens that support them.
User avatar
By GalactusX31
#93418 A little preview of my code and results before I go to sleep, also I have added a small function to know the "size" of the files in human readable, both for the file hosted in the http address and in the SD card, I hope it help to those who need it.

Code: Select all#include <SD.h>
#include <SPI.h>
#include <WiFi.h>
#include "Arduino.h"
#include <google-tts.h>
#include <HTTPClient.h>

HTTPClient http;
TTS tts;

const char* ssid = "MIWIFI_2G_dGTF";
const char* password =  "MtFDtEDp";

//--------------------[ String formatSizeUnits ]--------------------------
//    Function to represent only the size of the files in human readable
//                format, can be issued in its entirety

String formatSizeUnits(unsigned long bytes){
  String SizeUnit;
  if      (bytes >= 1073741824) { SizeUnit = String((bytes / 1073741824)) + " GB " + "[" + bytes + "]"; }
  else if (bytes >= 1048576)    { SizeUnit = String((bytes / 1048576)) + " MB " + "[" + bytes + "]"; }
  else if (bytes >= 1024)       { SizeUnit = String((bytes / 1024)) + " KB " + "[" + bytes + "]"; }
  else if (bytes > 1)           { SizeUnit = String(bytes) + " bytes " + "[" + bytes + "]"; }
  else if (bytes == 1)          { SizeUnit = String(bytes) + " byte " + "[" + bytes + "]"; }
  else                          { SizeUnit = "0 bytes"; }
  return SizeUnit;
}
//-----------------------------------------------------------------------

//-----------------------------------------------------------------------
//  This portion of code is only for testing
//  using the messages through the serial port.
#define debugprogram 1 // 1: Send messages to serial port
                       // 0: Disable serial messaging

#if debugprogram == 1
#define PRINT(x)    Serial.print(x)
#define PRINTLN(x)  Serial.println(x)
#else
#define PRINT(x)
#define PRINTLN(x)
#endif
//-----------------------------------------------------------------------

File root;  //  Needed to use the SD library

int tasks     = 0;  //  Multipurpose variable to control the "ReadFile"
                    //  function and other aspects of module programming
int FileLines = 0;  //  variable that stores the number of lines in a file

String chosenlanguage;  //  Variable that stores the selected language

//----------------------[ void MakeDirectory ]----------------------------
//                  Function to create directories

void MakeDirectory(String Directory) {
 
  String dir = "/" + Directory;

  if (SD.exists( dir )) {
    PRINTLN( "Directory: \" " + dir + " \" exist\n" );
  } else {
    PRINTLN( "Directory: \" " + dir + " \" don´t exist, making it!" );
    SD.mkdir( dir );
    PRINTLN( dir );
  }
}
//------------------------------------------------------------------------

void AudioDownload(String URL, String FileDirectory, String FileName){
  String Mp3FileName = FileName + String( ".mp3" );
  http.begin(URL);  //  We make the call to the address
  int httpCode = http.GET();  //  We capture the code returned by the URL address
  if(httpCode == 200) { //  Code 200 means that everything has gone well
         
    String payload = http.getString();  //  We take the data from the embedded data/audio file from the URL
                                        //  and temporarily save it in a string variable
    PRINT( "Size of embebed HTTP file: " );
    PRINTLN(formatSizeUnits(payload.length()));
   
    File f = SD.open( FileDirectory + '/' + Mp3FileName, FILE_WRITE );
         
    if   ( !f ) { PRINTLN("Could not create file");  while (1); }
    else      { f.print(payload);  PRINTLN("File was created"); } // We write the data in the audio file and close it.
   
    f.close();  //  Force the file to close after an successfully or fail writing.
   
  } else {  //  If the call to the URL address failed, we print the error code
    Serial.printf( "[HTTP] GET... failed, error: %s\n", http.errorToString( httpCode ).c_str() );
    PRINTLN( "" );
  }

  http.end(); //  Close/end the http connection
}

//-------------------------[ void ReadFile ]------------------------------
//  General purpose function, which encompasses everything related
//  to creating, reading and writing files and folders
//------------------------------------------------------------------------

void ReadFile( String FileName, int ReadFileOpcion ) {
    // FileName: Function target file name
    // ReadFileOption: option to use only one function and simplify programming

  root = SD.open( "/" + FileName + ".txt", FILE_READ );
 
  int LineNumRead = 1;
  bool found = false; //
 
  if ( root.available() > 0 ) {
    PRINTLN ( "File: \" " + FileName + " \" exist, accessing ...\n" );
    while ( root.available() > 0 ) {
      switch ( ReadFileOpcion ) {
        case 1: { // This function only serves to "count" the lines in the desired file
       
          String FL = root.readStringUntil( '\n' ); //  Read the selected file "line-by-line" using line feed as limit
          LineNumRead += 1; //  Every time it reaches the end of a line, we increase the value of "lines read" counter.
          }
          FileLines = LineNumRead - 1;

        break;
        case 2: {
          String FL = root.readStringUntil( '\n' ); //  Read the selected file "line-by-line" using line feed as limit

          int init = FL.indexOf( '-' );
          String lang1 = FL.substring( 0, init ); //  Get the content of the entire line
          PRINTLN( "Actual line: " + String( LineNumRead ) ); //  Pointer to the actual read line IN the file

          if ( lang1 == chosenlanguage ) {
            found = true; //  If the selected CODE is found, we proceed
            PRINTLN( "- CODE: " + chosenlanguage + ", exist in line: " + LineNumRead + ", inside of file: " + FileName );
            PRINTLN( "- The languages translated for this code are as follows:" );
            MakeDirectory( FileName + '/' + lang1 );  //  We create the directory that will contain the audios of the
                                                    //  selected language
            while ( found == true ) {
              int last = FL.indexOf( ',', init + 1 );  //  Capture the occurrence of the comma, to use it as a pointer
                                                      //  into the String containing the line of text
              if ( last < 0){ break; }  //  Force to etect if there are no more separators, and we exit the process
              String lang2 = FL.substring( init+1, last ); // Detect the following subString within the current reading
                                                           // line and pass it to the serial port (or for any other use,
                                                           // for example: enter these text strings in a menu).
              String lang3 = lang2.substring( 0,2 ); 
              String lang4 = lang2.substring( 2 ); 
              String GTL = tts.getSpeechUrl( lang4, lang1 ); //  We generate the link for the http request of google translator
             
              MakeDirectory( FileName + '/' + lang1 + '/' + lang3 );  //  Directory that will contain the translated languages
              AudioDownload( GTL, '/' + FileName + '/' + lang1, lang3 );  //  Download / create the *.mp3 file
             
              PRINTLN(GTL); // 
              PRINTLN( '/' + FileName + '/' + lang1 + '/' + lang3 );
              PRINTLN( " * " + lang4 );
              PRINTLN( " " );
             
              init = last;  //  We assign the next "initial" position, the "end" of the previous one,
                            //  in this way we can reuse the code without adding anything new
            }
          }
        }
        LineNumRead += 1;
      }
      if ( found == true ) {  //  If the language CODE is found, please stop reading / searching, so we make this process
                              //  faster and we don't waste time reading the rest of the file
        PRINTLN( "CODE language found!" );
        break;
      }
    }
 
    if ( found != true && ReadFileOpcion == 2 ){ //  If we read the "languages" file and we do not find the CODE, we launch an alert
      PRINTLN( "- The selected CODE language: " + chosenlanguage + " is not present in file: " + FileName );
    }
 
  } else {  //  If the "languages" file is not found, we launch an ALERT, this can be used later to "download" this file from the internet cloud
    PRINTLN( "The file cannot be read or does not exist\n" );
  }
 
  LineNumRead = 1;
  root.close(); //  Force to close any open file, in this case "root"
}

void setup(){
  Serial.begin(112500); // Initialize the serial port
 
  WiFi.mode( WIFI_STA ); 
  WiFi.begin( ssid, password );

  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    Serial.print( "." );
  }
 
  SD.begin(5);  // Initialize the SD module

  chosenlanguage = "en"; // We select the default language
 
  tasks = 1;
 
  if(WiFi.status() == WL_CONNECTED) {
    PRINTLN( "Connected to WIFI network, starting ONLINE MODE..." );
  } else {
    PRINTLN( "WIFI connection failed, starting OFFLINE MODE ..." );
  }
}
//  We use the variable "tasks", to tell the program where to start
void loop(){
  switch (tasks) { 
    case 1:
      MakeDirectory( "languages" ); //  First we create the "root" folder that will contain all the audios necessary for the application
      ReadFile( "languages", 1 );  //  Count the lines present in the file "languages.txt"
      ReadFile( "languages", 2 );  //  Find the language CODE in the file, and load the translated languages for it
      tasks += 1;
    break;
  }
}

The result is this, creation of the directories and download of the audios for their respective languages.

Image

I repeat, if someone knows how to do something much better than me, has any advice or correction, please let me know, it would help me a lot.