Pages: [1]   Go Down
Author Topic: My mind hit a brick wall - How to do int arrays with different length elements?  (Read 448 times)
0 Members and 1 Guest are viewing this topic.
Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 792
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

I need to do something like this:

Code:
static const uint8_t vectors[][] PROGMEM = {
    first element: 0x10,0x00,0xFF,0xFF
    second element: 0x0A,0x00,0x05,0x13,0x05,0x14,0x05,0x15,0xFF,0xFF
    third element: 0x09,0x00,0x05,0x13,0x05,0x14,0x05,0x15,0x06,0x18,0x06,0x21,0x05,0xFF,0xFF
   .....etc... (different number of bytes in each "element").
   96 in total
};

And I need to be able to access any element at random and either read it byte by byte, or else keep reading until the 0xFF,0xFF marker is found (prefer to use the string length).

Or, should I just create each one separately:

Code:
   vector[0] = 0x10,0x00,0xFF,0xFF;
    vector[1] = 0x0A,0x00,0x05,0x13,0x05,0x14,0x05,0x15,0xFF,0xFF;
    vector[2] = 0x09,0x00,0x05,0x13,0x05,0x14,0x05,0x15,0x06,0x18,0x06,0x21,0x05,0xFF,0xFF;
...etc.....

This should be easy, but I am just not seeing it. Any help will be appreciated.

-- Roger

(edit to add): It all has to be in PROGMEM, by the way.....
« Last Edit: February 15, 2013, 08:45:33 pm by Krupski » Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

UK
Offline Offline
Shannon Member
****
Karma: 222
Posts: 12520
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can't declare an array of arrays of different lengths. Instead of using an array of arrays, you need to use an array of pointers; each pointer would be initialised to point to an array holding your data values, which you have defined and initialised previously. If this lot is to be held in progmem then it's going to take considerable care (and trial and error) to make sure that you get the pointer dereferencing via progmem correct.

Here's a simple example to show the general idea, ignoring the progmem issue:

Code:
// uncompiled, untested
static const uint8_t alpha[] = { 0x10,0x00,0xFF,0xFF };
static const uint8_t beta[] = { 0x0A,0x00,0x05,0x13,0x05,0x14,0x05,0x15,0xFF,0xFF };
static const uint8_t gamma[] = { 0x09,0x00,0x05,0x13,0x05,0x14,0x05,0x15,0x06,0x18,0x06,0x21,0x05,0xFF,0xFF };
static const uint8_t *vectors[] = { alpha, beta, gamma };
// it probably needs a few more 'consts' in there too ...
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 792
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can't declare an array of arrays of different lengths. Instead of using an array of arrays, you need to use an array of pointers;

Yup. I see what you mean. No wonder I couldn't get it to work!  smiley

Thanks!

--- Roger
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 792
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can't declare an array of arrays of different lengths. Instead of using an array of arrays, you need to use an array of pointers; each pointer would be initialised to point to an array holding your data values, which you have defined and initialised previously. If this lot is to be held in progmem then it's going to take considerable care (and trial and error) to make sure that you get the pointer dereferencing via progmem correct.

Here's a simple example to show the general idea, ignoring the progmem issue:


Got it to work:

