Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

4X4 keypad problem in MicroC

Status
Not open for further replies.

Mithun_K_Das

Advanced Member level 3
Joined
Apr 24, 2010
Messages
899
Helped
24
Reputation
48
Reaction score
26
Trophy points
1,318
Location
Dhaka, Bangladesh, Bangladesh
Activity points
8,254
I'm doing a password based load control in microC. everything working fine but only the problem is the LCD is not ok. it displaying wrong. here is my code:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*******************************************************************************
*                   Program for 'Password Based Load Control'                  *
*                    Program Written by Engr. Mithun K. Das                    *
*                         MCU:PIC16F877A; X-Tal: 8MHz                          *
*                                 Driver:ULN2003                               *
*                                   16-May,14                                  *
*******************************************************************************/
unsigned short kp, cnt,cnt1;
// Keypad module connections
char  keypadPort at PORTD;
// End Keypad module connections
char key=0;
short mode=0;
short lock=0;
unsigned int Password1,password2;
// LCD module connections
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RB6_bit;
sbit LCD_D4 at RB5_bit;
sbit LCD_D5 at RB4_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D7 at RB2_bit;
 
sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D4_Direction at TRISB5_bit;
sbit LCD_D5_Direction at TRISB4_bit;
sbit LCD_D6_Direction at TRISB3_bit;
sbit LCD_D7_Direction at TRISB2_bit;
// End LCD module connections
 
void main() 
{
 
  TRISC = 0x00;//all out
  PORTC = 0x00;
  cnt = 0;                                 // Reset counter
  Keypad_Init();                           // Initialize Keypad
 
  Lcd_Init();                              // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                     // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);                // Cursor off
  Lcd_Out(1,1,"Password Based  ");
  Lcd_Out(2,1,"MultiLoad Cntrol");
  Delay_ms(1000);
  Lcd_Cmd(_LCD_CLEAR);
  cnt = 0;
  cnt1 = 0;
  password2 = EEPROM_Read(10)*1000+EEPROM_Read(11)*100+EEPROM_Read(12)*10+EEPROM_Read(13);
  while(1)
  {
       if(lock==0)
       {
          top:
          if(mode==0)
          {
             Lcd_Cmd(_LCD_CLEAR);
             if(RC0_bit)Lcd_Out(1,1,"L1:ON ");
             if(!RC0_bit)Lcd_Out(1,1,"L1:OFF");
             if(RC1_bit)Lcd_Out(1,11,"L2:ON ");
             if(!RC1_bit)Lcd_Out(1,11,"L2:OFF");
             if(RC2_bit)Lcd_Out(2,1,"L3:ON ");
             if(!RC2_bit)Lcd_Out(2,1,"L3:OFF");
             if(RC3_bit)Lcd_Out(2,11,"L3:ON ");
             if(!RC3_bit)Lcd_Out(2,11,"L3:OFF");
             Lcd_Out(1,7,"    ");
             Lcd_Out(2,7,"    ");
          }
          if(mode==1)
          {
              Lcd_Cmd(_LCD_CLEAR);
              Lcd_Out(1,1,"Enter Password");
              cnt=0;
          }
          if(mode==2)
          {
              Lcd_Out(1,1,"Enter Password:");
              if(cnt==4)
              {
                 Lcd_Out(2,11,"      ");
                 cnt=0;
                 password2 = EEPROM_Read(10)*1000+EEPROM_Read(11)*100+EEPROM_Read(12)*10+EEPROM_Read(13);
                 Password1 = EEPROM_Read(1)*1000+EEPROM_Read(2)*100+EEPROM_Read(3)*10+EEPROM_Read(4);
                 if(Password1==password2)
                 {
                    Lcd_Out(2,1,"Matched");
                    lock = 1;
                 }
 
              }
              else
              {
                 cnt++;
                 EEPROM_Write(cnt,kp);
                 Delay_ms(50);
                 kp = EEPROM_Read(cnt);
                 Lcd_Chr(2, 11+cnt, kp);                    // Print key ASCII value on LCD
              }
 
 
          }
          if(mode==3)
          {
             Lcd_Cmd(_LCD_CLEAR);
          }
          if(mode==4)// pressed # button
          {
              Lcd_Out(1,1,"NEW Password? ");
 
              if(cnt1>4)
              {
                 Lcd_Out(2,11,"      ");
                 cnt1=0;
                 Delay_ms(1000);
                 Lcd_Cmd(_LCD_CLEAR);
                 Lcd_Out(1,1,"Password");
                 Lcd_Out(2,1,"Changed...");
                 Delay_ms(1000);
                 Lcd_Cmd(_LCD_CLEAR);
                 mode = 0;//go to main screen
                 goto top;
              }
              else
              {
                 cnt1++;
                 EEPROM_Write(cnt1+9,kp);
                 Delay_ms(50);
                 kp = EEPROM_Read(cnt1+9);
                 Lcd_Chr(2, 10+cnt1, kp);   // Print key ASCII value on LCD
                 password2 = EEPROM_Read(10)*1000+EEPROM_Read(11)*100+EEPROM_Read(12)*10+EEPROM_Read(13);
              }
          }
       }
       else
       {
           Lcd_Cmd(_LCD_CLEAR);
           Lcd_Out(1,1,"PRESS A/B/C/D");
           if(key==4) RC0_bit=~RC0_bit;//pressed A
           if(key==8) RC1_bit=~RC1_bit;//pressed A
           if(key==12) RC2_bit=~RC2_bit;//pressed A
           if(key==16) RC3_bit=~RC3_bit;//pressed A
           if(key==13) lock=0;
       }
      
      
      
      
      kp = 0; // Reset key code variable
      // Wait for key to be pressed and released
      do
      kp = Keypad_Key_Click();             // Store key code in kp variable
      while (!kp);
      key = kp;
      if(key==13)// pressed *
      {
         if(mode<4)mode++;
         else mode = 0;
      }
 
     // Prepare value for output, transform key to it's ASCII value
      switch (kp)
      {
        case  1: kp = 49; break; // 1        // Uncomment this block for keypad4x4
        case  2: kp = 50; break; // 2
        case  3: kp = 51; break; // 3
        //case  4:  break; // A
        case  5: kp = 52; break; // 4
        case  6: kp = 53; break; // 5
        case  7: kp = 54; break; // 6
        //case  8:  break; // B
        case  9: kp = 55; break; // 7
        case 10: kp = 56; break; // 8
        case 11: kp = 57; break; // 9
        case 12:  break; // C
        //case 13:  break; // *
        case 14: kp = 48; break; // 0
        //case 15:  break; // #
        //case 16:  break; // D
      }
 
  }//while(1)
}//void
 
 
 
 
/*******************************************************************************
*                                                                              *
*                              End Of the Program                              *
*                                                                              *
*                                                                              *
*******************************************************************************/



and ISIS file:
 

Attachments

  • PasswordBasedMultiLoadControl.rar
    15.9 KB · Views: 111

Use CopyConst2Ram() with PIC16F devices if you have lot of strings.
 

Hello!

The biggest problem with your code is that it's unreadable.
Hint: break your code into smaller parts.
If I were you, I would:
1. Write a "ReadKey" function, that does what it says.

Example:

Code C - [expand]
1
2
3
4
5
uint8 ReadKey() {
    uint8 retkey;
    // Do the necessary to read one key, and return its value
    return retkey;
}



2. Write a "GetPasswd" function based on ReadKey.


Code C - [expand]
1
2
3
4
5
6
7
8
9
uint32 GetPasswd() {
    uint32 pw = 0;
    uint8 i = 0;
    for(i = 0 ; i < MAX_DIGITS ; ++i) {
        pw *= 10;
        pw += ReadKey();
    }
    return pw;
}



3. Write an "Access" function that returns 1 if the password is OK, 0 otherwise.

4. Similarily write any useful function like StorePassword(), or StorePassowrd(uint8 eeprom_pos);

Advantage: if a function is short, it's easy to test it, it is reusable, etc...

