Go Down

Topic: My mind hit a brick wall - How to do int arrays with different length elements? (Read 503 times) previous topic - next topic

Krupski

Hi all,

I need to do something like this:

Code: [Select]

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: [Select]

   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.....
Gentlemen may prefer Blondes, but Real Men prefer Redheads!

PeterH

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: [Select]

// 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 ...
I only provide help via the forum - please do not contact me for private consultancy.

Krupski


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!  :)

Thanks!

--- Roger
Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Krupski


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: [Select]

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
Gentlemen may prefer Blondes, but Real Men prefer Redheads!

AWOL

For reference, they're called Iliffe vectors.
Useful for odd-shaped arrays.
"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.

pYro_65

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: [Select]
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 :)

robtillaart

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
Rob Tillaart

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

Go Up