Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Little problem right here with a if else loop

Status
Not open for further replies.

be80be

Well-Known Member
Here the problem if I add the " else statement I get the waiting on key" but it doesn't go back and test the

"if (c != 0xFF) "

It never prints key press

If I leave out the else statement it prints key and **** pot of 0xFF

Code:
void main()
{
  ScanKeyMatrixInit();
  UART_Init(9600);
  char c;
 if (c != 0xFF) { 
  c = ScanKeyMatrix(); 
  printf("%d\n",c);
    __delay_ms(100);
 }
 else if (c == 0xFF)
 {
     UART_Write_Text("waiting on key\n");
     __delay_ms(100);
   
 }
 
Yup. Computers are stupid. You have to tell it to do while your main program loop or use an empty while() in the last line of your program just so it won't run off into the memory wildneress after the last instruction trying to execute instructions, which it will glady do.
 
There is no loop. It will return from main and crash.

Mike.

Yep it just sit's and tells me the no key press LOL so something like this is better

Code:
void main()
{
  ScanKeyMatrixInit();
     UART_Init(9600);
    char c;
 while (1)
  {
 if (c != 0xFF) {
       c = ScanKeyMatrix();
             printf("%d\n",c);
        __delay_ms(100);
 }
 else if (c == 0xFF)
 {
     UART_Write_Text("waiting on key\n");
         __delay_ms(1000);
 
    }
  }
}
That still does the same thing.
the else is where it stays it does not look for key press
Screenshot from 2018-02-05 00-52-58.png
 
Last edited:
There's the whole code

Code:
/*
 * File:   main.c
 * Author: burt
 *
 * Created on February 4, 2018, 3:31 PM
 */
// BEGIN CONFIG
#pragma config FOSC = HS 
#pragma config WDTE = OFF 
#pragma config PWRTE = OFF
#pragma config BOREN = ON 
#pragma config LVP = OFF 
#pragma config CPD = OFF 
#pragma config WRT = OFF 
#pragma config CP = OFF 
//END CONFIG
#define _XTAL_FREQ 20000000
#include <pic16f876a.h>
#include <xc.h>
#include <stdio.h>              // Standard I/O - required for printf() function
#include <stdlib.h>              // formatting text
#include <stdbool.h>
#include "uart.h"
#define row1port PORTBbits.RB0
#define row2port PORTBbits.RB1
#define row3port PORTBbits.RB2
#define row4port PORTBbits.RB3
#define col1port PORTBbits.RB4
#define col2port PORTBbits.RB5
#define col3port PORTBbits.RB6
#define col4port PORTBbits.RB7   //if a 4x4 keypad is used
#define row1tris TRISBbits.TRISB0
#define row2tris TRISBbits.TRISB1
#define row3tris TRISBbits.TRISB2
#define row4tris TRISBbits.TRISB3
#define col1tris TRISBbits.TRISB4
#define col2tris TRISBbits.TRISB5
#define col3tris TRISBbits.TRISB6
#define col4tris TRISBbits.TRISB7 
void  putch(char c)
   {
   UART_Write(c);   // this don't work can't use prinf
   }
char const keyPadMatrix[] = 
{ 
    '1','2','3','4',
    '5','6','7','8',
    '9','0','A','B',
    'C','D','E','F',
    0xFF
};
void ScanKeyMatrixInit()
{
    // we scan the keypad by turning on the row outputs and 
    // reading the columns 
    row1tris = 0;
    row2tris = 0;
    row3tris = 0;
    row4tris = 0;
    col1tris = 1;
    col2tris = 1;
    col3tris = 1;
    col4tris = 1;
}
char ScanKeyMatrix()
{
    // This routine returns the first key found to be
    // pressed during the scan.
    char key = 0, row;
   
    for( row = 0b00000001; row < 0b00010000; row <<= 1 )
    {       
        {   // turn on row output
            row1port = (row & 0x0001)>>0;
            row2port = (row & 0x0002)>>1;
            row3port = (row & 0x0004)>>2;
            row4port = (row & 0x0008)>>3;
            __delay_ms(1);
        }
       
        // read colums - break when key press detected
        if( col1port )
            break;
        key++;
        if( col2port )
            break;
        key++;
        if( col3port )
            break;
        key++;
        if( col4port )
            break;
        key++;
    }
    row1port = 0;
    row2port = 0;
    row3port = 0;
    row4port = 0;
       
    return keyPadMatrix[ key ]; 
}
void main()
{
  ScanKeyMatrixInit();
     UART_Init(9600);
    char c;
 if (c != 0xFF) {
       c = ScanKeyMatrix();
            UART_Write(c);
        __delay_ms(100);
 }
 else if (c == 0xFF)
 {
     UART_Write_Text("waiting on key\n");
         __delay_ms(1000);
    }
   while (1)
  { 
  }
}

As long as I just print the key they show up

Here the usat.h
Code:
#include <pic16f876a.h>
#include <xc.h>
char UART_Init(const long int baudrate)
{
    unsigned int x;
    x = (_XTAL_FREQ - baudrate*64)/(baudrate*64);
    if(x>255)
    {
        x = (_XTAL_FREQ - baudrate*16)/(baudrate*16);
        BRGH = 1;
    }
    if(x<256)
    {
      SPBRG = x;
      SYNC = 0;
      SPEN = 1;
          TRISC7 = 1;
          TRISC6 = 1;
          CREN = 1;
          TXEN = 1;
      return 1;
    }
    return 0;
}
char UART_TX_Empty()
{
  return TRMT;
}
char UART_Data_Ready()
{
   return RCIF;
}
char UART_Read()
{
  while(!RCIF);
  return RCREG;
}
void UART_Read_Text(char *Output, unsigned int length)
{
    unsigned int i;
    for(int i=0;i<length;i++)
        Output[i] = UART_Read();
}
void UART_Write(char data)
{
  while(!TRMT);
  TXREG = data;
}
void UART_Write_Text(char *text)
{
  int i;
  for(i=0;text[i]!='\0';i++)
      UART_Write(text[i]);
}


And what i get without the if else
Screenshot from 2018-02-05 01-30-49.png
 
How do I get rid of the <0xff>
and get just a single press
Screenshot from 2018-02-05 03-30-52.png

It gets all the keys

Screenshot from 2018-02-05 03-44-45.png
 
Last edited:
Re Initialise the Variable "c" at the end of IF ELSE loop.


Code (text):

void main()
{
ScanKeyMatrixInit();
UART_Init(9600);
char c;
while (1)
{
if (c != 0xFF) {
c = ScanKeyMatrix();
printf("%d\n",c);
__delay_ms(100);

}
else if (c == 0xFF)
{
UART_Write_Text("waiting on key\n");
__delay_ms(1000);


}
c = "";
}
}
 
How on earth does anyone expect that code to work? It tests the variable c before placing a value in it.

Mike.
 
Now I'm lost I think you mean this if (c != 0xFF)
c is loaded with 0xff if there is no keypress.
 
Look at this code,
Code:
 if (c != 0xFF) {
       c = ScanKeyMatrix();
            UART_Write(c);
        __delay_ms(100);
 }
 else if (c == 0xFF)
You test c in the first line and load c in the second!!

And, you only load c if it isn't oxff!!! The code makes no sense.

Mike.
 
C is loaded with whatever key is pressed if there is no keypressed it's 0xff
that's why I did the if not = 0xff
 
Dam your right I should be doing it like this ScanKeyMatrix()
Code:
void main()
{
    while (1) {
 
    ScanKeyMatrixInit();
     UART_Init(9600);
    char c;
    //c = ScanKeyMatrix();
 if (ScanKeyMatrix() != 0xFF) {
       c = ScanKeyMatrix();
            UART_Write(c);
        __delay_ms(100);
 }
 else if (c == 0xFF)
 {
     UART_Write_Text("waiting on key\n");
        __delay_ms(1000);

    }
  
  }
}
It was loading the 0xff after the loop runs right.
 
Last edited:
Well This is better now to get what i really want.
Screenshot from 2018-02-05 12-58-44.png


I changed chips to 16F15376 has more pins to mess with and is easier to use with mplab-x
Code:
void main(void)
{
    // initialize the device
    SYSTEM_Initialize();
    EUSART1_Initialize();
   
    // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
    // Use the following macros to:
    // Enable the Global Interrupts
    INTERRUPT_GlobalInterruptEnable();
    // Enable the Peripheral Interrupts
    INTERRUPT_PeripheralInterruptEnable();
    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();
    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();
   while (1) {
    ScanKeyMatrixInit();
    char c;
    //c = ScanKeyMatrix();
 if (ScanKeyMatrix() != 0xFF) {
       c = ScanKeyMatrix();
            EUSART1_Write(c);
            printf("\n");
        __delay_ms(100);
 }
 else 
 {
     printf("waiting on key\n");
        __delay_ms(1000);
    }
 
  }
}
 
This get's the keys good now to figure how to stop it from printing more then one number.
Code:
 ScanKeyMatrixInit();
   
    char keys;
    while (1) {
     keys = ScanKeyMatrix();
   
       switch(keys)
                     {
    case '1':     
        printf("Letter '1' found.\n");
        break;
    case '2':
        printf("Letter '2' found.\n");
        break;
    case '3':   
        printf("Letter '3' found.\n");
        break;
    case '4':     
        printf("Letter '4' found.\n");
        break;
    case '5':
        printf("Letter '5' found.\n");
        break;
    case '6':   
        printf("Letter '6' found.\n");
        break;
   case '7':     
        printf("Letter '7' found.\n");
        break;
    case '8':
        printf("Letter '8' found.\n");
        break;
    case '9':   
        printf("Letter '9' found.\n");
        break;
    case '0':     
        printf("Letter '0' found.\n");
        break;
    case 'A':
        printf("Letter 'A' found.\n");
        break;
    case 'B':   
        printf("Letter 'B' found.\n");
        break;
    case 'C':     
        printf("Letter 'C' found.\n");
        break;
    case 'D':
        printf("Letter 'D' found.\n");
        break;
    case 'E':   
        printf("Letter 'E' found.\n");
        break;
    case 'F':     
        printf("Letter 'F' found.\n");
        break;     
    default:    //printf("Key not in list.\n");
    __delay_ms(100);
}
 
   
  }
Screenshot from 2018-02-05 22-52-17.png
 
You need to detect rising or lowering edges. The way I do it is,
1. Get all keys into 1 variable - 16 bit for 4*4 keypad.
2. XOR with the previous value - this sets any key that changed to 1.
3. If active high - AND the XORed value with the current value - this gives a 1 for any new key press.
If active low then AND with the previous value.
4. Copy key value to previous.

For a single active low key on an arduino I use the following,
Code:
    pinMode(A0,INPUT_PULLUP);
    key=(digitalRead(A0));
    if((key^previous)&previous){
      Serial.print ("New Key press");
    }
    Serial.println(key);
    previous=key;

Mike.
Edit, added braces to avoid confusion.
 
I wish there was a pause like in basic LOL.
Thanks I'll try you code I did something like it but my thinking was backward.
I think diabetes neuropathy has killed my brain lol It has messed my eyes .
Thinking about the arduino Microchip got a killer atmega328-pB I think that's right I'm order one it faster chip and more hardware
and works with arduino ide.

This is the keyScan.h

Code:
/*
 * File: 
 * Author:
 * Comments:
 * Revision history:
 */
// This is a guard condition so that contents of this file are not included
// more than once.
#ifndef XC_HEADER_TEMPLATE_H
#define    XC_HEADER_TEMPLATE_H
#define row1port LATDbits.LATD0
#define row2port LATDbits.LATD1
#define row3port LATDbits.LATD2
#define row4port LATDbits.LATD3
#define col1port PORTDbits.RD4
#define col2port PORTDbits.RD5
#define col3port PORTDbits.RD6
#define col4port PORTDbits.RD7   //if a 4x4 keypad is used
#define row1tris TRISDbits.TRISD0
#define row2tris TRISDbits.TRISD1
#define row3tris TRISDbits.TRISD2
#define row4tris TRISDbits.TRISD3
#define col1tris TRISDbits.TRISD4
#define col2tris TRISDbits.TRISD5
#define col3tris TRISDbits.TRISD6
#define col4tris TRISDbits.TRISD7
#include <xc.h> // include processor files - each processor file is guarded.
char const keyPadMatrix[] =
{
    '1','2','3','4',
    '5','6','7','8',
    '9','0','A','B',
    'C','D','E','F',
    0xFF
};
void ScanKeyMatrixInit()
{
    // we scan the keypad by turning on the row outputs and
    // reading the columns
    row1tris = 0;
    row2tris = 0;
    row3tris = 0;
    row4tris = 0;
    col1tris = 1;
    col2tris = 1;
    col3tris = 1;
    col4tris = 1;
}
char ScanKeyMatrix()
{
    // This routine returns the first key found to be
    // pressed during the scan.
    char key = 0, row;
 
    for( row = 0b00000001; row < 0b00010000; row <<= 1 )
    {     
        {   // turn on row output
            row1port = (row & 0x0001)>>0;
            row2port = (row & 0x0002)>>1;
            row3port = (row & 0x0004)>>2;
            row4port = (row & 0x0008)>>3;
            __delay_ms(100);
        }
     
        // read colums - break when key press detected
        if( col1port )
            break;
        key++;
        if( col2port )
            break;
        key++;
        if( col3port )
            break;
        key++;
        if( col4port )
            break;
        key++;
    }
    row1port = 0;
    row2port = 0;
    row3port = 0;
    row4port = 0;
     
    return keyPadMatrix[ key ];
}
#ifdef    __cplusplus
extern "C" {
#endif /* __cplusplus */
    // TODO If C++ is being used, regular C code needs function names to have C
    // linkage so the functions can be used by the c code.
#ifdef    __cplusplus
}
#endif /* __cplusplus */
#endif    /* XC_HEADER_TEMPLATE_H */

Screenshot from 2018-02-05 23-32-07.png


Just a side note the new atmega
ATmega328PB-XMINI_front.jpg

ProductDetails.aspx
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top