Passing a 2-Dim array in to a function library

Hello,

I'm making a library for driving a 8x8 bi-colour LED Matrix. The matrix is hooked on the arduino using three 74HC595 shift registers. Problem is I can't pass the variable to my library.

Matrix.h

/*
  Matrix.cpp - Library for driving a led matrix.
  Created by Glenn Kerselaers, Februari 6, 2014.
  Released into the public domain.
*/

#ifndef Matrix_h
#define Matrix_h

#include "Arduino.h"
#include <FrequencyTimer2.h>
#include <Shifter.h>

class Shifter;
class FrequencyTimer2;

class Matrix
{
  public:
    Matrix(int cathodePins[8], int greenPins[8], int redPins[8], int greenScreen[][8], int redScreen[][8]);
    void clear();
    void display();
    void writeGreen(int,int,int);
	void writeRed(int,int,int);
   private:
     int _cathodePins[8];
     int _greenPins[8];
     int _redPins[8];
     int _greenScreen[][8];
     int _redScreen[][8];
};
#endif

Matrix.cpp

/*
  Matrix.cpp - Library for driving a led matrix.
  Created by Glenn Kerselaers, Februari 6, 2014.
  Released into the public domain.
*/

#include <FrequencyTimer2.h>
#include <Shifter.h>
#include "Arduino.h"
#include "Morse.h"

Matrix::Matrix(int cathodePins[8], int greenPins[8], int redPins[8], int greenScreen[][8], int redScreen[][8])
{
  for(int i = 0; i < 8; i++){
    shifter.setPin(cathodePins[i], LOW);
    shifter.setPin(greenPins[i],   LOW);
    shifter.setPin(redPins[i],     LOW);
  }
  Matrix::clear();

  FrequencyTimer2::disable();
  FrequencyTimer2::setPeriod(2000);
  FrequencyTimer2::setOnOverflow(Matrix::display);

  _cathodePins = cathodePins;
  _greenPins   = greenPins;
  _redPins     = redPins;
  _greenScreen = greenScreen;
  _redScreen   = redScreen;
}

void Matrix::writeGreen(int x, int y, boolean value){
	_greenScreen[x][y] = value;
}

void Matrix:writeRed(int x, int y, boolean value){
	_redScreen[x][y] = value;
	
}

void Matrix::clear(){
  for(int i = 0; i < 8; i++){
    for(int ii = 0; ii < 8; ii++){      
      _greenScreen[i][ii] = 0;
      _redScreen[i][ii]   = 0;
    }
  }
}

void Matrix::display(){
  for(int row = 0; row < 8; row++){
    shifter.setPin(_cathodePins[row], LOW);
    for(int col = 0; col < 8; col++){
      shifter.setPin(_greenPins[col], _greenScreen[col][row]);
      shifter.setPin(_redPins[col] ,  _redScreen[col][row]);
    }
    shifter.write();
    shifter.setPin(_cathodePins[row], HIGH);
  }
}

Example code

#include <Matrix.h>
#include <FrequencyTimer2.h>
#include <Shifter.h>

#define SER_Pin 4 // 14 SER_IN
#define RCLK_Pin 3 // 12 L_CLOCK
#define SRCLK_Pin 2 // 11 CLOCK
#define NUM_REGISTERS 3 // how many registers are in the chain
//initaize shifter using the Shifter library
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS); 

const int CATHODEPINS[8] = {
  4,5,6,7,0,1,2,3};
const int GREENPINS[8]   = {
  19,18,17,16, 23,22,21,20};
const int REDPINS[8]     = {
  12,13,14,15,8,9,10,11};

int GREENSCREEN[8][8];
int REDSCREEN[8][8];

Matrix matrix(CATHODEPINS,GREENPINS,REDPINS,GREENSCREEN,REDSCREEN);

void setup(){
}

void loop(){
  writeGreen(0,0,1);
  writeRed(7,7,1);
}

Compile error