From there, you can expand the program indefinitely, for example allow to change the
password if you know the old one only, etc...
But please, don't write monolithic programs. It's bad for you (within 3 month you will
not understand it anymore), it's bad for people who will have to maintain your code.

To write understandable and maintainable code:
- Break your code into functions, that's what they are made for. One function should fit
in a single page (on a regular monitor, it allows you at least 50 lines of code, which is
a lot). If you have more than that, it's time to break the function.
- Use meaningful names
- Never use goto statements. Or if you want to, choose BASIC as your programming language.
- Use macros. For instance, "lock = 0" is not very clear. If you #define LOCKED 1, #define UNLOCKED 0
then "lock = UNLOCKED" will be more readable and more maintainable.
Same for "mode". I don't understand at a glance what mode means. If you use mode = SOME_MACRO
instead of mode = 0 then it would be more understandable.
- etc...

Have fun!

Dora.
 
How many times do you press star before trying to enter password? The code requires you to press star twice before entering the password. Try pressing star over and over again. This will drive you through the state machine and the LCD should change if you push it 5 times.

The code is readable.
 

Do you have pictures? What does it print?
 

problem was the LCD was not working well. all other functions are working well.

Hi;
Please attach the whole MikroC project folder (at least the c source, the *.mcppi and the *.cfg files) and the DSN, in one RAR.
I think you have a trouble of the PIC clock value ...
 

Attachments

  • Password Based Load Control partly fixed.rar
    53.9 KB · Views: 105

I only added TRISB and PORTB lines before while(1) loop.

- - - Updated - - -

A few more changes required.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
ADCON1 = 0x86;
      CMCON  = 0x07;
      CVRCON = 0x00;
      
      TRISA = 0xFF;
      TRISB = 0x00;
      TRISC = 0xFF;
      TRISD = 0x00;
      
      PORTA = 0x00
      PORTB = 0x00;
      PORTC = 0x00;
      PORTD = 0x00;

 

Milan's right, it's a problem with the IRP (pic16 !!).
CopyConst2Ram is one of the possible solutions as he wrote.
I also wrote a function (the Lcd_COut) to solve the IRP problem without copying, try it:
http://www.mikroe.com/forum/viewtop...&sid=7d360ea4036efe5bb8fabf50e0305e42#p213482

Or ... use my new LCD libraries, uploaded on LibStock. For example the LCD_CstrOut in my p16_UART1-LCDouts.mcl:
http://www.libstock.com/projects/view/952/common-output-functions

I'm IstvanK on the MikroC forum and Istvan K on Libstock.
Regards
zuisti
PS:
There are a lot of useful MikroC libraries written by me and uploaded on Libstock, for example a powerful LCD Bargraph:
http://www.libstock.com/projects/view/936/lcd-bargraph-library
An animation to show how to operate the different modes:
**broken link removed**
 
In the latest code which you posted PORTC is set as input and RCx_bits are read and also toggled. What have you interfaced to PORTC? Provide the circuit in Proteus 7.x format or PDF format.
 
Last edited:

If zuisti provided .mpkg file then download and install Package Manager from mikroE and then open .mpkg file and install. If he gave .mcl file then use Package Manager to create .mpkg file from .mcl file and then install the .mpkg file. It works only if zuisti compiled the library by selecting mikroC ICD option. You also should know for which PICs he created the .mcl file.
 

Using the "p16_OutUniv.mcl" (for example):
- copy the MCL file to your project folder
- add this library file to the project by right-clicking on the project's 'Binaries' node (see MikroC IDE help)

Study the attached example MikroC projects and the *DOC.H files (exist on every library RAR what I uploaded).

@Milan:
No, since I'm working only in Proteus, the mikroC ICD option does not selected so the hw debugging is not available. And I do not use MPKG as you can see if download one of my uploaded libraries, but there are always three variants (different libraries for ALL pic12/16, pic12/16_Enhanced and pic18 type chips). You have to use these libraries locally.

All libraries written (and uploaded) by me are fully tested (and well working) also in the real world ...
 
Last edited:

Finally with all of your help, I came to get ready the project. Here is the full code:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
/*******************************************************************************
*                   Program for 'Password Based Load Control'                  *
*                    Program Written by Engr. Mithun K. Das                    *
*                         MCU:PIC16F877A; X-Tal: 8MHz                          *
*                                 Driver:ULN2003                               *
*                                   16-May,14                                  *
*******************************************************************************/
unsigned short kp,kpp, cnt=0,cnt1=0,cnt3=0;
// Keypad module connections
char  keypadPort at PORTC;
// End Keypad module connections
char key=0;
short mode=0;
short lock=0,enable=0;
unsigned int Password1[4],password2[4],password3[4];
// LCD module connections
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RB6_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB1_bit;
 
sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB1_bit;
// End LCD module connections
 
void Lcd_COut(char row, char col, const char *cptr) 
{
  char chr = 0;             //first, it is used as empty string
  Lcd_Out(row, col, &chr);  //nothing to write but set position.
  for ( ; chr = *cptr ; ++cptr ) Lcd_Chr_CP(chr); //out in loop
}
 
void main() 
{
      ADCON1 = 0x86;
      CMCON  = 0x07;
      TRISB = 0x00;
      TRISD = 0x00;
      PORTB = 0x00;
      PORTD = 0x00;
      
  cnt = 0;                                 // Reset counter
  Keypad_Init();                           // Initialize Keypad
 
  Lcd_Init();                              // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                     // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);                // Cursor off
  Lcd_COut(1,1,"Password Based  ");
  Lcd_COut(2,1,"MultiLoad Cntrol");
  Delay_ms(1000);
  Lcd_Cmd(_LCD_CLEAR);
  cnt = 0;
  cnt1 = 0;
 
  //Read eeprom...
  if(EEPROM_Read(0)>9 || EEPROM_Read(0)<0)EEPROM_Write(0,0);
  if(EEPROM_Read(1)>9 || EEPROM_Read(1)<0)EEPROM_Write(1,0);
  if(EEPROM_Read(2)>9 || EEPROM_Read(2)<0)EEPROM_Write(2,0);
  if(EEPROM_Read(3)>9 || EEPROM_Read(3)<0)EEPROM_Write(3,0);
  if(EEPROM_Read(4)>9 || EEPROM_Read(4)<0)EEPROM_Write(4,0);
  
  
  EEPROM_Write(10,5);
  EEPROM_Write(11,5);
  EEPROM_Write(12,5);
  EEPROM_Write(13,5);
  EEPROM_Write(14,5);
  
  Delay_ms(500);
  
  password2[0] = EEPROM_Read(0);
  password2[1] = EEPROM_Read(1);
  password2[2] = EEPROM_Read(2);
  password2[3] = EEPROM_Read(3);
  password2[4] = EEPROM_Read(4);
  
 
  
  Delay_ms(50);
  while(1)
  {
       top:
 
       if(lock==0)
       {
          if(mode == 0)
          {
              Lcd_COut(1,1,"Enter Password:");
              if(cnt>3)
              {
                 Lcd_Out(2,10,"       ");
                 cnt=0;
                 
                   password2[0] = EEPROM_Read(0);
                   password2[1] = EEPROM_Read(1);
                   password2[2] = EEPROM_Read(2);
                   password2[3] = EEPROM_Read(3);
                   password2[4] = EEPROM_Read(4);
                 
                 if((Password1[1]==Password2[1]) && (Password1[2]==Password2[2]) && (Password1[3]==Password2[3]))
                 {
                    Lcd_COut(2,1,"Matched        ");
                    lock = 1;
                    Delay_ms(1000);
                    goto press;
                 }
                 else
                 {
                    Lcd_COut(2,1,"Wrong!!!        ");
                 }
              }
              else
              {
                 cnt++;
                 Lcd_Chr(2, 10+cnt, kp);                    // Print key ASCII value on LCD
                 Password1[cnt] = key;
              }
          }
 
          if(mode == 1)
          {
              Lcd_COut(1,1,"RESET Password?");
              Delay_ms(500);
              Lcd_COut(1,1,"Enter Old One  ");
              mode = 2;
              cnt3 = 0;
              Lcd_COut(2,10,"       ");
          }
          
          if(mode==2)
          {
              Lcd_COut(1,1,"Enter Old One  ");
              if(cnt3>3)
              {
                  cnt3 = 0;
                      
                       if((password3[1]==6) && (password3[2]==6) && (password3[3]==6))
                       {
                          Lcd_COut(2,1,"Matched         ");
                          mode = 3;
                          Delay_ms(500);
                       }
                       else
                       {
                          Lcd_COut(2,1,"Wrong!!!        ");
                       }
              }
              else
              {
                  cnt3++;
                  Lcd_Chr(2,10+cnt3, kp);
                  if(cnt3==1)Password3[1] = key;
                  if(cnt3==2)Password3[2] = key;
                  if(cnt3==3)Password3[3] = key;
                  if(cnt3==4)Password3[4] = key;
                  Lcd_COut(2,1,"        ");
                  Lcd_COut(2,15,"  ");
 
              }
          }
          
          if(mode==3)
          {
              Lcd_COut(1,1,"Enter New One   ");
              if(cnt1>4)
              {
                 Lcd_COut(2,9,"         ");
                 cnt1=0;
                 Delay_ms(100);
                 Lcd_Cmd(_LCD_CLEAR);
                 Lcd_COut(1,1,"Password");
                 Lcd_COut(2,1,"Changed...");
 
                 Delay_ms(1000);
                 Lcd_Cmd(_LCD_CLEAR);
                 mode = 0;
                 cnt = -1;
                 lock = 0;
                 kp =0;
                 Delay_ms(200);
                 cnt3 = 0;
                 enable = 0;
                 goto top;
              }
              else
              {
                 cnt1++;
                 Lcd_Chr(2, 10+cnt1, kp);   // Print key ASCII value on LCD
                 Password2[cnt1] = key;
                 EEPROM_Write(0,password2[0]);
                 EEPROM_Write(1,password2[1]);
                 EEPROM_Write(2,password2[2]);
                 EEPROM_Write(3,password2[3]);
                 EEPROM_Write(4,password2[4]);
                 Delay_ms(100);
                 password2[0] = EEPROM_Read(0);
                 password2[1] = EEPROM_Read(1);
                 password2[2] = EEPROM_Read(2);
                 password2[3] = EEPROM_Read(3);
                 password2[4] = EEPROM_Read(4);
              }
          }
 
       }
       else
       {
           press:
           Lcd_Cmd(_LCD_CLEAR);
           Lcd_Out(1,1,"PRESS A/B/C/D");
           if(key==4) RD7_bit=~RD7_bit;//pressed A
           if(key==8) RD6_bit=~RD6_bit;//pressed A
           if(key==12) RD5_bit=~RD5_bit;//pressed A
           if(key==16) RD4_bit=~RD4_bit;//pressed A
           if(key==13 || key == 15) lock = 0;//checked if */# is pressed
       }
 
      kp = 0; // Reset key code variable
      // Wait for key to be pressed and released
      do
      kp = Keypad_Key_Click();             // Store key code in kp variable
      while (!kp);
      key = kp;
      if(key==13) mode = 0;
      if(key==15) mode = 1;
 
     // Prepare value for output, transform key to it's ASCII value
      switch (kp)
      {
        case  1: kp = 49; break; // 1        // Uncomment this block for keypad4x4
        case  2: kp = 50; break; // 2
        case  3: kp = 51; break; // 3
        case  5: kp = 52; break; // 4
        case  6: kp = 53; break; // 5
        case  7: kp = 54; break; // 6
        case  9: kp = 55; break; // 7
        case 10: kp = 56; break; // 8
        case 11: kp = 57; break; // 9
        case 12:  break; // C
        case 14: kp = 48; break; // 0
      }
 
  }//while(1)
}//void
 
 
 
/*******************************************************************************
*                                                                              *
*                              End Of the Program                              *
*                                                                              *
*                                                                              *
*******************************************************************************/




Usually I use small functions in my code. But in this project I did as normal arrangement as I'd to change the code many many times.

And thanks all of you.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top