How to pass an array of unsigned int into JSON format and POST it out

Hi there

I’m working on passing an array of unsigned int into JSON and I like to ask if it would be possible to do that.

Following is my code

IR_RX_Buffer_len = IR_Copy.rawlen;
  Serial.print("(");
  Serial.print(IR_RX_Buffer_len,DEC);
  Serial.print(") ");    
   for(int n = 0; n<IR_RX_Buffer_len ; n++){
    Serial.print(IR_RX_Buffer[n],DEC);
    Serial.print("-");
   }
   Serial.println(" ");
   request.hostname = "requestb.in";
    request.port = 80;
    request.path = "/1m2pa291";

    request.body = "{\"key\":\"hahahaha\"}";
    delay(500);
    http.post(request, response, headers);
    Serial.print("Application>\tResponse status: ");
    Serial.println(response.status);

    Serial.print("Application>\tHTTP Response Body: ");
    Serial.println(response.body);
  Serial.println(" ");

The output of the result

4293896800-3300-1800-300-1400-300-1350-300-500-300-500-300-500-300-1350-300-550-250-550-300-1350-300-1400-300-500-300-1400-300-500-250-550-300-1350-300-1400-300-500-300-1400-300-1350-300-500-350-500-300-1350-300-500-300-550-300-1400-300-500-300-500-300-500-300-500-300-500-250-550-300-550-300-550-250-550-250-550-250-550-300-500-300-550-300-500-300-500-300-500-300-500-250-550-250-550-300-550-300-1400-300-500-250-550-300-500-300-500-300-500-300-1400-250-1400-300HttpClient>.Connecting to: requestb.in:80
HttpClient>.Start of HTTP Request.
POST /1m2pa291 HTTP/1.0
Connection: close
HOST: requestb.in
Content-Length: 18
Content-Type: application/json
{"key":"hahahaha"}
HttpClient>.End of HTTP Request.

IR_RX_Buffer[n] is an array of unsigned int.
How do I place the IR_RX_Buffer into the request.body
so that I can send it POST it out as

request.body = "{\"data\":\"IR_RX_Buffer\"}";

Because when I try to do the above it threw error.

I’m new to writing code for hardware and I’m looking forward to learn from everyone
Thanks in advance

If you’re just looking for how to format an array of unsigned ints so they are valid JSON, then you want something that looks like this:

{
 "key" : "hahahaha",
 "myArray" : [0, 1, 2, 3, 4, 5, 6, 7, 8]
}

The things that usually cause people problems is there are no quotes in the values for an array of ints.

Hi @ZombieKiller

Oh I'm actually looking at how to add in the array of ints.
because when I put "{"data":"IR_RX_Buffer"}";
It throws an error.

also what do you mean by

The things that usually cause people problems is there are no quotes in the values for an array of ints

Thank you for the time.

So, what you want to do is build a string with the contents of your array, and then make that string part of the JSON that you include in your request body. So, where you have:

 for(int n = 0; n<IR_RX_Buffer_len ; n++){
    Serial.print(IR_RX_Buffer[n],DEC);
    Serial.print("-");
   } 

You could replace it with something like (this is psuedo code… I don’t know if this will compile):

String arr = "";
for (int n =0; n<IR_RX_Buffer_len; n++) {
    if (n > 0) {
       arr += ","; 
   }
    arr += String(IR_RX_Buffer[n]); 
}

And then your request body:

request.body = "{\"key\":\"hahahah\", \"irBuffer\": [" + arr + "] }";

Apologies if some of this isn’t 100% legit Wiring code, but it’s not quite 6am yet and I only write psuedocode before my first cup of coffee :smile:

2 Likes

Thank you so much!

I believe the code works :smile:
But when I try to send the code the spark core turns red.

Do you think it might be the buffer issue?

This is my revised function

void printIRCMD(void)
{
  IR_RX_Buffer_len = IR_Copy.rawlen;
  Serial.print("(");
  Serial.print(IR_RX_Buffer_len,DEC);
  Serial.print(") ");  
  String arr = "";
   for(int n = 0; n<IR_RX_Buffer_len ; n++){
    Serial.print(IR_RX_Buffer[n],DEC);
    Serial.print("-");
    //save into an array
    //already in array IR_RX_Buffer
    //publish out
    if (n > 0) {
       arr += ","; 
    }
    arr += String(IR_RX_Buffer[n],DEC); 
    
   }
    Serial.print("Standby To Send");
    request.hostname = "requestb.in";
    request.port = 80;
    request.path = "/rilzefri";

    request.body = "{\"key\":\"hahahah\", \"irBuffer\": [" + arr + "] }";;
    delay(500);
    http.post(request, response, headers);
    Serial.print("Application>\tResponse status: ");
    Serial.println(response.status);

    Serial.print("Application>\tHTTP Response Body: ");
    Serial.println(response.body);
  Serial.println(" ");
  IR_Receiver.resume();
}

My serial output

And Finally a video to share with you.
link