Code:
static const uint8_t char20[] PROGMEM = {
0x10,0x00,0xff,0xff
};
static const uint8_t char21[] PROGMEM = {
0x0a,0x00,0x05,0x1c,0x05,0x1b,0x05,0x1a,0x05,0x19,0x05,0x18,0x05,0x17,0x05,0x16,0x05,0x15,0x05,0x14,0x05,0x13,0x05,0x12,0x05,0x11,0x05,0x10,0x05,0x0f,0x05,0x0e,0x04,0x08,0x05,0x07,0x06,0x08,0x05,0x09,0xff,0xff
};
static const uint8_t char22[] PROGMEM = {
0x10,0x00,0x04,0x1c,0x04,0x1b,0x04,0x1a,0x04,0x19,0x04,0x18,0x04,0x17,0x04,0x16,0x04,0x15,0x0c,0x1c,0x0c,0x1b,0x0c,0x1a,0x0c,0x19,0x0c,0x18,0x0c,0x17,0x0c,0x16,0x0c,0x15,0xff,0xff
};
/////////////// lots deleted in the middle /////////////
static const uint8_t char7e[] PROGMEM = {
0x18,0x00,0x03,0x0d,0x03,0x0e,0x04,0x12,0x05,0x12,0x06,0x13,0x07,0x13,0x08,0x13,0x09,0x13,0x0a,0x12,0x0b,0x11,0x0c,0x11,0x0d,0x10,0x0e,0x0f,0x0f,0x0f,0x10,0x0e,0x11,0x0e,0x12,0x0e,0x13,0x0e,0x14,0x10,0x03,0x0f,0x03,0x10,0x04,0x11,0x05,0x11,0x06,0x12,0x07,0x12,0x08,0x12,0x09,0x12,0x0a,0x11,0x0b,0x10,0x0c,0x10,0x0d,0x0f,0x0e,0x0e,0x0f,0x0e,0x10,0x0d,0x11,0x0d,0x12,0x0d,0x13,0x0d,0x14,0x0e,0x14,0x0f,0x15,0x10,0x15,0x11,0x15,0x12,0x15,0x13,0xff,0xff
};

static const uint8_t char7f[] PROGMEM = {
0x0e,0x00,0x05,0x1c,0x04,0x1b,0x04,0x1a,0x03,0x19,0x03,0x18,0x03,0x17,0x03,0x16,0x04,0x15,0x05,0x15,0x06,0x14,0x07,0x14,0x08,0x14,0x09,0x14,0x0a,0x15,0x0a,0x16,0x0b,0x17,0x0b,0x18,0x0b,0x19,0x0b,0x1a,0x0a,0x1b,0x09,0x1b,0x08,0x1c,0x07,0x1c,0x06,0x1c,0xff,0xff
};

// pointers to all the strings
static const uint8_t *table[] PROGMEM = {
char20, char21, char22, char23, char24, char25, char26, char27, char28, char29, char2a, char2b, char2c, char2d, char2e, char2f,
///////////// deleted for clarity ////////////
char70, char71, char72, char73, char74, char75, char76, char77, char78, char79, char7a, char7b, char7c, char7d, char7e, char7f
};

To access each set of data:
pgm_read_byte(pgm_read_word(&table[character_code]) + offset into string);

I need a PROGMEM read word to get a pointer to the particular string of data, then use PROGMEM read byte of the word address + offset to get it all.

I can't get a string length, so I have to just blindly grab data until I hit 0xFF.

Oh well, clumsy but it works.

Thanks for the idea! It helped me on the right path.

-- Roger
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 285
Posts: 25632
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For reference, they're called Iliffe vectors.
Useful for odd-shaped arrays.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 64
Posts: 2100
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmmm, you guys seem to be making PROGMEM use really hard for yourselves. It can be far simpler, well in my opinion anyway.

I whipped up this and gave it a quick test on an uno:
Code:
struct A{
 
  char StrA[10];
  char StrB[15];
  char StrC[20];
 
} StrSet PROGMEM = {
  { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', '\0'},
  "0123456789abcd",
  { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', '\0'},
};

void setup(){
  char buffer[ 20 ];
 
  Serial.begin( 9600 );
  strcpy_P( buffer, StrSet.StrA );
  Serial.println( buffer );
 
  strcpy_P( buffer, StrSet.StrB );
  Serial.println( buffer );
 
  strcpy_P( buffer, StrSet.StrC );
  Serial.println( buffer );   
}

void loop(){ return; }

Hopefully it helps smiley
Logged


Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13471
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I can't get a string length, so I have to just blindly grab data until I hit 0xFF.
Oh well, clumsy but it works.
You could add an additional array holding the lengths... (are as PASCAL used to do, store the length in element
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: [1]   Go Up
Jump to: