PSOC5 LP with 4x4 Keypad and 16x2 LCD Menu System Example

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Y_r
Level 4
Level 4
50 replies posted 50 sign-ins 25 replies posted

Hello @MotooTanaka san,

I have been trying to get this example as a base to implement a simple HMI menu system using PSOC 5LP and 4x4 keypad and LCD: https://community.cypress.com/t5/Code-Examples/4x4-Matrix-Keypad-Sample/m-p/96977#M370

In the example code provided, the dump_key_matrix() function dumps the key pressed at that instant into a string str which can be used to print, either over UART or onto the LCD using appropriate functions (WORKS as described).

But, in a menu system, there are different levels at which the key press is to be detected (need to call dump_key_matrix() multiple times) which would mean that the dump_key_matrix() function needs to have a return type and not be 'void'.

I have tried modifying the return type to char and int too, where the letter[row][col] string will be used for a switch case and i set a variable flag with appropriate value for the corresponding key press, but this isn't working as intended.

 

Can you please guide me on how to modify the code to enable a return type for the dump_key_matrix() function which can be used to call the function multiple times in the code ( at different menu levels)?

 

To give a better view of what i want to implement:

1.) Show the first menu screen with 2 options to choose from (Press1 for Emp details, Press2 for Comp details).
2.) Take the input from user using dump_key_matrix().
3.) Based on the input, give the second menu screen with 2 more options to choose from.
If Press1 in first menu: Press1 for Name, Press2 for Age
If Press2 in first menu: Press1 for Company Address
4.) Again taking input from dump_key_matrix().
5.) Showing the third menu screen.
If Press1 in Second menu: emp_name (string)
If Press2 in Second menu: emp_age (string)
If Press 2 in first menu: show_company_details and address as a Up scrolling menu.

This is what i want to implement, but sadly i am not able to figure out the first part of getting a parsable (either using switch case or if else ) input variable to implement any of it.

 

Please help.


Regards,
Yash

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Yash-san,

To accomplish a target, there can be infinite number of methods.

So the following is a sketch of mine and is not the only method to realize something you wish.

Having said that the following seems to be working (using UART)

#include "project.h"
#include "stdio.h"

#define NUM_ROW 4
#define NUM_COL 4

volatile uint8_t key[NUM_ROW][NUM_COL] = { 0u } ;
uint8_t letter[NUM_ROW][NUM_COL] = {
    { '1', '2', '3', 'A' },
    { '4', '5', '6', 'B' },
    { '7', '8', '9', 'C' },
    { '*', '0', '#', 'D' }
} ;
    

volatile int row_no = 0 ;
volatile int col_no = 0 ;

void scan_key_matrix(void)
{
    switch(row_no) {
    case  0: ROW0_Write(1) ; ROW1_Write(0) ; ROW2_Write(0) ; ROW3_Write(0) ; break ;
    case  1: ROW0_Write(0) ; ROW1_Write(1) ; ROW2_Write(0) ; ROW3_Write(0) ; break ;
    case  2: ROW0_Write(0) ; ROW1_Write(0) ; ROW2_Write(1) ; ROW3_Write(0) ; break ;
    case  3: ROW0_Write(0) ; ROW1_Write(0) ; ROW2_Write(0) ; ROW3_Write(1) ; break ;
    default: ROW0_Write(0) ; ROW1_Write(0) ; ROW2_Write(0) ; ROW3_Write(0) ; break ;
    }

    switch(col_no) {
    case 0: key[row_no][col_no] = COL0_Read() ; break ;
    case 1: key[row_no][col_no] = COL1_Read() ; break ;
    case 2: key[row_no][col_no] = COL2_Read() ; break ;
    case 3: key[row_no][col_no] = COL3_Read() ; break ;
    }
    
    col_no++ ;
    if (col_no >= NUM_COL) {
        col_no = 0 ;
        row_no = (row_no + 1) % NUM_ROW ;
    } 
    ROW0_Write(0) ; 
    ROW1_Write(0) ; 
    ROW2_Write(0) ; 
    ROW3_Write(0) ; 
}

CY_ISR(my_tick_isr)
{
    scan_key_matrix() ;
}

#define STR_LEN 64
char str[STR_LEN+1] ;
void print(char *str)
{
    UART_PutString(str) ;
}

void printc(char c)
{
    UART_PutChar(c) ;
}

void cls(void)
{
    print("\033c") ; /* reset */
    CyDelay(20) ;
    print("\033[2J") ; /* clear screen */
    CyDelay(20) ;
}

void splash(void)
{
    cls() ;
    print("5LP 4x4 Matrix Key Test") ;
    snprintf(str, STR_LEN, "(%s %s)\n", __DATE__, __TIME__) ;
    print(str) ;
}

void init_hardware(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */
    UART_Start() ;
    splash() ;
    CySysTickStart() ;
    CySysTickSetCallback(0, my_tick_isr) ;
}

uint16_t get_key_matrix(void)
{
    int col, row ;
    uint16_t value = 0 ;
    for (row = 0 ; row < NUM_ROW ; row++) {
        for (col = 0 ; col < NUM_COL ; col++) {
            value <<= 1 ;
            if (key[row][col]) {
                value |= 0x01 ;
            }
        }
    }   
    return( value ) ;
}

