Bulk publish an array

Hello Everyone,

I am trying to do something simple, but I am a little confused. There seem to be a lot of different open topics about this already, but I was wondering if someone can assist me. I am just trying to measure current using a current shunt and I want to store that value into an array using the analogPin. I then want to bulk publish all the values that I am recording into the array. Can you please help me I am a little confused? When I publish the array I then want to push it through a webhook of IFTTT I have already set it up to receive my array name whenever it publishes. Here is my code:

int Current = 0;
int analogPin = A0;
unsigned int Current_Values [500]; 
int data = 0;
int i = 0;

void setup() {
}

void loop() {
    Current_Values[i] = analogRead(analogPin);
    i++;
    data = Current;
    if(i>=500){
        Particle.publish("Current", data);
    }
    delayMicroseconds(100);
}

Particle.publish() can only take a strings (up to 622 bytes) as data payload.

Hello ScruffR,

I understand that. I can publish sooner so that I do not go over the 622 bytes. This was just an example.

If you understand that you also understand that an integer array is not a string and each unsigned int in your array would occupy 4 bytes, right?

Hello ScruffR,

I am sorry i did not know that. Would you recommend that I move it too a string?

I really just want to record the values then everytime i publish the array i want to rewrite the array starting from 0 all of my data will be saved into a google sheet.

Moreover, the strings you can transfer via Particle.publish() can only use a subset of the entire 256 values range of a char array.

In order to transfer binary data you’d need to map your values into the acceptable range.
To pack the maximum amount of binary data into an acceptable string you’d use Base85 encoding.
Or when data density isn’t an issue you could just convert the binary values into a string representation like this

  char data[622];
  snprintf(data, sizeof(data), "%d", i);

BTW, your original code does fail to reset i to zero once the publish is done :wink:

I know I will clear it later my main concern is the publishing part. Let me look into the documentation on the snprintf and see if I can figure out how to do that.

Sorry I am new working on the Electron and I am trying to use it as a datalogger just bear with me please.

int Current = 0;
int analogPin = A0;
unsigned int Current_Values [50]; 
int data = 0;
int i = 0;

void setup() {



}

void loop() {
    Current_Values[i] = analogRead(analogPin);
    i++;
    data = Current;
        if(i>=50){
        Particle.publish("Current", data);
        i=0;
        }
    delay(100);
}

Now it resets the array back to zero :smile:

Hello scruffR,

I have to say that I am lost i was reading the JSON in the docs and I feel more lost than before can you give me an example with my code on how you would do it? I am sorry for asking you to do this for me I am really trying to learn.

int Current = 0;
int analogPin = A0;
unsigned int Current_Values [50]; 
int data = 0;
int i = 0;

void setup() {



}

void loop() {
    Current_Values[i] = analogRead(analogPin);
    i++;
    data = Current;
        if(i>=50){
        Particle.publish("Current", data);
        i=0;
        }
    delay(100);
}

Hello ScruffR,

How is this looking to you. Am I doing this right?

int Current = 0;
int analogPin = A0;
//unsigned int Current_Values [50];
int data = 0;
int i = 0;

int buf = 1;

JSONWriter& Current_Values();

// EXAMPLE
memset(buf, 0, sizeof(buf));
JSONBufferWriter writer(buf, sizeof(buf) - 1);

void setup() {
}

void loop() {

    //Current_Values[i] = analogRead(analogPin);
    writer.Current_Values(i) = analogRead(analogPin);
    i++;
    data = Current;
        if(i>=50){
        Particle.publish("Current", data);
        i=0;
        }
    delay(100);
}

Do I need to include a JSON extension? - figured out i had to include the JSMN

You never set Current so that code is just going to publish a zero over and over again. You publish “data”, but what is “data” at the moment when you are publishing it? If you wanted to just write a string, this is what I’d do:

int Current = 0;
int analogPin = A0;
unsigned int Current_Values [50]; 
int data = 0;
int i = 0;
char pub_data[622];
uint8_t chars_written = 0;

bool json_str = true; // change this if you want a normal array

void setup() {
    Serial.begin();
}

void loop() {
    // get the current reading
    Current_Values[i] = analogRead(analogPin);
    i++;
    
    // max value of analogRead is 4096, which is 4 bytes as a char representation, plus a delimeter is 5 bytes per value because a char is 1 byte
    // 622 max bytes divided by 5 bytes per value gives up to 124 values per packet max.
    // 50 values per packet with a 100ms delay means publish roughly every 5 seconds (assuming consistent connectivity, etc)
    if(i>=50){ 
        // we have enough data to make a complete packet, so let's assemble the packet
        uint8_t pub_data_index = 0;

        // if you want this to be a json-compliant string, we can set that up the formatting:
        if (json_str) {
            chars_written = snprint(pub_data, sizeof(pub_data), "{\"vals\":[");
            pub_data_index += chars_written;
        }


        for (int k = 0; k <= i; k++) {
            // for each value, add it into our publish string along with a delimeter
            // we move the starting point in our output char array with each write, by using '&' to get the address of the current specified index
            chars_written = snprintf(&pub_data[pub_data_index], (sizeof(pub_data) - pub_data_index), "%d", Current_Values[k]);
            pub_data_index += chars_written;  // move the location forward to write the next item. 
            if (k < i) {  // don't write the comma for the last value
                chars_written = snprint(&pub_data[pub_data_index], (sizeof(pub_data) - pub_data_index), ","); 
                pub_data_index += chars_written;  // move the location forward to write the next item. 
            }
        }

        // if you want this to be a json-compliant string, we can set that up the final formatting:
        if (json_str) {
            chars_written = snprint(&pub_data[pub_data_index], (sizeof(pub_data) - pub_data_index), "]}"); 
            pub_data_index += chars_written;
        }

        // let's see what we are sending before we send it!
        Serial.println(pub_data);

        // now the data is nicely formatted into a c-style string (aka char array with a null terminator provided by snprintf)
        Particle.publish("Current", pub_data);
        i=0;
    }

    delay(100);
}

Untested, but should be close to right.

1 Like

Hello Justicefreed_amper,

Thank you so much for your help that would have taken me forever to figure out can you please tell me where I can find this documentation in the particle docs?

This isn’t really documentation, this is just fundamental C++ programming best practices. JSON formatting is just being compliant to the JSON spec. If you are asking about some specific piece of info we can be more specific.

some example keywords you can search for your learning include:

  • c strings
  • c++ char array
  • c++ array of integers into string
  • c++ make json array
  • c++ array pointers
  • snprintf array

Hello justicefreed_amper,

Thank you I really appreciate it.