Example_Matrix:22: error: invalid conversion from 'const int*' to 'int*'
Example_Matrix:22: error: initializing argument 1 of 'Matrix::Matrix(int*, int*, int*, int (*)[8], int (*)[8])'
Example_Matrix:22: error: invalid conversion from 'const int*' to 'int*'
Example_Matrix:22: error: initializing argument 2 of 'Matrix::Matrix(int*, int*, int*, int (*)[8], int (*)[8])'
Example_Matrix:22: error: invalid conversion from 'const int*' to 'int*'
Example_Matrix:22: error: initializing argument 3 of 'Matrix::Matrix(int*, int*, int*, int (*)[8], int (*)[8])'
Example_Matrix.ino: In function 'void loop()':
Example_Matrix:28: error: 'writeGreen' was not declared in this scope
Example_Matrix:29: error: 'writeRed' was not declared in this scope

Example_Matrix:22: error: invalid conversion from 'const int*' to 'int*'

This one should be pretty obvious. You have a const int array that you are trying to pass to a method that does not expect a const array.

Either loose the const on the defined array or make the function expect a const array.

Example_Matrix:28: error: 'writeGreen' was not declared in this scope
Example_Matrix:29: error: 'writeRed' was not declared in this scope

So, define them.

Perhaps you meant

matrix.writeGreen(0,0,1);

You can't pass constants to a function that doesn't promise to leave them alone. Declare the arguments const in the constructor so the compiler can be assured your library won't muck with them.

To use the member functions writeRed() and writeGreen() you have to say what object they are a member of:

void loop() {
  matrix.writeGreen(0,0,1);
  matrix.writeRed(7,7,1);
}

I was a bit too quick. The error I received is strange to me. I followed the http://arduino.cc/en/Hacking/LibraryTutorial tutorial and did everything they said.

My Code

#include <Matrix.h>
#include <FrequencyTimer2.h>
#include <Shifter.h>

#define SER_Pin 4 // 14 SER_IN
#define RCLK_Pin 3 // 12 L_CLOCK
#define SRCLK_Pin 2 // 11 CLOCK
#define NUM_REGISTERS 3 // how many registers are in the chain
//initaize shifter using the Shifter library
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS); 

int CATHODEPINS[8] = {
  4,5,6,7,0,1,2,3};
int GREENPINS[8]   = {
  19,18,17,16, 23,22,21,20};
int REDPINS[8]     = {
  12,13,14,15,8,9,10,11};

int GREENSCREEN[8][8];
int REDSCREEN[8][8];

Matrix matrix(CATHODEPINS,GREENPINS,REDPINS,GREENSCREEN,REDSCREEN);

void setup(){
}

void loop(){
  matrix.writeGreen(0,0,1);
  matrix.writeRed(7,7,1);
}

error code

C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:10:19: error: Morse.h: No such file or directory
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:12: error: 'Matrix' has not been declared
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:12: error: ISO C++ forbids declaration of 'Matrix' with no type
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp: In function 'int Matrix(int*, int*, int*, int (*)[8], int (*)[8])':
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:15: error: 'shifter' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:19: error: 'Matrix' is not a class or namespace
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:23: error: 'Matrix' is not a class or namespace
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:25: error: '_cathodePins' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:26: error: '_greenPins' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:27: error: '_redPins' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:28: error: '_greenScreen' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:29: error: '_redScreen' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp: At global scope:
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:32: error: 'Matrix' is not a class or namespace
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp: In function 'void writeGreen(int, int, boolean)':
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:33: error: '_greenScreen' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp: At global scope:
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:36: error: function definition does not declare parameters
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:40: error: 'Matrix' is not a class or namespace
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp: In function 'void clear()':
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:43: error: '_greenScreen' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:44: error: '_redScreen' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp: At global scope:
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:49: error: 'Matrix' is not a class or namespace
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp: In function 'void display()':
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:51: error: 'shifter' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:51: error: '_cathodePins' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:53: error: '_greenPins' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:53: error: '_greenScreen' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:54: error: '_redPins' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:54: error: '_redScreen' was not declared in this scope