void print_key_table(uint16_t key_table)
{
    int row, col ;
    uint16_t mask = 0x8000 ; /* bin: 1000_0000_0000_0000 */
    snprintf(str, STR_LEN, "0x%04X: ", key_table) ;
    print(str) ;
    
    if (key_table & 0x8000) {
        print("1 is pushed ") ;
    }
    if (key_table & 0x4000) {
        print("2 is pushed ") ;
    }
    print("\n\r") ;
    
    for (row = 0 ; row < NUM_ROW ; row++) {
        for (col = 0 ; col < NUM_COL ; col++) {
            if (key_table & mask) {
                snprintf(str, STR_LEN, "%c ", letter[row][col]) ;
                print(str) ;
            } else {
                print("_ ") ;
            }
            mask >>= 1 ;
        }
        print("\n\r") ;
    }
}

#define BUTTON_1 0x8000
#define BUTTON_2 0x4000
#define BUTTON_D 0x0001

#define MENU_TOP 0u
#define MENU_10  10
#define MENU_11  11
#define MENU_12  12
#define MENU_20  20
#define MENU_21  21
#define MENU_22  22
int menu_mode = MENU_TOP ;

void greeting(void)
{
    cls() ;
    print("WELCOME TO THE") ; print("\n\r") ;
    print("EMP/COMP DBS")   ; print("\n\r") ;
}

void go_menu_top(void)
{
    cls() ;
    print("P1-Emp Details"); print("\n\r") ;
    print("P2-Comp Details"); print("\n\r") ;
    menu_mode = MENU_TOP ;
}

void go_menu_10(void)
{
    cls() ;
    print("PRESS 1: NAME"); print("\n\r") ;
    print("PRESS 2: AGE"); print("\n\r") ;
    menu_mode = MENU_10 ;
}

void go_menu_11(void) 
{
    cls() ;
    print("Employee Name"); print("\n\r") ;
    print("Yash"); print("\n\r") ;
    menu_mode = MENU_11 ;   
}

void go_menu_12(void)
{
    cls() ;
    print("Employee Age"); print("\n\r") ;
    print("24"); print("\n\r") ;
    menu_mode = MENU_12 ;   
}

void go_menu_20(void)
{
    cls() ;
    print("Press1:Comp Name"); print("\n\r") ;
    print("Press2:Comp Addr"); print("\n\r") ;
    menu_mode = MENU_20 ;  
}

void go_menu_21(void)
{
    cls() ;
    print("Company Name:"); print("\n\r") ;
    print("ATPL"); print("\n\r") ;
    menu_mode = MENU_21 ;   
}

void go_menu_22(void)
{
    cls() ;
    print("Company Addr:"); print("\n\r") ;
    print("Hyd"); print("\n\r") ;
    menu_mode = MENU_22 ;   
}

void do_menu_top(uint16_t key_table)
{
    switch(key_table) {
    case BUTTON_1: go_menu_10() ; break ;
    case BUTTON_2: go_menu_20() ; break ;
    default:       go_menu_top() ; break ;
    }
}

void do_menu_10(uint16_t key_table)
{

    switch(key_table) {
    case BUTTON_1: go_menu_11() ; break ;
    case BUTTON_2: go_menu_12() ; break ;
    case BUTTON_D: go_menu_top() ; break ;
    default:       go_menu_10() ; break ;
    }
}

void do_menu_11(uint16_t key_table)
{
    switch(key_table) {
    case BUTTON_1: go_menu_11() ; break ;
    case BUTTON_2: go_menu_11() ; break ;
    case BUTTON_D: go_menu_10() ; break ;
    default:       go_menu_10() ; break ;
    }
}

void do_menu_12(uint16_t key_table)
{

    switch(key_table) {
    case BUTTON_1: go_menu_12() ; break ;
    case BUTTON_2: go_menu_12() ; break ;
    case BUTTON_D: go_menu_10() ; break ;        
    default:       go_menu_12() ; break ;
    }
}

void do_menu_20(uint16_t key_table)
{
    switch(key_table) {
    case BUTTON_1: go_menu_21() ; ; break ;
    case BUTTON_2: go_menu_22() ; break ;
    case BUTTON_D: go_menu_top() ; break ;  
    default:       go_menu_20() ; break ;
    }
}

void do_menu_21(uint16_t key_table)
{
    switch(key_table) {
    case BUTTON_1: go_menu_21() ; break ;
    case BUTTON_2: go_menu_21() ; break ;
    case BUTTON_D: go_menu_20() ; break ;
    default:       go_menu_21() ; break ;
    }
}

void do_menu_22(uint16_t key_table)
{
    switch(key_table) {
    case BUTTON_1: go_menu_22() ; break ;
    case BUTTON_2: go_menu_22() ; break ;
    case BUTTON_D: go_menu_20() ; break ;
    default:       go_menu_22() ; break ;
    }
}

int main(void)
{
    uint16_t key_table = 0 ;
    uint16_t prev_key = 0 ;
    
    init_hardware() ;
    
    greeting() ;
    CyDelay(3000) ;
    
    go_menu_top() ;

    for(;;)
    {
        key_table = get_key_matrix() ;
        
        if ((key_table != 0) && (key_table != prev_key)) {  
            switch(menu_mode) {
            case MENU_TOP: do_menu_top(key_table) ; break ;
            case MENU_10:  do_menu_10(key_table)  ; break ;
            case MENU_11:  do_menu_11(key_table)  ; break ;
            case MENU_12:  do_menu_12(key_table)  ; break ;
            case MENU_20:  do_menu_20(key_table)  ; break ;
            case MENU_21:  do_menu_21(key_table)  ; break ;
            case MENU_22:  do_menu_22(key_table)  ; break ;
            default:       menu_mode = MENU_TOP   ; break ;
            }
            CyDelay(500) ;
        }
        prev_key = key_table ;
    }
}

Best Regards,

1-Jul-2021

Motoo Tanaka

View solution in original post

10 Replies