Simple Conversion Problem

My system involves values stored in a structure called Celldata[5] (eventually to be [60]) with elements for each entry
Celldata[j].temp;
Celldata[j].extra;

Each entry of each pair will fit into one byte. (For temp, I use uint8_t format since values may range up to 200.)
I seem to have no trouble in filling up the table with values. (For test purposes I have used some values based on [j] so that I can see what is going on.)

The problem seems to be in reading out the values in a way that is meaningful to the program.

Eventually I would like to form a long String, consisting of the value pairs (as strings, with some additional manipulations) separated by commas. (This is required by the format of the output which will eventually be sent to a Google sheet.)

I have extracted the confusing part of the program here - while leaving in some extraneous stuff - such as printing to the serial monitor at various points along the way.

I have not been able to get the desired string. I can compile with no errors,but the monitor at run time then has problems.

I think I'm not declaring something correctly, or some other foolish error, although I have tried many variations. There must be a way to do what I want.

Any suggestions?

//  Copy for playing around with  -  original compiles OK.
// HVM Jan24 2020 = Started same as Jan 22.  Mods made from here.

#include <ESP8266WiFi.h>
#include "HTTPSRedirect.h"
#include "DebugMacros.h"

float x ;
float h;
float t;
String datastring = "";

struct Celldata {
  uint8_t  temp;
  byte     cyc;
  byte     extra;  // here used for tests
                 } // For struct Celldata
Celldata[5];  // for now, try with only 5 slots. Eventually 60.

void setup() {

  delay(100);
  Serial.begin(115200);
  Serial.println();

}  // End of setup

void loop() {

  delay(1000);

  for (  int  j = 0 ; j <= 5 ; j++) { // Celldata was defined for  5  cells for now
    Celldata[j].temp = j;
    Celldata[j].extra = ( 2 * j );
    delay(100);
    byte num = (j % 3)  ;  // thus num will always be 0, 1, or 2

    Celldata[j].cyc  = num  ;  // % = the modulo operator, Thus  num    will always be 0, 1. 2
   
    Serial.print(Celldata[j].temp);
    Serial.print("  ");
    Serial.print(num);
    Serial.print(" = ");
    Serial.print(Celldata[j].cyc);
    Serial.print("extra= ");
    Serial.println(Celldata[j].extra);

  }  // end of "for" loop
     // End of putting data into cells of [j]  0 through 5
     // At this point, Celldata[5].temp, .num, and .extra are all filled with something.

  String adder = "";  //
  byte j;
  String cdt[j];
  String cyc[j];

  Serial.println("End of filling up slots");

  for (    j = 0 ; j <= 2 ; j++) { // Celldata was defined for  15  cells for now
    Serial.println("In for loop reading data");
    cdt[j] = Celldata[j].temp  ;
    cyc[j] = Celldata[j].cyc   ;
    Serial.println("read both pieces");
    Serial.print(cdt[j]);
    Serial.print("  ");
    Serial.print(cyc[j]);
    Serial.println(" end ");

    adder = adder +  cdt[j] + cyc[j] + "," ;

    Serial.println("used  adder = ");

                                 }  // end of for loop

  Serial.print("End of reading out cell data  ");
  Serial.println(adder);

 
}  // loopend -  I think!

mattbaum:
String, consisting of the value pairs (as strings, with some additional manipulations) separated by commas. (This is required by the format of the output which will eventually be sent to a Google sheet.)

Perhaps give an example of such a string for multiple "value pairs"

I can compile with no errors,but the monitor at run time then has problems.

Such as?

What is the purpose of this bit?

  String adder = "";  //
  byte j;
  String cdt[j];
  String cyc[j];

Ultimately the data will go into a Google sheet.
I copied and modified a sketch made by someone else, and the relevant part of the sample code (as modified) which works is shown in the "code" section here.

I made up the various "mcbXXX mcb" string values, and they are transferred neatly to the Google sheet columns by the rest of the program. I would like to duplicate this for the real values which I have (produced elsewhere in the program).

The "payload base" is the beginning of a string needed for the transfer to Google, and the ""}"; terminates the string.

For further info, the values in the array [j] are single byte values as follows:
Celldata[j].temp; = temperature, ranging from 0 to 200
Celldata[j].extra; = a number which is 0, 1, or 2, representing the state corresponding to the temperature. (I intend to do some further work to make the three values show up as words.)

I hope this helps someone to point me in the right direction!

  sheetXXX  = "mcb XXX mcb";
  sheetYYY  = "mcb YYY mcb";
  sheetZZZ  = "mcb ZZX mcb";
  

 // orig:   payload = payload_base + "\"" + sheetTemp + "," + sheetHumid + "\"}";
