Before logging an issue, please update to the latest release of Visual Micro from the Downloads Page.

When Logging a Support Issue in the Forum, please ensure you have also:-

  • Enabled vMicro > Compiler > Show Build Properties
  • Re-Compile your program with these settings enabled
 
Save the new Output to a Text File and....
  • Click the Reply button and attach as .txt file OR
  • Click here to Email us with the file attached, and a link to your post
Support requests without the output above may be impossible to answer, so please help us to help you
 
Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Problem with structures (Read 3050 times)
Marius
Developer
****
Offline


Posts: 204
Location: Centurion RSA
Joined: Sep 7th, 2011
Problem with structures
Jul 10th, 2019 at 3:43pm
Print Post  
Hi 
I declared a structure as folllows:
Code (C++)
Select All
struct  ConfigObject {
  char hostname[64];
  int port;
};

const char *filename = "/config.txt";  // <- SD library uses 8.3 filenames
ConfigObject config;    



And get this error:
Code (C++)
Select All
JsonConfigFile.ino: 29:52: error: 'Config' does not name a type
 



It worked before in other sketches but now I have an error. Not sure if I must set some parameter.
  
Back to top
IP Logged
 
Tim@Visual Micro
Administrator
*****
Offline


Posts: 12070
Location: United Kingdom
Joined: Apr 10th, 2010
Re: Problem with structures
Reply #1 - Jul 10th, 2019 at 4:11pm
Print Post  
can you post a full ino
  
Back to top
WWW  
IP Logged
 
Marius
Developer
****
Offline


Posts: 204
Location: Centurion RSA
Joined: Sep 7th, 2011
Re: Problem with structures
Reply #2 - Jul 11th, 2019 at 6:45am
Print Post  
Code (C++)
Select All
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to store your project configuration in a file.
// It uses the SD library but can be easily modified for any other file-system.
//
// The file contains a JSON document with the following content:
// {
//   "hostname": "examples.com",
//   "port": 2731
// }
//
// https://arduinojson.org/v6/example/config/

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

// Our configuration structure.
//
// Never use a JsonDocument to store the configuration!
// A JsonDocument is *not* a permanent storage; it's only a temporary storage
// used during the serialization phase. See:
// https://arduinojson.org/v6/faq/why-must-i-create-a-separate-config-object/

struct  ConfigObject {
  char hostname[64];
  int port;
};

const char *filename = "/config.txt";  // <- SD library uses 8.3 filenames
ConfigObject config;                         // <- global configuration object

// Loads the configuration from a file
void loadConfiguration(const char *filename, Config &config) {
  // Open file for reading
  File file = SD.open(filename);

  // Allocate a temporary JsonDocument
  // Don't forget to change the capacity to match your requirements.
  // Use arduinojson.org/v6/assistant to compute the capacity.
  StaticJsonDocument<512> doc;

  // Deserialize the JSON document
  DeserializationError error = deserializeJson(doc, file);
  if (error)
    Serial.println(F("Failed to read file, using default configuration"));

  // Copy values from the JsonDocument to the Config
  config.port = doc["port"] | 2731;
  strlcpy(config.hostname,                  // <- destination
          doc["hostname"] | "example.com",  // <- source
          sizeof(config.hostname));         // <- destination's capacity

  // Close the file (Curiously, File's destructor doesn't close the file)
  file.close();
}

// Saves the configuration to a file
void saveConfiguration(const char *filename, const Config &config) {
  // Delete existing file, otherwise the configuration is appended to the file
  SD.remove(filename);

  // Open file for writing
  File file = SD.open(filename, FILE_WRITE);
  if (!file) {
    Serial.println(F("Failed to create file"));
    return;
  }

  // Allocate a temporary JsonDocument
  // Don't forget to change the capacity to match your requirements.
  // Use arduinojson.org/assistant to compute the capacity.
  StaticJsonDocument<256> doc;

  // Set the values in the document
  doc["hostname"] = config.hostname;
  doc["port"] = config.port;

  // Serialize JSON to file
  if (serializeJson(doc, file) == 0) {
    Serial.println(F("Failed to write to file"));
  }

  // Close the file
  file.close();
}