@bosslee, based on your output, you have 584 entries in IR_RX_Buffer[] which you then convert to a string. With each number being 3 digits on average, that adds up to over 1.7KB of data being used on the stack since it’s a local variable. That is what is causing the Core to crash. So, you either make multiple smaller posts or rethink your approach IMO.

2 Likes

Thanks for the tip!
I kinda solved it.
in a non elegant way thou :smile:

for(int n = 0; n<IR_RX_Buffer_len ; n++){
    Serial.print(IR_RX_Buffer[n],DEC);
    Serial.print("-");
    //save into an array
    //already in array IR_RX_Buffer
    //publish out
    
    // if n is > 200 break it down into 3 push.
    // process in 3 pushes
    // else process in one push
    
    if (n > 0 && n <=150 ) {
        arr += ","; 
        arr += String(IR_RX_Buffer[n],DEC);
    }
    
    if (n > 150 && n <=300) {
        arr1 += ","; 
        arr1 += String(IR_RX_Buffer[n],DEC);
    }
    
    if (n > 300 && n <=450) {
        arr2 += ","; 
        arr2 += String(IR_RX_Buffer[n],DEC);
    }
    
    if (n > 450 && n <=600) {
        arr3 += ","; 
        arr3 += String(IR_RX_Buffer[n],DEC);
    }
    
   }
    Serial.print("Standby To Send");
    
    if (IR_RX_Buffer_len >= 200) {
        Serial.println("Pushing Multiple Request");
        Serial.print(IR_RX_Buffer_len,DEC);
        Serial.println(" ");
        request.hostname = "requestb.in";
        request.port = 80;
        request.path = "/rilzefri";
        request.body = "{\"Data\":\"Start\",\"irBuffer\": [" + arr + "],\"Part\":\"True\" }";
        http.post(request, response, headers);
        Serial.print("Application>\tResponse status: ");
        Serial.println(response.status);
        delay(1000);
        Serial.print("Application>\tHTTP Response Body: ");
        Serial.println(response.body);
        delay(5000);
        Serial.print("Pushing Part 2");
        Serial.println(" ");
        request.hostname = "requestb.in";
        request.port = 80;
        request.path = "/rilzefri";
        request.body = "{\"Data\":\"Part_2\",\"irBuffer\": [" + arr1 + "],\"Part\":\"True\" }";
        http.post(request, response, headers);
        Serial.print("Application>\tResponse status: ");
        Serial.println(response.status);
        delay(1000);
        Serial.print("Application>\tHTTP Response Body: ");
        Serial.println(response.body);
        delay(5000);
        Serial.print("Pushing Part 3");
        Serial.println(" ");
        request.hostname = "requestb.in";
        request.port = 80;
        request.path = "/rilzefri";
        request.body = "{\"Data\":\"Part_3\",\"irBuffer\": [" + arr2 + "],\"Part\":\"True\" }";
        http.post(request, response, headers);
        Serial.print("Application>\tResponse status: ");
        Serial.println(response.status);
        delay(1000);
        Serial.print("Application>\tHTTP Response Body: ");
        Serial.println(response.body);
        delay(5000);
        Serial.print("Pushing Part 4");
        Serial.println(" ");
        request.hostname = "requestb.in";
        request.port = 80;
        request.path = "/rilzefri";
        request.body = "{\"Data\":\"Part_4\",\"irBuffer\": [" + arr3 + "],\"Part\":\"False\" }";
        http.post(request, response, headers);
        Serial.print("Application>\tResponse status: ");
        Serial.println(response.status);
        delay(1000);
        Serial.print("Application>\tHTTP Response Body: ");
        Serial.println(response.body);
        delay(5000);
    } else {
        Serial.print("Pushing Single Data Source");
        Serial.println(" ");
        request.hostname = "requestb.in";
        request.port = 80;
        request.path = "/rilzefri";
        request.body = "{\"Data\":\"Start\",\"irBuffer\": [" + arr + "],\"Part\":\"False\"}";
        http.post(request, response, headers);
        Serial.print("Application>\tResponse status: ");
        Serial.println(response.status);
        delay(1000);
        Serial.print("Application>\tHTTP Response Body: ");
        Serial.println(response.body);
    }
  Serial.println(" ");

Thank you everyone.
Thank you @ZombieKiller for the code too!
Without it, I would not have known how to start.

@peekay123 has an extremely valid point. While my code technically works to build a JSON string with an array, there are practical limitations. We don’t have access to a lot of virtual machine / memory managers that we normally get with higher level languages like C# and Java. Putting 2KB on the stack is a bad idea.

There are two options:

  1. Figure out some way to manage the string you’re building so it’s in the heap and not on the stack.
  2. Convert your web/JSON interface so it accepts multiple smaller requests so you can keep the payload size down.

Of these, option 2 is my favorite because in addition to keeping your memory consumption down, it also keeps the payload size down which reduces network round-trip time, which in turn reduces the amount of time your core spends blocked on network operations.