title: LCD not working properly with PIC16F877A using mikroc development
body: <p>I've been designing a simple traffic signal code using a PIC microcontroller, it's supposed to have a control panel with which you input the timing for each traffic light, to make it more secure I added a password to stop anyone from messing with the timing.</p>
  
  <p>I used Proteus 8 for simulation. The problem happens is sometimes when I print out something on the LCD it comes out incorrect, and I still can't identify why this happens. when the red timing is inputted and yellow starts this shows up:
  <a href="http://i.stack.imgur.com/lnbrI.png" rel="nofollow">http://i.stack.imgur.com/lnbrI.png</a></p>
  
  <p>and the same thing happens for the green timing, I tried instead of inputting the string automatically to put it in a variable first, research didn't get anything specific to my problem!
  here's my code:</p>
  
  <pre><code>char kp;
  char entry[16];
  int i = 0;
  char password[] = "12345";
  char *Redd = "Red";
  char *Yelloww = "Yellow";
  char *Greenn = "Green";
  int Red;
  
  int Green;
  int Yellow;
  char test[5];
  
  
  sbit LCD_RS at RD4_bit;
  sbit LCD_EN at RD6_bit; 
  sbit LCD_D4 at RD0_bit;
  sbit LCD_D5 at RD1_bit;
  sbit LCD_D6 at RD2_bit;
  sbit LCD_D7 at RD3_bit;
  
  sbit LCD_RS_Direction at TRISD4_bit;
  sbit LCD_EN_Direction at TRISD6_bit;
  sbit LCD_D4_Direction at TRISD0_bit;
  sbit LCD_D5_Direction at TRISD1_bit;
  sbit LCD_D6_Direction at TRISD2_bit;
  sbit LCD_D7_Direction at TRISD3_bit;
  
  char keypadPort at PORTB;
  
  
  
  char keypadchar () {
    int key = 0;
    while (!key) key = Keypad_Key_Click();
    switch (key) {
      case 1: return '1'; break;
      case 2: return '2'; break;
      case 3: return '3'; break;
      case 5: return '4'; break;
      case 6: return '5'; break;
      case 7: return '6'; break;
      case 9: return '7'; break;
      case 10: return '8'; break;
      case 11: return '9'; break;
      case 13: return '*'; break;
      case 14: return '0'; break;
      case 15: return '#'; break;
    }
  }
  
  void inputPassword() {
    int count = 0;
    i = 0;
    Lcd_out(1,1,"Enter Password");
    lcd_cmd(_LCD_SECOND_ROW);
    while(1) {
      kp = keypadchar();
      if (kp != '*' &amp;&amp; kp != '#' &amp;&amp; count &lt; 15) {
        Lcd_Chr_Cp('*');
        while(entry[i]!=0) i++;    // break when find NULL
        entry[i] = kp;     // insert char where NULL was
        entry[i+1] = 0;   // and insert new NULL after it
        i = 0;
        count++;
      } else if (kp == '*') {
        if (strlen(entry) != 0) {
          LCD_Cmd(_LCD_MOVE_CURSOR_LEFT);
          Lcd_Chr_Cp(' ');
          LCD_Cmd(_LCD_MOVE_CURSOR_LEFT);
          while(entry[i]!=0) i++;    // break when find NULL
          entry[i-1] = 0;     // insert Null
          i = 0;
          count--;
        }
      } else if (kp == '#') {
        if (strlen(entry) != 0)
          if (strcmp(password,entry) == 0) {
            Lcd_out(2,1,"Password Correct  ");
            while(entry[i]!=0) {
              entry[i] = 0;
              i++;
            }
            i = 0;
            break;
          }
          else {
            Lcd_out(2,1,"Wrong password  ");
            delay_ms(1000);
            Lcd_out(2,1,"                  ");
            Lcd_out(2,1,"");
            while(entry[i]!=0) {
              entry[i] = 0;
              i++;
            }
            count = 0;
            i = 0;
          }
      }
    }
  }
  
  int entertiming(char *colorN) {
    int count = 0;
    i = 0;
    LCD_Cmd(_LCD_CLEAR);
    delay_ms(1);
    strcat(colorN," timing");
    delay_ms(1);
    LCD_Out(1,1,colorN);
    delay_ms(1);
    LCD_Cmd(_LCD_SECOND_ROW);
    while(entry[i]!=0) {
      entry[i] = 0;
      i++;
    }
    i = 0;
    while(1) {
      kp = keypadchar();
      if (kp != '*' &amp;&amp; kp != '#' &amp;&amp; count &lt; 3) {
        Lcd_Chr_Cp(kp);
        while(entry[i]!=0) i++;    // break when find NULL
        entry[i] = kp;     // insert char where NULL was
        entry[i+1] = 0;   // and insert new NULL after it
        i = 0;
        count++;
      } else if (kp == '*') {
        if (strlen(entry) != 0) {
          LCD_Cmd(_LCD_MOVE_CURSOR_LEFT);
          Lcd_Chr_Cp(' ');
          LCD_Cmd(_LCD_MOVE_CURSOR_LEFT);
          while(entry[i]!=0) i++;    // break when find NULL
          entry[i-1] = 0;     // insert Null
          i = 0;
          count--;
        }
      } else if (kp == '#') {
        if (strlen(entry) != 0)
          return atoi(entry);
      }
    }
  }
  
  void startcountdown(int time) {
    while (time &gt;= 0) {
      wordtostr(time,test);
      lcd_out(2,1,test);
      time--;
      delay_ms(1000);
      }
    } 
  
  void main () {
    Keypad_init();
    Lcd_init();
    LCD_Cmd(_LCD_CLEAR) ;
    LCD_Out(1, 1, "Hello!") ;
    Lcd_Cmd(_LCD_SECOND_ROW);
    delay_ms(1000);
    while(1) {
      inputPassword();
      delay_ms(1);
      Red = entertiming(Redd);
      delay_ms(1);
      Yellow = entertiming(Yelloww);
      delay_ms(1);
      Green = entertiming(Greenn); 
      while(1) {
        Lcd_cmd(_LCD_CLEAR);
        Lcd_Out(1,1,"Red");
        startcountdown(Red);
        Lcd_cmd(_LCD_CLEAR);
        Lcd_Out(1,1,"Yellow");
        startcountdown(Yellow);
        Lcd_cmd(_LCD_CLEAR);
        Lcd_Out(1,1,"Green");
        startcountdown(Green);
        }
     }
  }
  </code></pre>
  
  <p><strong>Edit:</strong> I edited the code with a more recent one, following the suggestions in the comments, I also completed the code except for one small piece, the inner while loop that keeps the countdown should have a break command that happens when an interrupt occurs to change the values of the red/yellow/green timing .. <strong>and a new problem showed up</strong>, the yellow reading I get is always converted to 0! no matter what number I input</p>
  
  <p><strong>Second Edit:</strong> When I change the sequence of the Red, Yellow, Green functions some sequences work and some doesn't this doesn't make sense</p>