I have a variable produced by the strftime function which is a char.
strftime(nextFileName, 13, “/%V_%Y.txt”, &timeinfo);
I want to copy it into another variable and thought that it should also be a char, but that produces an error “expression must be a modifiable lvalue”. I eventually found I could use the string class (with a small ‘s’):
string currentFileName = nextFileName;
To print this out I had to use a c_string:
Serial.println(currentFileName.c_str());
All this works within a function, but when I return to setup, the variable currentFileName appears empty & nothing prints out. I have declared it as a global variable, so I don’t understand.
Can anyone help, please??
I am desperate to find a good consistent authorative source of information on the particular version of C++ used with the ESP32/ESP8266 to learn this language from the ground up, but all I references and tutorials I can find deal with C++ 2011, not the version used by ESPs etc.
Any suggestions?
Hi Tony.
You must declare the variabe as String outside the setup() and outside the loop(), like this:
string currentFileName;
Then, whithin the function, use:
currentFileName = nextFileName;
Then, in the loop(), you can print the variable.
Serial.println(currentFileName.c_str());
Regards,
Sara
Hi Sara & thanks for your quick response.
My code does declare the variable as you suggested and while currentFileName prints out correctly within the function, it prints out nothing when it gets back into setup.
If it helps, I’ve included the whole sketch is here (this is just a testbed to get the code working before I write it back into the Web Server sketch):
#include <Arduino.h>
#include “FS.h”
#include “SD.h”
#include “SPI.h”
#include “time.h”
#include “WiFi.h”
#include “WiFiUdp.h”
#include <string>
using namespace std;
const char* ntpServer = “uk.pool.ntp.org”;
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 3600;
unsigned long currentTime;
char nextFileName [13];
string currentFileName;
const char* ssid = “xxxxxxxxx”;
const char* password = “xxxxxxxxx”;
// Initialize WiFi
void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print(“Connecting to WiFi ..”);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(‘.’);
delay(1000);
}
Serial.println(WiFi.localIP());
}
//Initialise SD card & print details
void initSDcard() {
if(!SD.begin()){
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);
}
// Function that gets current epoch time
unsigned long getTime() {
time_t now;
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println(“Failed to obtain time”);
return(0);
}
time(&now);
currentTime = (time(&now) + gmtOffset_sec + daylightOffset_sec);
strftime(nextFileName, 13, “/%V_%Y.txt”, &timeinfo);
Serial.print(“Line 59: nextFileName = “);
Serial.println(nextFileName);
string currentFileName = nextFileName;
Serial.print(“Line 62: currentFileName = “);
Serial.println(currentFileName.c_str());
return currentTime;
}
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 setup(){
Serial.begin(115200);
initWiFi();
initSDcard();
configTime (gmtOffset_sec,daylightOffset_sec,ntpServer);
Serial.print(“Line 168: Current time = “);
Serial.println(getTime());
Serial.print(“Line 170: nextFileName = “);
Serial.println(nextFileName);
Serial.print(“Line 173: currentFileName = “);
Serial.println(currentFileName.c_str());
writeFile(SD, “/hello.txt”, “Hello “);
appendFile(SD, “/hello.txt”, “World!\n”);
readFile(SD, “/hello.txt”);
Serial.print (“Line 179: currentFileName = “);
Serial.println(currentFileName.c_str());
deleteFile(SD, nextFileName);
renameFile(SD, “/hello.txt”, currentFileName.c_str());
readFile(SD, currentFileName.c_str());
}
void loop(){
}
Hope you can help,
Regards, Tony
Found the answer 🙂
If all else fails, read the instructions!!! I left the word ‘string’ in front of currentFileName = nextFileName; in the getTime() function.
All now working correctly.