Utilizing keypad library as class property

I want to use the arduino keypad library @ Arduino Playground - Keypad Library as a property on a class "Keyblock". I am no unable to initialize it because it requires parameters for the constructor. However those parameters are not allowed because they are not static (as far as I am aware). Code is below...

Main.ino

#include "Debug.h"
#include "Keyblock.h"

Debug debug;
Keyblock keyblock;

void loop(){
  keyblock.getKey();
}

void setup(){ 
  debug.message("Setup Complete");
}

Keyblock.h

#ifndef KEYBLOCK_H
#define KEYBLOCK_H

#include <SPI.h>
#include <Keypad.h>
#include "Debug.h"

class Keyblock {  
private:
    static constexpr unsigned ROWS = 4;
    static constexpr unsigned COLS = 3;

    static constexpr char keys[ROWS][COLS] = {
      {'1','2','3'},
      {'4','5','6'},
      {'7','8','9'},
      {'*','0','#'}
    };

    // put your pins in these arrays:
    static constexpr byte keypadRowPins[ROWS] = { 9, 8, 7, 6 };
    static constexpr byte keypadColPins[COLS] = { 12, 11, 10 };

    Keypad keypad;
    Debug debug;
public:
    Keyblock(); // add a user-defined default constructor
    void getKey();
};

#endif

Keyblock.cpp

#include "Keyblock.h"

Keyblock::Keyblock() : // member init-list between `:` and the body of the constructor
    keypad(makeKeymap(keys), keypadRowPins, keypadColPins, ROWS, COLS),
    debug(debug)
{}

void Keyblock::getKey() {
  char key = keypad.getKey();
  debug.message(key);
}

Errors :

sketch\Keyblock.cpp: In constructor 'Keyblock::Keyblock()':
sketch\Keyblock.cpp:5:16: warning: invalid conversion from 'const byte* {aka const unsigned char*}' to 'byte* {aka unsigned char*}' [-fpermissive]
     debug(debug)
                ^
In file included from sketch\Keyblock.h:5:0,
                 from sketch\Keyblock.cpp:1:
C:\Users\campo\Documents\Arduino\libraries\Keypad\src/Keypad.h:78:2: note:   initializing argument 2 of 'Keypad::Keypad(char*, byte*, byte*, byte, byte)'
  Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols);
  ^~~~~~
sketch\Keyblock.cpp:5:16: warning: invalid conversion from 'const byte* {aka const unsigned char*}' to 'byte* {aka unsigned char*}' [-fpermissive]
     debug(debug)
                ^
In file included from sketch\Keyblock.h:5:0,
                 from sketch\Keyblock.cpp:1:
C:\Users\campo\Documents\Arduino\libraries\Keypad\src/Keypad.h:78:2: note:   initializing argument 3 of 'Keypad::Keypad(char*, byte*, byte*, byte, byte)'
  Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols);
  ^~~~~~
sketch\Keyblock.cpp:3:1: warning: 'Keyblock::debug' is initialized with itself [-Winit-self]
 Keyblock::Keyblock() : // member init-list between `:` and the body of the constructor
 ^~~~~~~~
C:\Users\campo\AppData\Local\Temp\ccxzZ5s3.ltrans0.ltrans.o: In function `global constructors keyed to 65535_0_Debug.cpp.o.2048':
<artificial>:(.text.startup+0x100): undefined reference to `Keyblock::keypadRowPins'
<artificial>:(.text.startup+0x102): undefined reference to `Keyblock::keypadRowPins'
<artificial>:(.text.startup+0x10c): undefined reference to `Keyblock::keypadColPins'
<artificial>:(.text.startup+0x10e): undefined reference to `Keyblock::keypadColPins'
<artificial>:(.text.startup+0x124): undefined reference to `Keyblock::keys'
<artificial>:(.text.startup+0x126): undefined reference to `Keyblock::keys'
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino Mega or Mega 2560.

If change the properties to something like

unsigned int ROWS = 4;
unsigned int COLS = 3;

I get the following errors

Keyblock.h:13:38: error: invalid use of non-static data member 'Keyblock::COLS'
     static constexpr char keys[ROWS][COLS] = {
                                      ^~~~
sketch\Keyblock.h:11:25: note: declared here
     unsigned int COLS = 3;
                         ^
Keyblock.h:21:34: error: invalid use of non-static data member 'Keyblock::ROWS'
     constexpr byte keypadRowPins[ROWS] = { 9, 8, 7, 6 };
                                  ^~~~
sketch\Keyblock.h:10:25: note: declared here
     unsigned int ROWS = 4;
                         ^
Keyblock.h:22:34: error: invalid use of non-static data member 'Keyblock::COLS'
     constexpr byte keypadColPins[COLS] = { 12, 11, 10 };

I found this approach below compiles but it seems like a horrible design/mess. Maybe its the best way but I was hoping to find something that is cleaner.

#ifndef KEYBLOCK_H
#define KEYBLOCK_H

#include <SPI.h>
#include <Keypad.h>
#include "Debug.h"

class Keyblock {  
private:
    // const unsigned int ROWS;
    // const unsigned int COLS;
    int ROWS;
    int COLS;

    char keys[4][3];
    // put your pins in these arrays:
    byte keypadRowPins[4];
    byte keypadColPins[3];

    Keypad keypad;
    Debug debug;
public:
    Keyblock():
    keypad(makeKeymap(keys), keypadRowPins, keypadColPins, ROWS, COLS)
    {

        ROWS = 4;
        COLS = 3;

        char _keys[4][3] = {
          {'1','2','3'},
          {'4','5','6'},
          {'7','8','9'},
          {'*','0','#'}
        };

        for(int i = 0; i < 4; i++){
            for(int j = 0; j < 3; j++){
                keys[i][j] = _keys[i][j];
            }
        }

        // put your pins in these arrays:
        char _keypadRowPins[4] = { 9, 8, 7, 6 };
        char _keypadColPins[3] = { 12, 11, 10 };

        for(int i = 0; i < 4; i++){
            keypadRowPins[i] = _keypadRowPins[i];        
        }

        for(int i = 0; i < 3; i++){
            keypadColPins[i] = _keypadColPins[i];        
        }

    }

    void getKey();
};

#endif

Compiles, untested:

#include <Keypad.h>

class Keyblock {
  private:
    static constexpr unsigned ROWS = 4;
    static constexpr unsigned COLS = 3;

    static constexpr char keys[ROWS][COLS] = {
      {'1', '2', '3'},
      {'4', '5', '6'},
      {'7', '8', '9'},
      {'*', '0', '#'}
    };

    // put your pins in these arrays:
    static constexpr byte keypadRowPins[ROWS] = { 9, 8, 7, 6 };
    static constexpr byte keypadColPins[COLS] = { 12, 11, 10 };

    Keypad keypad;

  public:
    Keyblock(); // add a user-defined default constructor
    void getKey();
};

constexpr byte Keyblock::keypadRowPins[ROWS];
constexpr byte Keyblock::keypadColPins[COLS];
constexpr char Keyblock::keys[ROWS][COLS];
constexpr unsigned Keyblock::ROWS;
constexpr unsigned Keyblock::COLS;

Keyblock::Keyblock() : // member init-list between `:` and the body of the constructor
  keypad(makeKeymap(keys), keypadRowPins, keypadColPins, ROWS, COLS) {}

void Keyblock::getKey() {
  char key = keypad.getKey();
}

Keyblock keyblock;

void setup(){ 

}

void loop(){
  keyblock.getKey();
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.