C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT_Arduino Project Folder\libraries\Matrix\Matrix.cpp:10:19: error: Morse.h: No such file or directory

Neither you nor anyone else can hide the use of a library from the sketch. Include Morse.h in the sketch.

#include <Shifter.h>

class Shifter;

One of them is unnecessary.

Your sketch needs to include Matrix.h, too.

I really can't find the problem. It's the first time I make my own library.

My test code:

#include <FrequencyTimer2.h>
#include <Matrix.h>
#include <Shifter.h>

#define SER_Pin 4 // 14 SER_IN
#define RCLK_Pin 3 // 12 L_CLOCK
#define SRCLK_Pin 2 // 11 CLOCK
#define NUM_REGISTERS 3 // how many registers are in the chain
//initaize shifter using the Shifter library
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS); 

int CATHODEPINS[8] = {
  4,5,6,7,0,1,2,3};
int GREENPINS[8]   = {
  19,18,17,16, 23,22,21,20};
int REDPINS[8]     = {
  12,13,14,15,8,9,10,11};
Matrix matrix(CATHODEPINS,GREENPINS,REDPINS);

void setup(){
}

void loop(){
  matrix.writeGreen(0,0,1);
  matrix.writeRed(7,7,1);
}

Matrix.cpp

/*
  Matrix.cpp - Library for driving a led matrix.
  Created by Glenn Kerselaers, Februari 6, 2014.
  Released into the public domain.
*/

#include "FrequencyTimer2.h"
#include "shifter.h"
#include "Matrix.h"
#include "Arduino.h"

Matrix::Matrix(int cathodePins[8], int greenPins[8], int redPins[8])
{
class Shifter;
class Matrix;
class FrequencyTimer2;

  for(int i = 0; i < 8; i++){
    shifter::setPin(cathodePins[i], LOW);
    shifter::setPin(greenPins[i],   LOW);
    shifter::setPin(redPins[i],     LOW);
  }
  Matrix::clear();

  FrequencyTimer2::disable();
  FrequencyTimer2::setPeriod(2000);
  FrequencyTimer2::setOnOverflow(Matrix::display);

  _cathodePins = cathodePins;
  _greenPins   = greenPins;
  _redPins     = redPins;
}

void Matrix::writeGreen(int x, int y, boolean value){
	_greenScreen[x][y] = value;
}

void Matrix::writeRed(int x, int y, boolean value){
	_redScreen[x][y] = value;
}

void Matrix::clear(){
  for(int i = 0; i < 8; i++){
    for(int ii = 0; ii < 8; ii++){      
      _greenScreen[i][ii] = 0;
      _redScreen[i][ii]   = 0;
    }
  }
}

void Matrix::display(){
  for(int row = 0; row < 8; row++){
    shifter.setPin(_cathodePins[row], LOW);
    for(int col = 0; col < 8; col++){
      shifter::setPin(_greenPins[col], _greenScreen[col][row]);
      shifter::setPin(_redPins[col] ,  _redScreen[col][row]);
    }
    shifter::write();
    shifter::setPin(_cathodePins[row], HIGH);
  }
}

Matrix.h

/*
  Matrix.cpp - Library for driving a led matrix.
  Created by Glenn Kerselaers, Februari 6, 2014.
  Released into the public domain.
*/

#ifndef Matrix_h
#define Matrix_h

#if ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

#include "FrequencyTimer2.h"
#include "Shifter.h"
#include "Matrix.h"

class Shifter;
class FrequencyTimer2;

class Matrix
{
  public:
    Matrix(int cathodePins[8], int greenPins[8], int redPins[8]);
    void clear();
    void display();
    void writeGreen(int,int,int);
	void writeRed(int,int,int);
   private:
     int _cathodePins[8];
     int _greenPins[8];
     int _redPins[8];
     int _greenScreen[][8];
     int _redScreen[][8];
};
#endif

