Struct with * to struct with * to const 3d int array

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok so I have a bunch of RGB leds and a struct to define the port, pins, brightness of each color, timing things, and pointer to Sequence structure.

The sequence structure is how the leds will light up. It contains a *** to const int [][][]. In my later code I try to access that array like so:

const struct Sequence_Struct *Seq;
Seq = leds[i].Sequence;
if(leds[i].transition_time > Seq->Sequence[i][leds[i].index][4]) ....

This does not work, however if instead I use the int [][][] straight up it does so

if(leds[i].transition_time > SequenceLED1[i][leds[i].index][4])....

does work.

Below is how I define all the structures and const int [][][] in a header file.

//The sequences are read as follows, {R,G,B,time to keep values at that level, time to transition into next level}
const int SequenceLED1_length = 6;
const int SequenceLED1[2][6][5] =
{
//LED 1
{{0,65,0,1000,500},
{65,65,65,1000,500},
{65,0,65,1000,500},
{0,65,65,1000,500},
{65,0,0,1000,500},
{65,65,0,1000,500}},
///LED 2
{{0,0,0,1000,1000},
{65,65,65,1000,1000},
{0,0,0,1000,1000},
{65,65,65,1000,1000},
{0,0,0,1000,1000},
{65,65,65,1000,1000}}
};


//Here We define the sequences for each LED 
struct Sequence_Struct
{
	const int Sequence_length;
	const int ***Sequence;
} Seq[2] = 
{
{6,(const int ***)SequenceLED1},
{6,(const int ***)SequenceLED1}
};

//Defenition For each LED
struct RGB_LED_Struct{
	//brightness
	unsigned char red;
	unsigned char green;
	unsigned char blue;
	//hardware
	volatile uint8_t * port;
	char r_pin,g_pin,b_pin;
	//timing
	int index;
	int time_left;
	int transition_time;
	//the sequence currently playing
	const struct Sequence_Struct *Sequence;
} leds[num_leds];

I then call led_init that does the following:

void leds_init()
{
	leds[0].red = SequenceLED1[0][0][0];
	leds[0].green = SequenceLED1[0][0][1];
	leds[0].blue = SequenceLED1[0][0][2];
	leds[0].port = &PORTB;
	leds[0].r_pin = 0;
	leds[0].g_pin = 4;
	leds[0].b_pin = 2;
	leds[0].index=0;
	leds[0].time_left=SequenceLED1[0][0][3];
	leds[0].transition_time = 0;
	leds[0].Sequence = &Seq[0];

	leds[1].red = SequenceLED1[1][0][0];
	leds[1].green = SequenceLED1[1][0][1];
	leds[1].blue = SequenceLED1[1][0][2];
	leds[1].port = &PORTB;
	leds[1].r_pin = 1;
	leds[1].g_pin = 3;
	leds[1].b_pin = 5;
	leds[1].index=0;
	leds[1].time_left=1000;
	leds[1].transition_time = 0;
	leds[1].Sequence = &Seq[0];
}

Can someone explain what am I doing wrong when trying to get access to the const int [][][] using

if(leds[i].transition_time > Seq->Sequence[i][leds[i].index][4])....

Am i incorrectly assigning the pointer to the array ?

Last Edited: Tue. Jan 25, 2011 - 01:01 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Am i incorrectly assigning the pointer to the array ?
Yes. The compiler has no idea what the size of the array is, so it can't possibly find the correct element.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So is it possible to have a pointer to constant 3d array and retrieve the correct elements ??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As long as the compiler knows the size of the second two dimensions.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ooops, my bad i think i pasted the wrong line of code at the end. The array is defined as const int SequenceLED1[2][6][5]{...data...}; So the compiler does know the dimensions. When I use SequenceLED1[i][leds[i].index][4] to access the element the code does work. When I try to using the pointer to this const array from structure Sequence to access the same element it does not. What I want is to have multiple const int [][][] with known dimensions defined in header files and then LED structure having a pointer to Sequence structure which has a pointer to one of these arrays.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
So the compiler does know the dimensions.
But when you do this:

 const int ***Sequence

then the compiler has no clue that this is referring to an array at all, much less one with a specific size.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So there is no way to use a pointer to a 3d array and specify the dinesions ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does it even compile when you use the pointer?

You define Seq as a pointer...

const struct Sequence_Struct *Seq; 

But also have it defined as an array...

//Here We define the sequences for each LED
struct Sequence_Struct
{
   const int Sequence_length;
   const int ***Sequence;
} Seq[2]
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think this probably gives enough to work on. In the simulator it outputs the value 65 to PORTB. Which is this value - that is element [1][3][2] in the array:

Quote:
///LED 2
{
{0,0,0,1000,1000},
{65,65,65,1000,1000},
{0,0,0,1000,1000},
{65,65,65,1000,1000},
{0,0,0,1000,1000},
{65,65,65,1000,1000}

#include  

int data[2][6][5] = { 
//LED 1 
	{
		{0,65,0,1000,500}, 
		{65,65,65,1000,500}, 
		{65,0,65,1000,500}, 
		{0,65,65,1000,500}, 
		{65,0,0,1000,500}, 
		{65,65,0,1000,500}
	}, 
///LED 2 
	{
		{0,0,0,1000,1000}, 
		{65,65,65,1000,1000}, 
		{0,0,0,1000,1000}, 
		{65,65,65,1000,1000}, 
		{0,0,0,1000,1000}, 
		{65,65,65,1000,1000}
	} 
}; 

volatile int (*pdat)[2][6][5];

int main (void) { 
	pdat = (void *)&data[0][0][0];
	PORTB = (*pdat)[1][3][2];
	while(1);
}

(and, yes, I copped out with a (void*) cast - ho hum ;-))

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks everyone :)

This is how I can retrieve the data out of the const int SequenceLED1[2][5][6] array:

//Here We define the sequences for each LED 
struct Sequence_Struct
{
	const int Sequence_length;
	const int *Sequence;
}Sequences[2] = 
{
{6,&SequenceLED1[0][0][0]},
{6,&SequenceLED1[0][0][0]}
};

//And this is how to get the data
int GetSequenceData(struct Sequence_Struct *Sequence,int i,int j,int k)
{
	int (*data)[num_leds][Sequence->Sequence_length][5] = Sequence->Sequence;
	return (*data)[i][j][k];
}