Arduino array of strings (char arrays)

Discussion in 'Programmer's Corner' started by djsfantasi, Jun 2, 2014.

  1. djsfantasi

    Thread Starter AAC Fanatic!

    Apr 11, 2010
    2,810
    834
    I'm trying to figure out char arrays on the Arduino. I have a two dimensional array containing messages that I want to send out the serial port. One entry looks like:

    Code ( (Unknown Language)):
    1. MoveCommand[5][20]="#0P1500T3000"
    And to send it to the serial port, would the syntax be:

    Code ( (Unknown Language)):
    1. serial.println MoveCommand[5][];
    :confused:?

    I don't have the Arduino yet to test, so I'm asking here
     
  2. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,394
    497
    The references only show examples with one dimensional arrays.

    However. Since you have multiple messages (strings), you can do array of strings. See the last example on this page:
    http://arduino.cc/en/Reference/String
     
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    Three basic things: If your array (or string) is not a constant array then it must be stored twice, once in ROM and once in RAM. Making it constant takes out the RAM requirement, but you may need to copy it first to a RAM array to use it.

    Next, unless all of your 5 times 20 = 100 arrays are the same length you may again wasting space. So if they are of differing lengths make the array not of strings but of pointers to strings. Depending on the data that may be smaller. (The tradeoff is you need an additional 100 pointer locations minus the max string length differences.)

    Last, if the strings are all the same length, don't store as strings and you'll save 100 char locations just used to hold the trailing zero of each string.
     
  4. djsfantasi

    Thread Starter AAC Fanatic!

    Apr 11, 2010
    2,810
    834
    The array is defined as [64][20], so isn't that two dimensional?

    Is the serial.println example correct for printing the fifth entry of the above array?
     
    Last edited: Jun 3, 2014
  5. djsfantasi

    Thread Starter AAC Fanatic!

    Apr 11, 2010
    2,810
    834
    Ernie,

    The array is stored as constants.

    Thanks for the tips on conserving memory. It isn't an issue now, but they will be helpful in the future.
     
  6. MrChips

    Moderator

    Oct 2, 2009
    12,447
    3,363
    char ch[64][20]

    is two dimensional array of characters, i.e. 64 strings of 20 characters.
     
  7. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    If the array is constant then how can
    Code ( (Unknown Language)):
    1. MoveCommand[5][20]="#0P1500T3000"
    not generate an error? Note I do not use the Arduino, I am interpeting this as C code.

    And that has room for 64 strings of 19 characters each, assuming a string needs the trailing zero (see my note above).
     
  8. sirch2

    Well-Known Member

    Jan 21, 2013
    1,008
    351
    off the top of my head is it not more like this

    Code ( (Unknown Language)):
    1.  
    2. char ch[64][21]; //extra char for string terminator
    3. strcpy(ch[0], "blah");
    4. strcpy(ch[1], "blah blah");
    5.  
    6. serial.println(ch[0]);
    7.  
    8.  
    Although as others have said if the Strings are constants there are probably more memory efficient ways of handling this.
     
  9. djsfantasi

    Thread Starter AAC Fanatic!

    Apr 11, 2010
    2,810
    834
    Ok, I was misleading in my initial post. In my example of one entry, I wasn't illustrating assignment; I meant "MoveCommand[5][20] has the value of "#0P1500T3000"

    My actual code looks like this extract...
    Code ( (Unknown Language)):
    1.  
    2. const char* MoveCommand[][60]={
    3. "#0P1500#1P1500#2P1000#3P570#4P1500#5P2400#6P510#8P1500#9P1500#10P1500#11P1400T1000",
    4. "#2P1100",
    5. "#0P2000*#1P1100*T100",
    6. "#2P750",
    7. etc... for up to 60 entries
    8. }
    9.  
    So to print oout the ith entry, is the syntax:
    Code ( (Unknown Language)):
    1. serial.println MoveCommand[i][];[/i]

    :confused:
     
  10. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    Code ( (Unknown Language)):
    1. const char* MoveCommand[][60]={
    2. "#0P1500#1P1500#2P1000#3P570#4P1500#5P2400#6P510#8P1500#9P1500#10P1500#11P1400T1000",
    3. "#2P1100",
    4. "#0P2000*#1P1100*T100",
    5. "#2P750",
    6. etc... for up to 60 entries
    7. }
    8.  
    If you have 60 strings of variable length you need a vector (a one dimensional array) of 60 pointers to see them all. It is a vector as the length of the referenced object (the string) is irrlevant as to where the string is.

    Yes the length is importaint as the lengths of the strings listed are 82, 7, 21 and 7 chars respectively, and you only wish to print that many each time. By using the quotes in the definition the Arduino compiler puts that zero in for you so these strings will work with functions such as serial.println

    I do note your 1st string exceeds your expectation of 60 chars max. But no bother as you have an array of pointers so the 2nd dimension is unnecessary and also incorrect.

    Something like this would be preferable:
    Code ( (Unknown Language)):
    1. const char* MoveCommand[]={
    2. "#0P1500#1P1500#2P1000#3P570#4P1500#5P2400#6P510#8P1500#9P1500#10P1500#11P1400T1000",
    3. "#2P1100",
    4. "#0P2000*#1P1100*T100",
    5. "#2P750",
    6. etc... for up to 60 entries
    7. }
    8.  
    See example #2 here

    And to print this out:
    Code ( (Unknown Language)):
    1. serial.println MoveCommand[i];[/i]


    Again, DO NOTE I have never programmed this machine. I just read a user's guide and apply my knowedge of C.
     
    djsfantasi likes this.
  11. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,394
    497
    I am talking about Arduino. All the Arduino examples I have looked have one dimensional arrays. I am not Arduino guru so I don't know all the ins and outs of Arduino arrays, but, at this point in time, I have a feeling that Arduino only support one dimensional arrays.
    So.
    You can do:
    * try using two dimensional array when you get the board and find out if they work
    * e-mail Arduino software development team and ask them if their software support arrays with more than one dimension
    * ask on Arduino forums, there must be people who already tried it
     
  12. djsfantasi

    Thread Starter AAC Fanatic!

    Apr 11, 2010
    2,810
    834
    The code compiles fine. Comments from the Arduino forum led me to this solution. I asked here because I know of members who are Arduino experts. My confusion stems from referencing the individual strings/messages.

    I can't order the board right now, as I'm unemployed but have been coding in the IDE.
     
    Last edited: Jun 3, 2014
  13. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    A quick google of "arduino two dimensional array" yeilds positive results.

    Gee, I sure do wish one of dem experts would wander by and add something. :D
     
    djsfantasi likes this.
  14. djsfantasi

    Thread Starter AAC Fanatic!

    Apr 11, 2010
    2,810
    834
    So I successfully downloaded a trial Arduino simulator and wrote a test sketch. Thank you, ErnieM. Your comments were right on. I just was so dense, I couldn't see it until I had written code which could be executed.

    As I understand it, MoveCommand is an array of pointers, which in turn points to my messages. There is no need for the second dimension. Defining them as constant keeps them in flash memory, leaving SRAM available for dynamic data structures and variables.

    Having said that, to print out the ith message, I'd code:
    Code ( (Unknown Language)):
    1. Serial.println(MoveCommand[i]);[/i]
     
  15. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    I think he's got it !!! :D
     
  16. djsfantasi

    Thread Starter AAC Fanatic!

    Apr 11, 2010
    2,810
    834
    Update: I almost had it. Defining them as constant didn't put them into program memory :confused: There is an Arduino library, PGMSPACE, that extends data types so they can be stored in program space. The table cannot be used directly (it's rows have to be copied from program space into RAM when needed) but as in my program, there is only one place the tables values are needed, it is easy to use!

    I ran into another problem where I am assigning values to a table (the code is automatically generated in an external program). It was to a set of global integer arrays. I learned that definition and initialization can occur in the global definition section, but that assignment must take place in a function. I did it in setup. No thanks to the compiler error messages!

    Thanks to all and a special thanks to ErnieM.
     
Loading...