// This mod works.  Puts data into each column OK

//  This is what works:
    payload = payload_base + "\"" + sheetTemp + "," + sheetXXX + "," + sheetYYY + "," + sheetZZZ + "," + sheetHumid + "\"}";
  for (  int  j = 0 ; j <= 5 ; j++)   // Celldata was defined for  5  cells for now

The comment is correct, so why does the for loop write to 6 element6 of the array, one of which does not exist ?

Sorry about that one!
I had originally made my tests with 15 elements, but reduced it to 5 to minimize the output I had to look through. In my actual code, I see that I used j going from 0 to 4, but this was not the problem.

In my actual code, I see that I used j going from 0 to 4,

So the code that you posted was not actually the code that you have a problem with

Are there any other differences that we should know about ?

I have just now removed some extraneous stuff, added and corrected some things, and re-run my extract of my original file.
(As I said, it is merely an extract, to try to find what I am doing wrong.)

This compiles, but on running it flags an error in the Serial Monitor, so I know that something is not right. The error occurs at the place in the code indicated by < >.

I have been able to insert items such as sheetXXX = "mcb XXX mcb"; into the original code string.
I have been unable to insert items from my array/structure Celldata[j].
I think that I am not declaring something correctly, but I have no clue as to what/where.

//  Copy for playing around with  -  original compiles OK.
// HVM Jan24 2020 = Started same as Jan 22.  Mods made from here.

#include <ESP8266WiFi.h>
#include "HTTPSRedirect.h"
#include "DebugMacros.h"

  int j ;
struct Celldata {
  uint8_t  temp;
  byte     cyc;
  byte     extra;
                 } // For struct Celldata
Celldata[5];  // for now, try with only 5 slots. Eventually 60.

  String adder = "";  //
 /*
  String CDT[j];
  String CYC[j];
  uint8_t cdt[j];
  byte    cyc[j];
*/
void setup() {

  delay(100);
  Serial.begin(115200);
  Serial.println();

}  // End of setup

void loop() {

  String CDT[j];
  String CYC[j];
  uint8_t cdt[j];
  byte    cyc[j];


 int t;
 int h;
 String  sheetTemp  = ""; 
 String  sheetHumid = "";        
 String  sheetXXX  = "mcb XXX mcb";
 String  sheetYYY  = "mcb YYY mcb";
 String  sheetZZZ  = "mcb ZZX mcb";



  delay(1000);

  for (  j = 0 ; j <= 4 ; j++) { // Celldata was defined for  5  cells for now
    Celldata[j].temp = j;
    Celldata[j].extra = ( 2 * j );
    Celldata[j].cyc  = (j % 3)  ;  // % = the modulo operator, Thus cyc will always be 0, 1. 2

// Let's see what is in the cells"   
    Serial.print(Celldata[j].temp);
    Serial.print("  ");
    Serial.print(Celldata[j].extra);
    Serial.print(" = ");
    Serial.print(Celldata[j].cyc);
  }  // end of "for" loop
     // End of putting data into cells of [j]  0 through 5
     // At this point, Celldata[  ].temp, .num,  are each filled with something.

  Serial.println("End of filling up slots");

// Now let's extract data from the cells and try to form a string from them:

  for ( int  j = 0 ; j <= 4 ; j++) { // Celldata was defined for  5  cells for now
    Serial.println("In for loop reading data");

// < Here is where a runtime error occurs >
    
    cdt[j] = Celldata[j].temp  ;
    cyc[j] = Celldata[j].cyc   ;
    CDT[j] = 2 *   cyc[j];
    CYC[j] = 100 + cyc[j];
    Serial.println("read both pieces");
    Serial.print("cdt ");
    Serial.print(cdt[j]);
//    Serial.print(CDT[j]]);
    Serial.print(" cyc ");
//    Serial.print(cyc[j];
    Serial.print(CYC[j]);
    Serial.println(" end ");
//    adder = adder +  CDT[j] + CYC[j] + "," ;
    Serial.print("used  adder.  j = ");
    Serial.println(j);
                                 }  // end of for loop

  Serial.print("End of reading out cell data  ");
  Serial.println(adder);


//-----The portion below here works in the original.
//-----I am trying to create a similar string using my values taken from hte Celldat[ ].cyc  and  Celldata[  ].tmp

String payload_base =  "{\"command\": \"appendRow\", \
                    \"sheet_name\": \"TempSheet\", \
                       \"values\": ";
String payload = "";

  sheetTemp  = String("   ") + String(t) + String(t);
  sheetHumid = String("  ")  + String(h) + String(t);        
 
  sheetXXX  = "mcb XXX mcb";
  sheetYYY  = "mcb YYY mcb";
  sheetZZZ  = "mcb ZZX mcb";
  
 // orig:   payload = payload_base + "\"" + sheetTemp + "," + sheetHumid + "\"}";
// This mod works in the original.  Puts data into each column OK
    payload = payload_base + "\"" + sheetTemp + "," + sheetXXX + "," + sheetYYY + "," + sheetZZZ + "," + sheetHumid + "\"}";

 
}  // loopend -  I think!

