Go Down

Topic: Changing the contents of an Array (Read 233 times) previous topic - next topic

dcaroth

Asking for help,

I'm really trying to comprehend Arrays. I just started messing with them a few weeks ago.
Im wanting to create a sketch that will read a couple of arrays and create a single string to be passed to a function. I've developed the following that does just that:

Code: [Select]
#define TAGS(x) (sizeof(x) / sizeof(x[0]))
#define VALS(x) (sizeof(x) / sizeof(x[0]))
const char *tag[] = {"State= ", ", Bat(%)= ", ", Bat(mV)= ", ", RSSI= ", ", SMS#= ", ", Lock= ", ", Light= "};
char *val[] = {"1", "100", "4217", "22", "11", "unlocked", "OFF"};
char message[100];
int i;
int pbat = 97;

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

void loop() {
  getStats();
  delay(5000);
}

void getStats(){
  strcpy(message, "");
  for(i=0; i<TAGS(tag); i++){
    strcat(message, tag[i]);
    strcat(message, val[i]);
  }
  Serial.println(message);
}

The out is as expeted below:
Code: [Select]

State= 1, Bat(%)= 100, Bat(mV)= 4217, RSSI= 22, SMS#= 11, Lock= unlocked, Light= OFF


But I need to change the contents of the 2nd Array based on changing inputs of my Arduino UNO. The problem I'm having is changing int's to char's and then writting them to the 2nd Array. The following code works for doing this but it contains Strings, and I'm trying to avoid using Strings as much as possible.
Code: [Select]

char cpbat[4];
String str;
str = String(pbat);
str.toCharArray(cpbat, 4);
val[1] = cpbat;

The output is as expected below:
Code: [Select]
State= 1, Bat(%)= 97, Bat(mV)= 4217, RSSI= 22, SMS#= 11, Lock= unlocked, Light= OFF


The following line of code will write to the array but will only write the contents to element 1 (index 0) of the array. I've tried defining which index to write it to but can't find a way so that it will complie without error:
Code: [Select]
itoa(pbat, *val, 10);
The output is as follows:
Code: [Select]
State= 97, Bat(%)= 100, Bat(mV)= 4217, RSSI= 22, SMS#= 197, Lock= , Light= OFF


The following line of code will write to the correct index that I define but again it will also always stuff the contents into element 1 (index 0) of the array, even when I tell it to write the contents to element 6 (index 5). It seems to corrupt other elements as well. Example:
Code: [Select]

val[6] = itoa(pbat, *val, 10);

The output is as follows:
Code: [Select]
State= 97, Bat(%)= 100, Bat(mV)= 4217, RSSI= 22, SMS#= 197, Lock= , Light= 97


I've tried so many variations to write what I need into the 2nd Array but to no avail and I'm starting to repeat my self with attempts. I'm really hoping this can be accomplished without using Strings.

Any ideas?

6v6gt

Try this:
char cpbat[4]  ;  // ensure this buffer  is big enough for the value plus 1 for the end marker
itoa(pbat, cpbat, 10); 
val[1] = cpbat;

dcaroth

OMG that works! I was so close to figuring this out on my own but yet so far away. But most importantly I can understand this after seeing it. I've been reading two different books and Google seraching for two days on this one task of stuffing an int into that array at the correct locatoin.

Thank you 6v6gt!

P.S.- Like your avatar. Transistors just can't match it (yet).

UKHeliBob

Or take a different approach and use an array of ints that you can change at will

Code: [Select]
char outBuffer[100];

int val[] = {1, 100, 4217, 22, 11, LOW, LOW};

void setup()
{
  Serial.begin(115200);
  printData();
  val[3] = 45;
  val[5] = HIGH;
  val[6] = HIGH;
  printData();
}

void loop()
{
}

void printData()
{
  sprintf(outBuffer, "State = %d, Bat(%%) = %d, Bat(mV) = %d, RSSI = %d, SMS# = %d, Lock = %s, Light = %s",
          val[0], val[1], val[2], val[3], val[4], (val[5] == LOW) ? "unlocked" : "locked", (val[6] == LOW) ? "OFF" : "ON");
  Serial.println(outBuffer);
}
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

dcaroth

Yes I agree but only 4 of the elements in the 2nd array will be integers. I guess I could create a 3rd array and see if it's much of a difference in memory usage or not. It just seemed easier and quicker to read in the two different arrays in sequential order to build a single string to pass to a function.

UKHeliBob

Or don't use an array at all.  Use a struct and give the data meaningful names instead of an anonymous array index
Code: [Select]

struct dataLayout
{
  byte state = 1;
  byte batPercent = 100;
  int batMv  = 4217;
  byte rssi = 22;
  byte sms = 11;
  char * lock = "locked";
  char * light = "ON";
} data;

char outBuffer[100];

void setup()
{
  Serial.begin(115200);
  printData();
  data.light = "OFF";
  printData();
  data.rssi = 23;
  data.batMv = 1234;
  data.lock = "unlocked";
  printData();
}

void loop()
{
}

void printData()
{
  sprintf(outBuffer, "State = %d, Bat(%%) = %d, Bat(mV) = %d, RSSI = %d, SMS# = %d, Lock = %s, Light = %s",
          data.state, data.batPercent, data.batMv, data.rssi, data.sms, data.lock, data.light);
  Serial.println(outBuffer);
}
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

dcaroth

Hmm, struct is a new one for me. I'll have to dig in and learn about that. Thanks.

UKHeliBob

Hmm, struct is a new one for me. I'll have to dig in and learn about that. Thanks.
They can be useful but it is a case of horses for courses.  Structs are ideal for holding related data of different types.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Go Up