// Prints the content of a file to the Serial
void printFile(const char *filename) {
  // Open file for reading
  File file = SD.open(filename);
  if (!file) {
    Serial.println(F("Failed to read file"));
    return;
  }

  // Extract each characters by one by one
  while (file.available()) {
    Serial.print((char)file.read());
  }
  Serial.println();

  // Close the file
  file.close();
}

void setup() {
  // Initialize serial port
  Serial.begin(9600);
  while (!Serial) continue;

  // Initialize SD library
  while (!SD.begin(4)) {
    Serial.println(F("Failed to initialize SD library"));
    delay(1000);
  }

  // Should load default config if run for the first time
  Serial.println(F("Loading configuration..."));
  loadConfiguration(filename, config);

  // Create configuration file
  Serial.println(F("Saving configuration..."));
  saveConfiguration(filename, config);

  // Dump config file
  Serial.println(F("Print config file..."));
  printFile(filename);
}

void loop() {
  // not used in this example
}

// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization or deserialization problem.
//
// The book "Mastering ArduinoJson" contains a case study of a project that has
// a complex configuration with nested members.
// Contrary to this example, the project in the book uses the SPIFFS filesystem.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤
 

  
Back to top
IP Logged
 
Tim@Visual Micro
Administrator
*****
Offline


Posts: 12070
Location: United Kingdom
Joined: Apr 10th, 2010
Re: Problem with structures
Reply #3 - Jul 11th, 2019 at 1:25pm
Print Post  
It has always been the case that you need to place your own prototypes between the creation of a type and where they are first used. 

Arduino IDE has moved to using a new system to deduce the location of prototypes which works most of the time. We will shortly move to the same. 

