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
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,

Thank you very much for having interest in my sample 😉

I modified my sample from

 

void dump_key_matrix(void)
{
    int col, row ;
    for (row = 0 ; row < NUM_ROW ; row++) {
        for (col = 0 ; col < NUM_COL ; col++) {
            if (key[row][col]) {
                snprintf(str, STR_LEN, "%c ", letter[row][col]) ;
                print(str) ;
            } else {
                print("- ") ;
            }
        }
        print("\n\r") ;
    }   
}

int main(void)
{
    init_hardware() ;

    for(;;)
    {
        cls() ;
        dump_key_matrix() ;
        CyDelay(1000) ;
    }
}

 

to

 

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") ;
    }
}

int main(void)
{
    uint16_t key_table = 0 ;
    
    init_hardware() ;

    for(;;)
    {
        cls() ;
        key_table = get_key_matrix() ;

        print_key_table(key_table) ;
        CyDelay(1000) ;
    }
}

 

Now if you call get_key_matrix(), you will get an uint16_t key_table, which shows the status of all keys.

So you can test 

key_table & 0x8000 to check if '1' is pushed,

key_table & 0x4000 to check if '2' is pushed...

By building and running the new sample, you will see

(1) When no key is pressed

001-no-push.JPG

(2) When '1' is pressed

002-key_1_pushed.JPG

(3) When '2' is pressed

003-key_2_pushed.JPG

I hope that these new functions make implementing your menu project easier.

Best Regards,

1-Jul-2021

Motoo Tanaka

 

Hello @MotooTanaka san,


Thank you for the quick response and the updated project for the keypad read.

Firstly, let me list down what i understood from the new project:
1.) The keypad scanning is performed by scan_key_matrix() function every 1ms because of the SysTick timer interrupt and scans if there is any key pressed.
2.) In the main for (;;)key_table variable used to get the value, using the get_key_matrix() function,  of the keypress which is collected from the scan_key_matrix() function every 1ms.
3.) This key_table variable is passed on to the print_key_table() function as an argument.
4.) Inside the print_key_table() function, you have added
           (i) A mask variable which comes handy when printing a particular keypress on the top line.
           (ii) And then running a nested for loop to check all the 16 key cells and, on a key press, the key_table is compared with the letter[row][col] and copied into the str string using snprintf and then printing the str as a matrix 4x4 form over UART -- Similar to the dump_key_matrix() function in last version of the firmware.

If my understanding is not correct, please let me know.

As i already mentioned previously, i would like to implement an interface between 4x4  keypad and a 16x2 LCD display (instead of UART).

In the new sample, instead of printing the values over UART using print_key_table() function, is it possible to store or get a return value of the current key press ( as int or char) which can be used in a switch case statements (to help me navigate through the different menu's on the LCD) based on the key pressed??

 

So, what i would like to have is like:

key_table = get_key_matrix();          //to get the value of key pressed (1 or 2 mostly would be enough)
where get_key_matrix() function should return a value (int or uint) to be used for the switch case statements

switch(key_table)                  //first input to toggle to the second menu
{
case 1:
{
//print something over LCD
key1=get_key_matrix()       //taking the input again from user to reach the second menu
switch(key1)                            //second menu options to toggle
{
case 1:
//Do something or print
case 2: 
//print something else
}
}
case 2:
//print the second statement
}

Hope you understand the application a bit better now.

Please advice on how to proceed and what can be done or modified to achieve the said functionality.

 

Thanks and Regards,
Yash

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Yash-san,

scan_key_matrix() is called every 1ms and it checks "ONLY 1" key per call to make the interrupt time short. So to scan all 16 keys, it takes 16ms. Or we can say that each key[r][c] is updated every 16ms.

Anyway, so we can assume that the key[*][*] is basically up to date, unless your application is very fast FPS type shooting game or something.

get_key_matrix() get the current key[*][*] values into an uint16_t key_table.

And push of '1' key set the MSB bit of the key_table, this means we can accept multi keys touch.

 

Anyway so to use key_table value for switch statement, we could do something like

==================

#define BUTTON_1 0x8000

#define BUTTON_2 0x4000

....

switch(key_table) {

case BUTTON_1: 

    /* button 1 pressed process */

   break ;

case BUTTON_2:

  /* button 2 pressed process */

  break ;

/* .... */

 default:

     break ;

}

==================

or since we know that key[0][0] is '1', we could write something like below.

And this way, we don't even need get_key_matrix()

=====================

if (key[0][0]) { /* button 1 is pressed */

} else if (key[0][1]) { /* button 2 is pressed */

}

=====================

 

Best Regards,

1-Jul-2021

Motoo Tanaka

P.S. BTW, as a mcu is faster than us, if you have two checks for '1'  in switch statement only 1 push can go through them, so I would recommend to have some delay after each button check.

Or provide other variables to hold push and release state of each buttons and use it to detect two separated pushes.

Edited: if (letter[0][0]) ... was mistake of if (key[0][0]) ...

lock attach
Attachments are accessible only for community members.

Hello Tanaka-san,


Thank you for being so patient and explaining and guiding me through the sample code.

Unfortunately, I tried both of your suggestion individually, but none of them helped me.

The observations are as follows:
1. When using the first method (#define BUTTON_1 and BUTTON_2), the key press is not being sampled -> No change in the LCD screen (still displaying the previous menu).
2. When using the second method ( if(letter[0][0]…), the program doesn't take any key press input and directly scrolls through the first option of every menu and shows the last submenu directly (without pressing any Key).

I am clueless on what could be causing this behavior.

Can you please check and let me know what i could be doing wrong in my project?
I have attached the zip file of my project for your reference.

The database_fun() is executed first. So, you can start checking from there.
I have added comments of the observations in the database_fun() function.

 

Please advice.

Regards,
Yash

0 Likes
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

Hello @MotooTanaka-san,

 

Thank you so much for your continuous support and help!! ☺😀

The example provided by you worked great in UART and i was able to modify it to work on LCD.

I was having issue implementing the detection mechanism and shifting to a submenu, which was solved by your sample code above.

Thanks a lot for your help.

 

PS: Maybe you can post it as a sample code/code example with the heading of Simple MENU System (or DBS) using 4x4 matrix and 16x2 LCD on PSOC 5LP. Could help others like me!!!


Regards,
Yash

 

0 Likes
Y_r
Level 4
Level 4
50 replies posted 50 sign-ins 25 replies posted

Hello, @MotooTanaka san,

I am trying out ways to implement a scrollable and selectable menu system (and perform different actions on a submenu like reading a POT, Temp sensor or ultrasonic distance, etc.) on a 16x2 LCD and using a 4x4 Keypad to control the scrolling and selecting.
I have adapted the above sample you shared, to the LCD module and it works a charm.

I have tried to follow this Arduino example (ignore the language😅), and have got it working similar to the youtube video.

I was wondering if you had any suggestions on how I can be able to adapt your shared sample to meet something similar working.

Your insight will be helpful.

Thanks and Regards,
Yash

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Yash-san,

Yes, your subject title and question(request) mentioned such action from the beginning,

but as this discussion has been marked as "answered".

Would you create another discussion focusing more on the 16x2 LCD Menu side?

 

In this discussion, the basic logic should have been covered, but LCD Menu part has not.

 

Although I'm going to think about the implementation, 

please note that you are the subject of the development

and we (members) are supposed to be helping you.

 

Best Regards,

8-Dec-2021

Motoo Tanaka

 

0 Likes

Hello, @MotooTanaka san,

Following your advice, I was trying to get the menu system that I implemented yesterday up and running and was successful in getting a similar form of the firmware you shared, working today.

I will follow, read and check out the blog post to see if my code can be improved in some way☺.

Thank you for being so kind to invest your time and helping me out☺.

Regards,
Yash