Closed wittrup closed 6 months ago
Hi @wittrup,
I'm surprised you had to use buffers.
Did you try to pass the file
directly to deserializeJson()
and serializeJson()
?
Best regards, Benoit
Yes.
Reproduced what I did first:
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// 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/v7/example/config/
#include <WiFiNINA.h>
#include <ArduinoJson.h>
// Our configuration structure.
struct Config {
char hostname[64];
int port;
};
const char* filename = "/fs/config.txt"; // File path
Config config; // <- global configuration object
// Loads the configuration from a file
void loadConfiguration(const char* filename, Config& config) {
// Open file for reading
WiFiStorageFile file = WiFiStorage.open(filename); // Open file for reading
// Allocate a temporary JsonDocument
JsonDocument 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) {
// Open file for writing
WiFiStorageFile file = WiFiStorage.open(filename); // Open file
if (file) {
file.erase(); // Erase existing file to overwrite
}
if (!file) {
Serial.println(F("Failed to create file"));
return;
}
// Allocate a temporary JsonDocument
JsonDocument 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
WiFiStorageFile file = WiFiStorage.open(filename); // Open file for reading
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(115200);
while ((!Serial) && (millis() < 3000)); // Wait until 3 seconds for Serial
while (!SD.begin(chipSelect)) {
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);
}
Verify generates the output:
\AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino: In function 'void printFile(const char*)':
\AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:94:34: error: no matching function for call to 'WiFiStorageFile::read()'
In file included from \Documents\Arduino\libraries\WiFiNINA\src/WiFi.h:38:0,
from \Documents\Arduino\libraries\WiFiNINA\src/WiFiNINA.h:23,
from \AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:17:
\Documents\Arduino\libraries\WiFiNINA\src/WiFiStorage.h:108:11: note: candidate: uint32_t WiFiStorageFile::read(void*, uint32_t)
uint32_t read(void *buf, uint32_t rdlen) {
^~~~
\Documents\Arduino\libraries\WiFiNINA\src/WiFiStorage.h:108:11: note: candidate expects 2 arguments, 0 provided
\AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino: In function 'void setup()':
\AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:107:11: error: 'SD' was not declared in this scope
\AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:107:11: note: suggested alternative: 'SDA'
\AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:107:20: error: 'chipSelect' was not declared in this scope
\AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:107:20: note: suggested alternative: 'pselect'
In file included from \Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/deserialize.hpp:9:0,
from \Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/JsonDeserializer.hpp:7,
from \Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson.hpp:47,
from \Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson.h:9,
from \AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:18:
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/Reader.hpp: In instantiation of 'int ArduinoJson::V703PB2::detail::Reader<TSource, Enable>::read() [with TSource = WiFiStorageFile; Enable = void]':
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/Latch.hpp:38:9: required from 'void ArduinoJson::V703PB2::detail::Latch<TReader>::load() [with TReader = ArduinoJson::V703PB2::detail::Reader<WiFiStorageFile, void>]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/Latch.hpp:30:11: required from 'char ArduinoJson::V703PB2::detail::Latch<TReader>::current() [with TReader = ArduinoJson::V703PB2::detail::Reader<WiFiStorageFile, void>]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/JsonDeserializer.hpp:47:27: required from 'char ArduinoJson::V703PB2::detail::JsonDeserializer<TReader>::current() [with TReader = ArduinoJson::V703PB2::detail::Reader<WiFiStorageFile, void>]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/JsonDeserializer.hpp:71:20: required from 'ArduinoJson::V703PB2::DeserializationError::Code ArduinoJson::V703PB2::detail::JsonDeserializer<TReader>::parseVariant(ArduinoJson::V703PB2::detail::VariantData&, TFilter, ArduinoJson::V703PB2::DeserializationOption::NestingLimit) [with TFilter = ArduinoJson::V703PB2::detail::AllowAllFilter; TReader = ArduinoJson::V703PB2::detail::Reader<WiFiStorageFile, void>]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/JsonDeserializer.hpp:35:23: required from 'ArduinoJson::V703PB2::DeserializationError ArduinoJson::V703PB2::detail::JsonDeserializer<TReader>::parse(ArduinoJson::V703PB2::detail::VariantData&, TFilter, ArduinoJson::V703PB2::DeserializationOption::NestingLimit) [with TFilter = ArduinoJson::V703PB2::detail::AllowAllFilter; TReader = ArduinoJson::V703PB2::detail::Reader<WiFiStorageFile, void>]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/deserialize.hpp:57:8: required from 'ArduinoJson::V703PB2::DeserializationError ArduinoJson::V703PB2::detail::doDeserialize(TDestination&&, TReader, TOptions) [with TDeserializer = ArduinoJson::V703PB2::detail::JsonDeserializer; TDestination = ArduinoJson::V703PB2::JsonDocument&; TReader = ArduinoJson::V703PB2::detail::Reader<WiFiStorageFile, void>; TOptions = ArduinoJson::V703PB2::detail::DeserializationOptions<ArduinoJson::V703PB2::detail::AllowAllFilter>]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/deserialize.hpp:69:38: required from 'ArduinoJson::V703PB2::DeserializationError ArduinoJson::V703PB2::detail::deserialize(TDestination&&, TStream&&, Args ...) [with TDeserializer = ArduinoJson::V703PB2::detail::JsonDeserializer; TDestination = ArduinoJson::V703PB2::JsonDocument&; TStream = WiFiStorageFile&; Args = {}; <template-parameter-1-5> = void]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/JsonDeserializer.hpp:679:39: required from 'typename ArduinoJson::V703PB2::detail::enable_if<ArduinoJson::V703PB2::detail::is_deserialize_destination<TDestination>::value, ArduinoJson::V703PB2::DeserializationError>::type ArduinoJson::V703PB2::deserializeJson(TDestination&&, Args&& ...) [with TDestination = ArduinoJson::V703PB2::JsonDocument&; Args = {WiFiStorageFile&}; typename ArduinoJson::V703PB2::detail::enable_if<ArduinoJson::V703PB2::detail::is_deserialize_destination<TDestination>::value, ArduinoJson::V703PB2::DeserializationError>::type = ArduinoJson::V703PB2::DeserializationError]'
\AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:39:57: required from here
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/Reader.hpp:22:26: error: no matching function for call to 'WiFiStorageFile::read()'
return source_->read(); // Error here? See https://arduinojson.org/v7/invalid-input/
^
In file included from \Documents\Arduino\libraries\WiFiNINA\src/WiFi.h:38:0,
from \Documents\Arduino\libraries\WiFiNINA\src/WiFiNINA.h:23,
from \AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:17:
\Documents\Arduino\libraries\WiFiNINA\src/WiFiStorage.h:108:11: note: candidate: uint32_t WiFiStorageFile::read(void*, uint32_t)
uint32_t read(void *buf, uint32_t rdlen) {
^~~~
\Documents\Arduino\libraries\WiFiNINA\src/WiFiStorage.h:108:11: note: candidate expects 2 arguments, 0 provided
In file included from \Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Serialization/serialize.hpp:7:0,
from \Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/JsonSerializer.hpp:9,
from \Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/ConverterImpl.hpp:7,
from \Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson.hpp:42,
from \Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson.h:9,
from \AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:18:
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Serialization/Writer.hpp: In instantiation of 'size_t ArduinoJson::V703PB2::detail::Writer<TDestination, Enable>::write(uint8_t) [with TDestination = WiFiStorageFile; Enable = void; size_t = unsigned int; uint8_t = unsigned char]':
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Serialization/CountingDecorator.hpp:17:12: required from 'void ArduinoJson::V703PB2::detail::CountingDecorator<TWriter>::write(uint8_t) [with TWriter = ArduinoJson::V703PB2::detail::Writer<WiFiStorageFile, void>; uint8_t = unsigned char]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/TextFormatter.hpp:166:5: required from 'void ArduinoJson::V703PB2::detail::TextFormatter<TWriter>::writeRaw(char) [with TWriter = ArduinoJson::V703PB2::detail::Writer<WiFiStorageFile, void>]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/TextFormatter.hpp:85:15: required from 'void ArduinoJson::V703PB2::detail::TextFormatter<TWriter>::writeFloat(T) [with T = double; TWriter = ArduinoJson::V703PB2::detail::Writer<WiFiStorageFile, void>]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/JsonSerializer.hpp:65:5: required from 'size_t ArduinoJson::V703PB2::detail::JsonSerializer<TWriter>::visit(ArduinoJson::V703PB2::JsonFloat) [with TWriter = ArduinoJson::V703PB2::detail::Writer<WiFiStorageFile, void>; size_t = unsigned int; ArduinoJson::V703PB2::JsonFloat = double]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantData.hpp:31:44: required from 'typename TVisitor::result_type ArduinoJson::V703PB2::detail::VariantData::accept(TVisitor&) const [with TVisitor = ArduinoJson::V703PB2::detail::JsonSerializer<ArduinoJson::V703PB2::detail::Writer<WiFiStorageFile, void> >; typename TVisitor::result_type = unsigned int]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantData.hpp:69:31: required from 'static typename TVisitor::result_type ArduinoJson::V703PB2::detail::VariantData::accept(const ArduinoJson::V703PB2::detail::VariantData*, TVisitor&) [with TVisitor = ArduinoJson::V703PB2::detail::JsonSerializer<ArduinoJson::V703PB2::detail::Writer<WiFiStorageFile, void> >; typename TVisitor::result_type = unsigned int]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Serialization/serialize.hpp:15:29: required from 'size_t ArduinoJson::V703PB2::detail::doSerialize(ArduinoJson::V703PB2::JsonVariantConst, TWriter) [with TSerializer = ArduinoJson::V703PB2::detail::JsonSerializer; TWriter = ArduinoJson::V703PB2::detail::Writer<WiFiStorageFile, void>; size_t = unsigned int]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Serialization/serialize.hpp:22:34: required from 'size_t ArduinoJson::V703PB2::detail::serialize(ArduinoJson::V703PB2::JsonVariantConst, TDestination&) [with TSerializer = ArduinoJson::V703PB2::detail::JsonSerializer; TDestination = WiFiStorageFile; size_t = unsigned int]'
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/JsonSerializer.hpp:133:35: required from 'size_t ArduinoJson::V703PB2::serializeJson(ArduinoJson::V703PB2::JsonVariantConst, TDestination&) [with TDestination = WiFiStorageFile; size_t = unsigned int]'
\AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:75:30: required from here
\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Serialization/Writer.hpp:18:26: error: no matching function for call to 'WiFiStorageFile::write(uint8_t&)'
return dest_->write(c);
^
In file included from \Documents\Arduino\libraries\WiFiNINA\src/WiFi.h:38:0,
from \Documents\Arduino\libraries\WiFiNINA\src/WiFiNINA.h:23,
from \AppData\Local\Temp\.arduinoIDE-unsaved202427-23644-rm19e1.fd93\JsonConfigFile\JsonConfigFile.ino:17:
\Documents\Arduino\libraries\WiFiNINA\src/WiFiStorage.h:117:11: note: candidate: uint32_t WiFiStorageFile::write(const void*, uint32_t)
uint32_t write(const void *buf, uint32_t wrlen) {
^~~~~
\Documents\Arduino\libraries\WiFiNINA\src/WiFiStorage.h:117:11: note: candidate expects 2 arguments, 1 provided
exit status 1
Compilation error: no matching function for call to 'WiFiStorageFile::read()'
I'm sorry, I didn't realize that WiFiStorageFile
doesn't implement the Stream
interface.
I opened the following issue: arduino-libraries/WiFiNINA#276
Once WiFiStorageFile
implements Stream
, using it with ArduinoJson will be very straightforward.
Not need to add a new example or a new documentation page.
I've merged together a working example of JsonConfigFile.ino and WiFiStorage.ino so that ArduinoJson can be used with Arduino Nano 33 IoT and others that use u-blox NINA-W102 (datasheet).
I'd like to have it improved, quality checked etc. and implemented as an example in ArduinoJson/examples/