The CDT and CYC arrays are declared as Strings
The cyc array is declared as byte
I am not clear what you are trying to do in the following 2 lines

    CDT[j] = 2 *   cyc[j];
    CYC[j] = 100 + cyc[j];
/Users/john/Documents/Arduino/sketch_dec25a/sketch_dec25a.ino: In function 'void loop()':
/Users/john/Documents/Arduino/sketch_dec25a/sketch_dec25a.ino:56:15: warning: 'j' is used uninitialized in this function [-Wuninitialized]
   String cdt[j];
               ^

That certainly looks like it could cause problems! Perhaps you wanted 5 elements?

Here are the results I get after using 5 instead of 'j' and using "j < 5" in the loops:

0  0 = 0extra= 0
1  1 = 1extra= 2
2  2 = 2extra= 4
3  0 = 0extra= 6
4  1 = 1extra= 8
End of filling up slots
In for loop reading data
read both pieces
0  0 end 
used  adder = 
In for loop reading data
read both pieces
1  1 end 
used  adder = 
In for loop reading data
read both pieces
2  2 end 
used  adder = 
In for loop reading data
read both pieces
3  0 end 
used  adder = 
In for loop reading data
read both pieces
4  1 end 
used  adder = 
End of reading out cell data  00,11,22,30,41,

Here is the code I used:

//  Copy for playing around with  -  original compiles OK.
// HVM Jan24 2020 = Started same as Jan 22.  Mods made from here.


// #include <ESP8266WiFi.h>
// #include "HTTPSRedirect.h"
// #include "DebugMacros.h"


float x ;
float h;
float t;
String datastring = "";


struct Celldata {
  uint8_t  temp;
  byte     cyc;
  byte     extra;  // here used for tests
} // For struct Celldata
Celldata[5];  // for now, try with only 5 slots. Eventually 60.


void setup() {


  delay(100);
  Serial.begin(115200);
  Serial.println();


}  // End of setup


void loop() {


  delay(1000);


  for (  int  j = 0 ; j < 5 ; j++)
  { // Celldata was defined for  5  cells for now
    Celldata[j].temp = j;
    Celldata[j].extra = ( 2 * j );
    delay(100);
    byte num = (j % 3)  ;  // thus num will always be 0, 1, or 2


    Celldata[j].cyc  = num  ;  // % = the modulo operator, Thus  num    will always be 0, 1. 2


    Serial.print(Celldata[j].temp);
    Serial.print("  ");
    Serial.print(num);
    Serial.print(" = ");
    Serial.print(Celldata[j].cyc);
    Serial.print("extra= ");
    Serial.println(Celldata[j].extra);


  }  // end of "for" loop
  // End of putting data into cells of [j]  0 through 5
  // At this point, Celldata[5].temp, .num, and .extra are all filled with something.


  String adder = "";  //


  String cdt[5];
  String cyc[5];


  Serial.println("End of filling up slots");


  for (byte j = 0 ; j < 5 ; j++) { // Celldata was defined for  15  cells for now
    Serial.println("In for loop reading data");
    cdt[j] = Celldata[j].temp  ;
    cyc[j] = Celldata[j].cyc   ;
    Serial.println("read both pieces");
    Serial.print(cdt[j]);
    Serial.print("  ");
    Serial.print(cyc[j]);
    Serial.println(" end ");


    adder = adder +  cdt[j] + cyc[j] + "," ;


    Serial.println("used  adder = ");


  }  // end of for loop


  Serial.print("End of reading out cell data  ");
  Serial.println(adder);




}  // loopend -  I think!

Thanks!
This seems to accomplish what I had been trying to do.
It seems so simple - I don't know why it hadn't come out in all the variations I had tried. (In fact, I thought I had tried declaring my variables as Strings as the first approach, and went to other variations after that.)

At any rate, I think I;m finally on the right road! I won't be able to actually test this for a few days, but I think that my problem us finally solved.

Thanks again

  • Matt