Pages: [1]   Go Down
Author Topic: Passing 2D array into a function, pointers?  (Read 1709 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I am trying to control an RGB strip, and to create some of the effects would like to store the brightness of each RGB leds information in a 2D matrix; 3 rows for colour and 160 (NUM of leds) for the columns. I have tried to write functions to handle shifting and displaying the information in the 2D array, but it seems I need to use pointers (maybe?) which I am not familiar with. So I have a few questions:
-Is an array the best way to handle this sort of information? (I think that it is only using 3*160 = 480 bytes of the 1024 on the ATmega168)
-Can I replace a whole column of an array at a time e.g. Array[][0] = Array[][1]? (as aposed to modifying each element in a column)
-How can I get pointers to work/fix the error message(s)? 

Here is the compile error:
shift_Update_etc.cpp: In function 'void loop()':
shift_Update_etc:65: error: invalid conversion from 'void*' to 'byte**'
shift_Update_etc:65: error: initializing argument 1 of 'void Update(byte**, int)'
shift_Update_etc:65: error: label 'ColourArray' used but not defined

Code:

#include <FastSPI_LED.h>
//SCK = pin 13. SD = pin 11. Pins 10 and 12 are not used.
#define NUM_LEDS 160
struct CRGB { unsigned char b; unsigned char g; unsigned char r; };
struct CRGB *leds;
#define PIN 4

//---Functions---

//Shift every element in the array by 1 to either the left or the right
void ArrayShift(byte** ColourArray, int N_LEDS, char Direction){
  if(Direction == 'R'){
    for(int i = N_LEDS - 1; i >= 0; i--){
      for(int j =0 ; j < 3; j++){
        ColourArray[j][i] = ColourArray[j][i-1];
      }
     }
    }
     else{
      for(int i = 0; i < N_LEDS - 1; i++){
        for(int j = 0; j < 3; j++){
         ColourArray[j][i] = ColourArray[j][i-1];
        }
     }
  }
}

//Updates the RGB strip with new information
void Update(byte** ColourArray, int N_LEDS){
  memset(leds, 0, NUM_LEDS * 3);
  for(int i = 0; i < N_LEDS; i++){
    leds[i].r = ColourArray[0][i];
    leds[i].g = ColourArray[1][i];
    leds[i].b = ColourArray[2][i];
  }
  delay(1); //Min time needed to write data to strip
  FastSPI_LED.show();
}

//---End functions---

void setup()
{
  FastSPI_LED.setLeds(NUM_LEDS);
  FastSPI_LED.setChipset(CFastSPI_LED::SPI_WS2801);

  FastSPI_LED.setPin(PIN);
  FastSPI_LED.setDataRate(2); // data rate 2 is good (default is 1)
  FastSPI_LED.init();
  FastSPI_LED.start();

  leds = (struct CRGB*)FastSPI_LED.getRGBData();
 
  memset(leds, 0, NUM_LEDS * 3);
  FastSPI_LED.show();
  byte ColourArray[3][NUM_LEDS]; //Setup the array
  for ( int i = 0; i<NUM_LEDS; i++){
    for(int j = 0; j<3; j++){
      ColourArray[j][i] = 255;
    }
  }
}


void loop() {
  Update(&&ColourArray, NUM_LEDS);
}

 
Logged

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

change &&ColourArray

to ColourArray

an array name without indexing is its pointer i.e 'byte**' ( arrays are pointers in disguise )

this wont work until
byte ColourArray[3][NUM_LEDS];
is declared in a scope loop() can see
it is currently only in scope during setup(), also if you make it global you will need to change the parameter names in the functions that use 'ColourArray' as a name
« Last Edit: May 06, 2012, 05:34:16 am by pYro_65 » Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If I declare 'byte ColourArray[3][NUM_LEDS]' outside both the setup() and loop() calls I get a new error (This is with the change to ColourArray):
shift_Update_etc.cpp: In function 'void loop()':
shift_Update_etc:66: error: cannot convert 'byte (*)[160]' to 'byte**' for argument '1' to 'void Update(byte**, int)'

I also changed the paramter names:
Code:
//Updates the RGB strip with new information
void Update(byte** CArray, int N_LEDS){
  memset(leds, 0, NUM_LEDS * 3);
  for(int i = 0; i < N_LEDS; i++){
    leds[i].r = CArray[0][i];
    leds[i].g = CArray[1][i];
    leds[i].b = CArray[2][i];
  }
  delay(1); //Min time needed to write data to strip
  FastSPI_LED.show();
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
cannot convert 'byte (*)[160]' to 'byte**'
There is a real big clue there as to how you need to change the function declaration.
Code:
void Update(byte* CArray[160], int N_LEDS)
{ // Down here where it belongs!
Logged

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

You can cast the variable to the pointer type.

Code:
Update( ( byte** ) ColourArray, NUM_LEDS );

or use an array in the parameter list

Code:
void Update(byte CArray[][NUM_LEDS], int N_LEDS){
  memset(leds, 0, NUM_LEDS * 3);
  for(int i = 0; i < N_LEDS; i++){
    leds[i].r = CArray[0][i];
    leds[i].g = CArray[1][i];
    leds[i].b = CArray[2][i];
  }
  delay(1); //Min time needed to write data to strip
  FastSPI_LED.show();
}
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I managed to get the code to compile using the code pYro_65 provided:
Update(byte CArray[][NUM_LEDS], int N_LEDS){

I did try the other suggestions, but got new error messages that I wasn't able to clearly decipher. 

I will test test it out soon, but thanks for the help in the meantime.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK. It works! I did have to use a 328 board though, the 168 stopped uploading halfway through (even if I decreased the NUM_LEDS to 1, so that the array would decrease in size) Is this a memory problem? The 168 will still take my old programs without the functions and array.

Here is the error that occurs midway through an upload to the 168 board:
avrdude: stk500_paged_load(): (a) protocol error, expect=0x14, resp=0x14
avrdude: stk500_cmd(): protocol error
Logged

Pages: [1]   Go Up
Jump to: