PIC16F873A Problem with code

Thread Starter

André Ferrato

Joined Apr 5, 2015
215
Hi, i'm trying to make a "Fake Bomb" for my airsoft games, so the idea is, an LCD, a 4x4 keypad, 2 buzzers, 3 LEDS to indicate the times you can miss the password before the bomb "explodes". I'll be attaching the Proteus file( Please note it's note complete, i'm testing parts of the code and implementing hardware to simulate as the code goes).

I managed to implement the timer of the bomb, using tmr0 function of PIC. It was not a trouble, the two buttons ADJUST + and ADJUST - , sets the minutes and only sets when the timer is off ( the flag for the timer is flags.b5), if pressed enter when timer is off, timer goes on.

I haven't implemented the features that happen when timer is over yet.

My main problem is the password, i was working on some way to get the pressed number using a variable called kp that gets the number of the key that was pressed, store in some variable and them compare this variable with another variable that had the real password. So if those 2 match, it would disarm the bomb, if the user miss the password for 3 times, the bombs goes boom :)

And i couldn't find a way to! The code was almost working, but suddenly it stopped, it started acting weird. I marked the function that was working and started acting weird as "<-- TROUBLESOME FUNCTION" in the code, so you guys could take a look.

Also i did not implement anything related to what happens when the user misses 3 times, or what happens when the user press the "CLEAN" key that you guys will notice i tagged in PROTEUS. I'm just trying to get the password working first.

Can anyone help me ? This is the first code i write, so please forgive for anything.

Also where can i upload the proteus files and MikroC files so anyone could take a look, the extensions are not allowed as attachments!


C:
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

#define col_4   RC0_bit
#define row_A   RC1_bit
#define row_B   RC2_bit
#define row_C   RC3_bit
#define row_D   RC4_bit
#define col_1   RC5_bit
#define col_2   RC6_bit
#define col_3   RC7_bit


char senha_usuario[4] ;
char senha_memoria[4] ;
int cnt_cliques = 0;
char kp = 17;
char kp_saved;

char i;


char cnt_tentativas = 0;             // tracking block


char cnt=0;                          // timer0
short minutos = 0, segundos = 0;     //
char control = 1;                    // keypad iteration variable

char flags = 0;                      // flags.b5 = assigned to the timer
                                     // flags.b4 = assigned to NEW PASSWORD button, to see if it was pressed
                                     //
                                     //
                                     //


char *textos[2] = {                  // texts to be displayed
                  "ATVD",
                  "DSTV",
                  };

char *Ptr1;                          // variable to display the texts




void key_pressed(char ReturnedValue)  // gets the value from the interrupt function
{
kp = ReturnedValue;
}



void interrupt()
{
  PORTB.RB6 = ~PORTB.RB6;
  INTCON.TMR0IF = 0;
  TMR0=100;

  if(col_1 && control == 0x01)        //if column is high and control variable is 1
      {
         control = 0x02;
         col_1 = 0x00;                    // only column 1 in low level, and so goes on
         col_2 = 0x01;
         col_3 = 0x01;
         col_4 = 0x01;

         if(!row_A)     key_pressed(1);
         else if(!row_B) key_pressed(4);
         else if(!row_C) key_pressed(7);
         else if(!row_D) key_pressed(11);  // CLEAN

      }
      else if(col_2 && control == 0x02)
      {
         control = 0x03;
         col_1 = 0x01;
         col_2 = 0x00;
         col_3 = 0x01;
         col_4 = 0x01;

         if(!row_A)      key_pressed(2);
         else if(!row_B) key_pressed(5);
         else if(!row_C) key_pressed(8);
         else if(!row_D) key_pressed(0);

      }
      else if(col_3 && control == 0x03)
      {
         control = 0x04;
         col_1 = 0x01;
         col_2 = 0x01;
         col_3 = 0x00;
         col_4 = 0x01;

         if(!row_A)      key_pressed(3);
         else if(!row_B) key_pressed(6);
         else if(!row_C) key_pressed(9);
         else if(!row_D) key_pressed(12);   //ENTER

      }
      else if(col_4 && control == 0x04)
      {
         control = 0x01;
         col_1 = 0x01;
         col_2 = 0x01;
         col_3 = 0x01;
         col_4 = 0x00;

         if(!row_A)      key_pressed(13);    // not used
         else if(!row_B) key_pressed(14);    // new password
         else if(!row_C) key_pressed(15);    // adjust +
         else if(!row_D) key_pressed(16);    // adjust -

      }

  if(flags.b5)    // if flags.b5 is high, start the cnt variable, start counting time for the bomb
              {
              cnt++;
              if(cnt >= 50)
                     {
                     cnt = 0;
                     segundos--;
                     if(segundos<0)
                                   {
                                   segundos = 59;
                                   minutos--;
                                   if(minutos<0)
                                                {
                                                minutos = 0;
                                                segundos = 0;
                                                flags.b5= 0;
                                                }
                                   }
                     }
              }
} //end interrupt





void main()
{
  TRISB = 0b00000000;               // ports b as OUTPUTS
  TRISC = 0b00011110;               //                                      port C B0,B5,B6,B7 are OUTPUTS
                                    //                                             B1,B2,B3,B4 are INPUTS
  TRISA = 0b00000000;               // ports a as OUTPUTS
  //PORTC = 0b00000000;             // all ports C starts low
  PORTA = 0b00000000;               // all ports A starts low
  OPTION_REG = 0b000000110;         // prescaler 1:64
  CMCON = 0b11111111;               // analog comp off
  INTCON.GIE = 1;                   // global interruption enabled
  INTCON.TMR0IE = 1;                // tmr0 interruption enabled
  INTCON.TMR0IF = 0;                // sets tmr0 interruption flag
  TMR0 = 100;                       // offset of tmr0
  ADCON1 = 0;                       // analog ports off

  Lcd_Init();                       // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  Lcd_Cmd(_LCD_BLINK_CURSOR_ON);
  Lcd_Out(1,1, "Timer:");
  Lcd_Out(2,1, "SENHA:");

  Ptr1 = textos[1];

  senha_memoria[1] = 1;
  senha_memoria[2] = 2;
  senha_memoria[3] = 3;
  senha_memoria[4] = 4;

  while(1)
  {

if(kp == 14 && flags.b5 == 0)                        // sets NEW PASSWORD button flag
                   {
                    flags.b4 = 1;
                    kp = 17;        // resets kp value, so it won't trigger any other events
                    delay_ms(200);  // debounces the keypad, 200 miliseconds is fine, and it won't matter when the user operates it
                   }

if(kp == 15 && flags.b5 == 0)                        // if adjust + is pressed and timer is off
                   {
                   minutos++;
                   delay_ms(200);
                   kp = 17;
                      if(minutos>99)
                      {
                      minutos = 00;
                      }
                   }

else if(kp == 16 && flags.b5 == 0)                  // if adjust - is pressed and timer is off
                   {
                   minutos--;
                   delay_ms(200);
                   kp = 17;
                         if(minutos <0)
                         {
                          minutos = 99;
                         }

                   }

else if(kp == 12)                  // if ENTER is pressed
                    {
                                   if(flags.b5 == 0 && minutos > 0 && flags.b4 == 0)
                                   {
                                   flags.b5 = 1;
                                   Ptr1 = textos[0];
                                   }

                    delay_ms(200);
                    kp = 17;
                    }



else if( kp >= 0 && kp <=9)                        // if any number is pressed in the keypad  <-- TROUBLESOME FUNCTION
                     {
                      kp_saved = kp;
                      kp = 17;
                      delay_ms(200);

                      if(cnt_cliques == 1)
                                     {
                                      Lcd_Out(2,8, "*");
                                      senha_usuario[cnt_cliques] = kp_saved ;
                                      cnt_cliques++;
                                      delay_ms(200);

                                     }

                     else if(cnt_cliques == 2 && kp >= 0 && kp <= 9)
                          {
                           Lcd_Out(2,9,"*");
                           senha_usuario[cnt_cliques] = kp_saved ;
                           cnt_cliques++;
                           delay_ms(200);

                          }

                     else if(cnt_cliques == 3  && kp >= 0 && kp <= 9)
                              {
                               Lcd_Out(2,10,"*");
                               senha_usuario[cnt_cliques] = kp_saved ;
                               cnt_cliques++;
                               delay_ms(200);

                              }

                     else if(cnt_cliques == 4  && kp >= 0 && kp <= 9)
                               {
                                Lcd_Out(2,11,"*");
                                senha_usuario[cnt_cliques] = kp_saved ;
                                cnt_cliques++;
                                delay_ms(200);

                               }




                     } // end else if das teclas




  Lcd_Out(1,13, Ptr1);
  Lcd_Chr( 1, 7, minutos / 10 + '0' );
  Lcd_Chr_CP( minutos % 10 + '0' );
  if( flags.B0 && segundos.B0 ) // makes : blinks every second
  Lcd_Chr_CP( ' ' );
  else
  Lcd_Chr_CP( ':' );
  Lcd_Chr_CP( segundos / 10 + '0' );
  Lcd_Chr_CP( segundos % 10 + '0' );

} //end while
} //end main
 
Last edited by a moderator:

AlbertHall

Joined Jun 4, 2014
12,347
At the start of the 'troublesome function' section you have a line 'kp = 17' so after that all the tests 'if kp>=0 && kp<=9' are going to fail.
 

Thread Starter

André Ferrato

Joined Apr 5, 2015
215
And they should, because kp = 17 resets the key pressed, if it doesnt reset, the if statements goes on, it should only enter the first loop and then exit.
 

AlbertHall

Joined Jun 4, 2014
12,347
So the code in lines from 246 to 271 will never be executed as the 'if' condition will always be false. What are those lines for?
 

JohnInTX

Joined Jun 26, 2012
4,787
At line 230 try:
else if (( kp >= 0) && (kp <=9))

Relational operators have a lower precedence than arithmetic or logical operators so I don't think your expression is being evaluated like you want.
 
Last edited:
Top