Arduino Forum

Using Arduino => Programming Questions => Topic started by: dcaroth on Mar 23, 2019, 07:31 am

Title: Changing the contents of an Array
Post by: dcaroth on Mar 23, 2019, 07:31 am
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?
Title: Re: Changing the contents of an Array
Post by: 6v6gt on Mar 23, 2019, 08:19 am
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;
Title: Re: Changing the contents of an Array
Post by: dcaroth on Mar 23, 2019, 08:44 am
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).
Title: Re: Changing the contents of an Array
Post by: UKHeliBob on Mar 23, 2019, 09:01 am
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);
}
Title: Re: Changing the contents of an Array
Post by: dcaroth on Mar 23, 2019, 09:12 am
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.
Title: Re: Changing the contents of an Array
Post by: UKHeliBob on Mar 23, 2019, 09:19 am
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);
}
Title: Re: Changing the contents of an Array
Post by: dcaroth on Mar 24, 2019, 04:10 am
Hmm, struct is a new one for me. I'll have to dig in and learn about that. Thanks.
Title: Re: Changing the contents of an Array
Post by: UKHeliBob on Mar 24, 2019, 08:13 am
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.