The older system places them before first line of real code (non #include), which is why users types would always be placed in .h files. You can override by adding them yourself. Notice I have added prototypes for the save and load methods that make use of the types in their signatures.

Code (C++)
Select All
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to store your project configuration in a file.
// It uses the SD library but can be easily modified for any other file-system.
//
// The file contains a JSON document with the following content:
// {
//   "hostname": "examples.com",
//   "port": 2731
// }
//
// https://arduinojson.org/v6/example/config/

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

// Our configuration structure.
//
// Never use a JsonDocument to store the configuration!
// A JsonDocument is *not* a permanent storage; it's only a temporary storage
// used during the serialization phase. See:
// https://arduinojson.org/v6/faq/why-must-i-create-a-separate-config-object/

struct  ConfigObject {
  char hostname[64];
  int port;
};

////// prototypes in correct location for cpp
//
void saveConfiguration(const char *filename, const Config &config);
void loadConfiguration(const char *filename, Config &config);
//
///////////////////

const char *filename = "/config.txt";  // <- SD library uses 8.3 filenames
ConfigObject config;                         // <- global configuration object

// Loads the configuration from a file
void loadConfiguration(const char *filename, Config &config) {
  // Open file for reading
  File file = SD.open(filename);

  // Allocate a temporary JsonDocument
  // Don't forget to change the capacity to match your requirements.
  // Use arduinojson.org/v6/assistant to compute the capacity.
  StaticJsonDocument<512> doc;

  // Deserialize the JSON document
  DeserializationError error = deserializeJson(doc, file);
  if (error)
    Serial.println(F("Failed to read file, using default configuration"));

  // Copy values from the JsonDocument to the Config
  config.port = doc["port"] | 2731;
  strlcpy(config.hostname,                  // <- destination
          doc["hostname"] | "example.com",  // <- source
          sizeof(config.hostname));         // <- destination's capacity

  // Close the file (Curiously, File's destructor doesn't close the file)
  file.close();
}

// Saves the configuration to a file
void saveConfiguration(const char *filename, const Config &config) {
  // Delete existing file, otherwise the configuration is appended to the file
  SD.remove(filename);

  // Open file for writing
  File file = SD.open(filename, FILE_WRITE);
  if (!file) {
    Serial.println(F("Failed to create file"));
    return;
  }

  // Allocate a temporary JsonDocument
  // Don't forget to change the capacity to match your requirements.
  // Use arduinojson.org/assistant to compute the capacity.
  StaticJsonDocument<256> doc;

  // Set the values in the document
  doc["hostname"] = config.hostname;
  doc["port"] = config.port;

  // Serialize JSON to file
  if (serializeJson(doc, file) == 0) {
    Serial.println(F("Failed to write to file"));
  }

  // Close the file
  file.close();
}

// Prints the content of a file to the Serial
void printFile(const char *filename) {
  // Open file for reading
  File file = SD.open(filename);
  if (!file) {
    Serial.println(F("Failed to read file"));
    return;
  }

  // Extract each characters by one by one
  while (file.available()) {
    Serial.print((char)file.read());
  }
  Serial.println();

  // Close the file
  file.close();
}

void setup() {
  // Initialize serial port
  Serial.begin(9600);
  while (!Serial) continue;

  // Initialize SD library
  while (!SD.begin(4)) {
    Serial.println(F("Failed to initialize SD library"));
    delay(1000);
  }

  // Should load default config if run for the first time
  Serial.println(F("Loading configuration..."));
  loadConfiguration(filename, config);

  // Create configuration file
  Serial.println(F("Saving configuration..."));
  saveConfiguration(filename, config);

  // Dump config file
  Serial.println(F("Print config file..."));
  printFile(filename);
}

void loop() {
  // not used in this example
}

// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization or deserialization problem.
//
// The book "Mastering ArduinoJson" contains a case study of a project that has
// a complex configuration with nested members.
// Contrary to this example, the project in the book uses the SPIFFS filesystem.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤
 

« Last Edit: Jul 11th, 2019 at 1:27pm by Tim@Visual Micro »  
Back to top
WWW  
IP Logged
 
Marius
Developer
****
Offline


Posts: 204
Location: Centurion RSA
Joined: Sep 7th, 2011
Re: Problem with structures
Reply #4 - Jul 11th, 2019 at 1:49pm
Print Post  
That does not work either as you need the type declaration in the proto declaration.

Code (C++)
Select All
JsonConfigFile.ino: 34:52: error: 'Config' does not name a type
   void saveConfiguration(const char *filename, const Config &config)

JsonConfigFile.ino: 34:60: error: ISO C++ forbids declaration of 'config' with no type [-fpermissive]
   void saveConfiguration(const char *filename, const Config &config) 

  
Back to top
IP Logged
 
Tim@Visual Micro
Administrator
*****
Offline


Posts: 12070
Location: United Kingdom
Joined: Apr 10th, 2010
Re: Problem with structures
Reply #5 - Jul 11th, 2019 at 2:01pm
Print Post  
Sorry I should have added the prototypes after the type had been created + there are some bugs in your code. One example is that you changed the type name from Config to ConfigObject but you have not changed the type name within the rest of the code.

I have used the original json example to show the prototypes in the correct location alongside code that works.

Code (C++)
Select All
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
//
// This example shows how to store your project configuration in a file.
// It uses the SD library but can be easily modified for any other file-system.
//
// The file contains a JSON document with the following content:
// {
//   "hostname": "examples.com",
//   "port": 2731
// }

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

// Configuration that we'll store on disk
struct Config {
  char hostname[64];
  int port;
};

const char *filename = "/config.txt";  // <- SD library uses 8.3 filenames
Config config;                         // <- global configuration object

void loadConfiguration(const char* filename, Config& config);
void saveConfiguration(const char* filename, const Config& config);

// Loads the configuration from a file
void loadConfiguration(const char *filename, Config &config) {
  // Open file for reading
  File file = SD.open(filename);

  // Allocate the memory pool on the stack.
  // Don't forget to change the capacity to match your JSON document.
  // Use arduinojson.org/assistant to compute the capacity.
  StaticJsonBuffer<512> jsonBuffer;

  // Parse the root object
  JsonObject &root = jsonBuffer.parseObject(file);

  if (!root.success())
    Serial.println(F("Failed to read file, using default configuration"));

  // Copy values from the JsonObject to the Config
  config.port = root["port"] | 2731;
  strlcpy(config.hostname,                   // <- destination
          root["hostname"] | "example.com",  // <- source
          sizeof(config.hostname));          // <- destination's capacity

  // Close the file (File's destructor doesn't close the file)
  file.close();
}

// Saves the configuration to a file
void saveConfiguration(const char *filename, const Config &config) {
  // Delete existing file, otherwise the configuration is appended to the file
  SD.remove(filename);

  // Open file for writing
  File file = SD.open(filename, FILE_WRITE);
  if (!file) {
    Serial.println(F("Failed to create file"));
    return;
  }

  // Allocate the memory pool on the stack
  // Don't forget to change the capacity to match your JSON document.
  // Use https://arduinojson.org/assistant/ to compute the capacity.
  StaticJsonBuffer<256> jsonBuffer;

  // Parse the root object
  JsonObject &root = jsonBuffer.createObject();

  // Set the values
  root["hostname"] = config.hostname;
  root["port"] = config.port;

  // Serialize JSON to file
  if (root.printTo(file) == 0) {
    Serial.println(F("Failed to write to file"));
  }

  // Close the file (File's destructor doesn't close the file)
  file.close();
}

// Prints the content of a file to the Serial
void printFile(const char *filename) {
  // Open file for reading
  File file = SD.open(filename);
  if (!file) {
    Serial.println(F("Failed to read file"));
    return;
  }

  // Extract each characters by one by one
  while (file.available()) {
    Serial.print((char)file.read());
  }
  Serial.println();

  // Close the file (File's destructor doesn't close the file)
  file.close();
}

void setup() {
  // Initialize serial port
  Serial.begin(9600);
  while (!Serial) continue;

  // Initialize SD library
  while (!SD.begin()) {
    Serial.println(F("Failed to initialize SD library"));
    delay(1000);
  }

  // Should load default config if run for the first time
  Serial.println(F("Loading configuration..."));
  loadConfiguration(filename, config);

  // Create configuration file
  Serial.println(F("Saving configuration..."));
  saveConfiguration(filename, config);

  // Dump config file
  Serial.println(F("Print config file..."));
  printFile(filename);
}

void loop() {
  // not used in this example
}

// See also
// --------
//
// The website arduinojson.org contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization or deserialization problem.
// Please check it out at: https://arduinojson.org/
//
// The book "Mastering ArduinoJson" contains a case study of a project that has
// a complex configuration with nested members.
// Contrary to this example, the project in the book uses the SPIFFS filesystem.
// Please check it out at: https://arduinojson.org/book/ 

« Last Edit: Jul 11th, 2019 at 2:02pm by Tim@Visual Micro »  
Back to top
WWW  
IP Logged
 
Marius
Developer
****
Offline


Posts: 204
Location: Centurion RSA
Joined: Sep 7th, 2011
Re: Problem with structures
Reply #6 - Jul 11th, 2019 at 2:31pm
Print Post  
Thanks that works now. The bugs were me mucking about to try and isolate the issue
  
Back to top
IP Logged
 
Tim@Visual Micro
Administrator
*****
Offline


Posts: 12070
Location: United Kingdom
Joined: Apr 10th, 2010
Re: Problem with structures
Reply #7 - Jul 11th, 2019 at 2:39pm
Print Post  
Great, Yep makes sense. When/if you create a new empty project the template adds a note about the prototypes but we need to move to using the ctags system Arduino uses.

If Microsoft hasn't of caused tool window chaos with VS2019 we would be working on that right now  Cry but the forward moves will be good for us  Smiley
« Last Edit: Jul 11th, 2019 at 2:40pm by Tim@Visual Micro »  
Back to top
WWW  
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint