[Arduinojson]How to use uint_8t with json

Good day,

I actually a problem with an asisignment.

error: incompatible types in assignment of ‘ArduinoJson::Internals::EnableIf<true, int>::type {aka int}’ to ‘uint8_t [16] {aka unsigned char [16]}’

config_radio.appskey = root[“appskey”] | 0x00;

Here is the problem. I would like to temporarely save LoRa (TTN) credential into an SD card. (When themicrocotroller read the SDcard, it save it into an EEPROM and delete the file, immediately).

For that task, I am using Arduinojson library to use the JSON format.

First be inform, for now, my credential are in my ino file as the following:

static const PROGMEM u1_t NWKSKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  static const u1_t PROGMEM APPSKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  static const u4_t DEVADDR = 0x0000000; // <-- Change this address for every node

You can observ the type : u1_t and u4_t.

I asked the TTN forum and the replyed, it match as the following

// Target platform as C library
typedef uint8_t bit_t;
typedef uint8_t u1_t;
typedef int8_t s1_t;
typedef uint16_t u2_t;
typedef int16_t s2_t;
typedef uint32_t u4_t;
typedef int32_t s4_t;
typedef unsigned int uint;
typedef const char* str_t;

I created my own library for that job.

I created (in my file.h) a struct (but not really sure about my code) which should contain the value of my first pasted code, above.

struct Config_radio {
    uint8_t nwkskey[16];
    uint8_t appskey[16];
    uint32_t devaddr;
  };

and I declare as the following

Config_radio config_radio;

In my file.ccp, I am try to create the config file as the following (FYI)

int Foxuino::_save_Config(const char * filename, int board){
  // Open file for writing

    //int board Not use for now. I gave a temp value of 2, but it will be bwteen 1 and 4 later
  board = 2;
    _sd.remove(filename);

    File file = _sd.open(filename, FILE_WRITE);
    if (!file) {
      if(_print)
      {
        Serial.println(F("Failed to create file"));
      }
      return 0;
    }

    // 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();

    root["nwkskey"] = "0x00";
    root["appskey"] = "0x00";
    root["devaddr"] = "0x00";


    // Serialize JSON to file
    if (root.printTo(file) == 0) {
      if(_print)
      {
        Serial.println(F("Failed to write to file"));
      }
      return board - (board+board); // return -2
    }

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

Then I should get a new file name config.txt with the following text

{
“nwkskey”: “0x00”,
“appskey”: “0x00”,
“devaddr”: “0x00”
}

I know, the above string van not work and this all of my problem. I believe, I can only save char, int or boleen value. But unit_8t, is not a int?

Finaly, I have a function to load the config file, and my compiler generated an error message from that function

int Foxuino::_load_Config(const char * filename, int board)
{
  
    // 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"));
      return 0;
    }
    else
    {
      // 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
      */
      

      config_radio.nwkskey = root["nwkskey"] | 0x00;
      config_radio.appskey = root["appskey"] | 0x00;
      config_radio.devaddr = root["devaddr"] | 0x00;
      
      // Close the file (File's destructor doesn't close the file)
      file.close();

    }
}

My compiler display that error message:

error: incompatible types in assignment of ‘ArduinoJson::Internals::EnableIf<true, int>::type {aka int}’ to ‘uint8_t [16] {aka unsigned char [16]}’

config_radio.appskey = root[“appskey”] | 0x00;

What I understand, arduinojson dot not accept uint8_t, but why it do not show an error about uint32_t?

Does it correct, Arduinojson file only accpet booleen, int and char value?

NOTE: When the file is created, the user will remove the user card and save his credential. When the micro controller (SAMD21) is started for the second time, it will read the credential and save it in the EEPROM and then delete the file.

Then now my worries is how to save the value

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }

in a JSON file and then give the read value to the static variable

static const PROGMEM u1_t NWKSKEY[16]

The think, I would like to first solve, it how to save and read

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }

(Of course, the above key are NULL. in order to avoid providing real credential :open_mouth: )
to and from a json file with Arduinojson

I hope, I clearely explained the situation and issue :slight_smile:

Many thank for any help you can give me

I wish you a nice day
Pierrot

I believe, I can only save char, int or boleen value.

You can print any kind of variable (well, almost any) to a file on an SD card. That includes signed and unsigned bytes, ints, and longs.

My compiler display that error message:

Except when declaring and initializing an array, you can not use an array name on the left of an equal sign. You must set each element of the array individually.

root["appskey"] probably returns a string. Oring that with 0x00 doesn't make sense. You need to use strcpy() or memcpy() to copy that string into another array.

Dear PaulS

Thank for your reply

root[“appskey”] probably returns a string. Oring that with 0x00 doesn’t make sense

Yes, of course :slight_smile:

Then I should do something like?

for (byte i = 0; i < sizeof(config_radio.nwkskey); i++) {
            config_radio.nwkskey[i] = root["nwkskey"][i];
        }

(The error message do not occur from my compiler with it)

And of course the credential should not be a string but a uint8_t.
So, let say,I replace the value

root["nwkskey"] = "0x00";
      root["appskey"] = "0x00";
      root["devaddr"] = "0x00";

by (somethink like

      root["nwkskey"] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
      root["appskey"] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
      root["devaddr"] = 0x0000000;

Am I closer to the right way?

In any case, this

      root["nwkskey"] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
      root["appskey"] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
      root["devaddr"] = 0x0000000;

generate an error

couldn’t deduce template parameter ‘TValue’

So I do not know if the error come from my syntax or from the size of root[“nwkskey”]. For this, I am a bit lost :slight_smile:

You can’t assign a collection of values to an array in one step, like that. You need to assign elements individually.