Skip to content

Commit

Permalink
[#78] Keypad not working
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidZemon committed Feb 28, 2019
1 parent 68e60ad commit 2426ad7
Show file tree
Hide file tree
Showing 5 changed files with 232 additions and 0 deletions.
1 change: 1 addition & 0 deletions Examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ add_subdirectory(PropWare_FullDuplexSerial)
add_subdirectory(PropWare_HD44780)
add_subdirectory(PropWare_I2C)
add_subdirectory(PropWare_I2CSlave)
add_subdirectory(PropWare_Keypad)
add_subdirectory(PropWare_L3G)
add_subdirectory(PropWare_MAX6675)
add_subdirectory(PropWare_MAX72xx)
Expand Down
6 changes: 6 additions & 0 deletions Examples/PropWare_Keypad/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.3)
find_package(PropWare REQUIRED)

project(PropWareKeypad_Demo)

create_simple_executable(${PROJECT_NAME} Keypad_Demo.cpp)
71 changes: 71 additions & 0 deletions Examples/PropWare_Keypad/Keypad_Demo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* @file Keypad_Demo.cpp
*
* @author David Zemon
*
* @copyright
* The MIT License (MIT)<br>
* <br>Copyright (c) 2013 David Zemon<br>
* <br>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject to the following conditions:<br>
* <br>The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.<br>
* <br>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

#include <PropWare/hmi/input/keypad.h>
#include <PropWare/hmi/output/printer.h>

using namespace PropWare;

/**
* @example PropWare_Keypad/Keypad_Demo.cpp
*
* Read keys from a common 4x4 keypad to interact with a user
*
* @include PropWare_Keypad/CMakeLists.txt
*/
int main() {
Keypad::Key keys[] = {
Keypad::Key('1'), Keypad::Key('2'), Keypad::Key('3'), Keypad::Key('A'),
Keypad::Key('4'), Keypad::Key('5'), Keypad::Key('6'), Keypad::Key('B'),
Keypad::Key('7'), Keypad::Key('8'), Keypad::Key('9'), Keypad::Key('C'),
Keypad::Key('*'), Keypad::Key('0'), Keypad::Key('#'), Keypad::Key('D')
};
const Pin rowPins[] = {
Pin(Pin::P19),
Pin(Pin::P20),
Pin(Pin::P21),
Pin(Pin::P22),
};
const Pin columnPins[] = {
Pin(Pin::P26),
Pin(Pin::P25),
Pin(Pin::P24),
Pin(Pin::P23),
};

Keypad keypad(keys, rowPins, columnPins);

while (1) {
//for (auto key : keys) {
// if (keypad.is_pressed(key.get_character()))
// pwOut << key.get_character() << '\n';
//}

keypad.get_keys();
for (size_t i = 0; i < Utility::size_of_array(keys); ++i) {
if (0 == i % 4)
pwOut << '\n';
pwOut << (keys[i].get_state() ? keys[i].get_character() : ' ') << ' ';
}

waitcnt(100*MILLISECOND + CNT);
}
}
1 change: 1 addition & 0 deletions PropWare/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(PROPWARE_SOURCES
${CMAKE_CURRENT_LIST_DIR}/gpio/pin.h
${CMAKE_CURRENT_LIST_DIR}/gpio/port.h
${CMAKE_CURRENT_LIST_DIR}/gpio/simpleport.h
${CMAKE_CURRENT_LIST_DIR}/hmi/input/keypad.h
${CMAKE_CURRENT_LIST_DIR}/hmi/input/scancapable.h
${CMAKE_CURRENT_LIST_DIR}/hmi/input/scanner.cpp
${CMAKE_CURRENT_LIST_DIR}/hmi/input/scanner.h
Expand Down
153 changes: 153 additions & 0 deletions PropWare/hmi/input/keypad.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/**
* @file PropWare/hmi/input/keypad.h
*
* @author David Zemon
*
* @copyright
* The MIT License (MIT)<br>
* <br>Copyright (c) 2013 David Zemon<br>
* <br>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject to the following conditions:<br>
* <br>The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.<br>
* <br>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

#pragma once

#include <PropWare/gpio/pin.h>
#include <PropWare/utility/utility.h>

namespace PropWare {

class Keypad {
public:
class Key {
public:
friend class Keypad;

public:
Key(const char character)
: character(character),
state(false) {
}

char get_character() const {
return this->character;
}


bool get_state() const {
return this->state;
}

protected:
char character;
bool state;
};

public:
/**
* MAPSIZE is the number of rows (times 16 columns)
*/
static const unsigned int DEFAULT_BOUNCE_TIME_MS = 10;

public:
/**
* Allows custom m_keymap, pin configuration, and keypad sizes
*/
template<size_t ROW_SIZE, size_t COLUMN_SIZE>
Keypad(Key keys[], const Pin (&rowPins)[ROW_SIZE], const Pin (&columnPins)[COLUMN_SIZE])
: m_keys(keys),
m_rowPins(rowPins),
m_columnPins(columnPins),
m_rows(ROW_SIZE),
m_columns(COLUMN_SIZE),
m_keyCount(this->m_rows * this->m_columns),
m_startTime(CNT - DEFAULT_BOUNCE_TIME_MS * MILLISECOND) {
this->set_debounce_time(Keypad::DEFAULT_BOUNCE_TIME_MS);
}

/**
* Populate the key list
*/

bool is_pressed(const char character) {
this->get_keys();

for (uint_fast8_t i = 0; i < this->m_keyCount; i++)
if (character == this->m_keys[i].character) {
return this->m_keys[i].state;
}
return false;
}

bool get_keys() {
bool keyActivity = false;

// Limit how often the keypad is scanned. This makes the loop() run 10 times as fast.
if ((CNT - this->m_startTime) > this->m_debounceTime) {
this->scan_keys();
this->m_startTime = CNT;
}

return keyActivity;
}

/**
* Minimum debounceTime is 1 mS.
*/
void set_debounce_time(const uint32_t debounceMs) {
if (!debounceMs)
this->m_debounceTime = MILLISECOND;
else
this->m_debounceTime = debounceMs * MILLISECOND;
}

private:

/**
* Hardware scan
*/
void scan_keys() {
for (uint_fast8_t row = 0; row < this->m_rows; row++) {
this->m_rowPins[row].set_dir_in();
this->m_rowPins[row].high();
}

// bitMap stores ALL the keys that are being pressed.
for (uint_fast8_t column = 0; column < this->m_columns; ++column) {
// Begin column pulse output.
this->m_columnPins[column].low();
this->m_columnPins[column].set_dir_out();

for (uint_fast8_t row = 0; row < this->m_rows; ++row) {
const uint_fast8_t keyIndex = column * 4 + row;
this->m_keys[keyIndex].state = !this->m_rowPins[row].read();
}

// Set pin to high impedance input. Effectively ends column pulse.
this->m_columnPins[column].high();
this->m_columnPins[column].set_dir_in();
}
}

private:
Key *m_keys;
const Pin *m_rowPins;
const Pin *m_columnPins;
const uint_fast8_t m_rows;
const uint_fast8_t m_columns;
const uint_fast8_t m_keyCount;

uint32_t m_debounceTime;
volatile uint32_t m_startTime;
};

}

0 comments on commit 2426ad7

Please sign in to comment.