keywords.txt

/*
  Matrix.cpp - Library for driving a led matrix.
  Created by Glenn Kerselaers, Februari 6, 2014.
  Released into the public domain.
*/

Matrix		KEYWORD1
clear		KEYWORD2
display		KEYWORD2
writeGreen	KEYWORD2
writeRed	KEYWORD2

Remaining error

C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp: In constructor 'Matrix::Matrix(int*, int*, int*)':
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:15: error: 'shifter' has not been declared
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:16: error: 'shifter' has not been declared
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:17: error: 'shifter' has not been declared
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:23: error: no matching function for call to 'FrequencyTimer2::setOnOverflow(<unresolved overloaded function type>)'
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\FrequencyTimer2/FrequencyTimer2.h:61: note: candidates are: static void FrequencyTimer2::setOnOverflow(void (*)())
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:25: error: incompatible types in assignment of 'int*' to 'int [8]'
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:26: error: incompatible types in assignment of 'int*' to 'int [8]'
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:27: error: incompatible types in assignment of 'int*' to 'int [8]'
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp: At global scope:
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:30: error: prototype for 'void Matrix::writeGreen(int, int, boolean)' does not match any in class 'Matrix'
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\/Matrix.h:26: error: candidate is: void Matrix::writeGreen(int, int, int)
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:34: error: prototype for 'void Matrix::writeRed(int, int, boolean)' does not match any in class 'Matrix'
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\/Matrix.h:27: error: candidate is: void Matrix::writeRed(int, int, int)
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp: In member function 'void Matrix::display()':
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:49: error: 'shifter' was not declared in this scope
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:51: error: 'shifter' is not a class or namespace
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:52: error: 'shifter' is not a class or namespace
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:54: error: 'shifter' is not a class or namespace
C:\Users\Glenn Kerselaers\SkyDrive\DEVELOPMENT\_Arduino Project Folder\libraries\Matrix\Matrix.cpp:55: error: 'shifter' is not a class or namespace
Matrix::Matrix(int cathodePins[8], int greenPins[8], int redPins[8])
{
class Shifter;
class Matrix;
class FrequencyTimer2;

What do you think the last 3 lines are doing?

Hint: NOTHING.

#include "shifter.h"

Why is Shifter defined in shifter.h? The name case should match. Only the idiots that brought you Windows are stupid enough to think that case doesn't matter.

    shifter::setPin(cathodePins[i], LOW);

Is setPin defined as static? I can't imagine that that is correct. If the class is called Shifter, why are you using shifter as the scope?

PaulS, thank you for your help. I understand I may frustrate you, my apologies. I'm trying my best. I applied your last solution and still it tells me " 'shifter' was not declared in this scope"
I'm giving up on this library. Thanks for the help but my Arduino skills aren't good enough apparently and I fail to find a good reference to make the library.

You are calling shifter methods as if they are static, looks like you not need an instance.
Which is in your sketch:

Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);

You willl need to either declare the variable in the matrix library maybe pass it by reference through the constructor:

class Matrix{

  public:
  Matrix(int cathodePins[8], int greenPins[8], int redPins[8], Shifter &s );
  Shifter &shifter;
  //...
};

Matrix::Matrix(int cathodePins[8], int greenPins[8], int redPins[8], Shifter &s)
: shifter( s )
{

for(int j = 0; j< 8; j++){
shifter.setPin(cathodePins[j], LOW);
shifter.setPin(greenPins[j], LOW);
shifter.setPin(redPins[j], LOW);
}
this->clear();
/*
These are also classes, they need instances.
FrequencyTimer2::disable();
FrequencyTimer2::setPeriod(2000);
FrequencyTimer2::setOnOverflow(Matrix::display);
*/
_cathodePins = cathodePins;
_greenPins = greenPins;
_redPins = redPins;
}

Looks like you have lots of reading to do.
Best way is to open up some other libraries and try understand what is going on.