1. 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.
    Dismiss Notice

READING A PUSHBUTTON & display on LCD

Discussion in 'Microcontrollers' started by fantabulous68, Sep 9, 2009.

  1. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    I recently got a pikit 2, its the 1st time that im using push button switches.
    im using 4 pushbuttons. when i power the circuit The LCD displays "infrared liquid level detector" permanently, so the lcd code and initialising is working.

    All i want for now is:

    when i press ENTER/Settings button....i want "enter/settings" to display on the LCD. And that is not happening when i press the button. Please help me solve this problem....i attached a picture of how i connect the switch to the pic.


    Code (text):

    #include <pic.h>
    #include "pic.h"
    #include "delay.h"
    #include "math.h"
    #include <stdio.h>
    #include <stdlib.h>


    char input_sw;
    #define HOME_SW RC2             //HOME switch  
    #define INCREASE_SW RC3         //INCREASE switch
    #define DECREASE_SW RC4         //DECREASE switch
    #define ENTERSETTINGS_SW RA4        //ENTERSETTINGS switch

    void init(void)
    {  

        OSCCON|=0x60; //set fosc to 4Mhz
        TRISB=0x00;
        TRISC=0xFC;
            TRISA = 0b10000010;     // RA7 high imp, RA3 is serial out,
        ANSEL=0x02;            //set RA1 as analog input for GP2 sensor
        ANSELH=0x00;
        lcd_init(); //call LCD initialisation
    }

     void read_input_sw(void)
    {
     char input_sw2;
     input_sw = ((HOME_SW*8)+(INCREASE_SW*4)+(DECREASE_SW*2)+(ENTERSETTINGS_SW*1)); //create a binary combination of the input switches
     if (input_sw != 0) //check if any of the switches are pressed
        {
         DelayMs(20); //switch debouncing
         input_sw2 = ((HOME_SW*8)+(INCREASE_SW*4)+(DECREASE_SW*2)+(ENTERSETTINGS_SW*1));
         while (input_sw2 != 0) //if a switch is pressed wait for release
                {
                 input_sw2 = ((HOME_SW*8)+(INCREASE_SW*4)+(DECREASE_SW*2)+(ENTERSETTINGS_SW*1));
                 DelayMs(20); //switch debouncing
                }
         }
    }
     
       
    [COLOR="Red"]void home_screen(void)[/COLOR]
    {
        lcd_clear();
        lcd_goto_L1();
        [COLOR="Red"]lcd_puts("INFRARED LIQUID"); //home screen message (line 1)[/COLOR]
        lcd_goto_L2();
    [COLOR="Red"]   lcd_puts("LEVEL DETECTOR"); //home screen message (line 2)[/COLOR]

        read_input_sw();
        while(input_sw == 0)

            read_input_sw();
            switch(input_sw)
        {
            case 8: break; 
            //  ENTER/SETTINGS  button pressed 
            case 1: {   lcd_clear();
                        lcd_goto_L1();
            [COLOR="Red"]            lcd_puts(" ENTER/SETTINGS ");[/COLOR]
                        DelayS(1);
                        lcd_clear();
                       
                        break;
                    }
                       default : break; //should any abnormalties occur
        }
        return;
    }


    void main(void)
    {
        init(); // initialise I/O ports, LCD
        while (1)
        {
        home_screen();
       
        }
         
    }
       
     

    Attached Files:

    Last edited: Sep 9, 2009
  2. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    If thats how the buttons are wired then you have to check for a LOW signal.

    like ..

    Code (text):

    char WaitForInput(void){
    char done;
    char temp;
    done = 0;

    while(!done){
        if(!ENTERSETTINGS_SW){
            temp = 1;
            done = 0xff;
        }

        if(!HOME_SW){
            temp = 2;
            done = 0xff;
        }

        if(!INCREASE_SW){
            temp = 3;
            done = 0xff;
        }

        if(!DECREASE_SW){
            temp = 4;
            done = 0xff;
        }
    }//end of while
        DelayMs(20);    //debounce
        return temp;
    }
     
    and do this for calling in your main code:

    Code (text):

    if(WaitForInput = 1){
        //This is where you put code if the user pressed ENTER
    }

    if(WaitForInput = 2){
        //This is where you put code if the user pressed Home
    }

    if(WaitForInput = 3){
        //This is where you put code if the user pressed Increase
    }

    if(WaitForInput = 4){
        //This is where you put code if the user pressed Decrease
    }
     
    or
    Code (text):

    switch(WaitForInput){
        case 1:
            //User Pressed ENTER do something
            break;
        case 2:
            //User Pressed HOME do something
            break;
        case 3:
            //User Pressed INCREASE do something
            break;
        case 4:
            //User Pressed DECREASE do something
            break;
    }
     
     
    Last edited: Sep 9, 2009
  3. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    Thanks ALOT AtomSoft...Im going to try that out now....
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US

    heh no problem.

    This would be the same but smoother:
    Code (text):

    char WaitForInput(void){
      char temp;

      while(1){
        if(!ENTERSETTINGS_SW){
            temp = 1;
            break;
        }

        if(!HOME_SW){
            temp = 2;
            break;
        }

        if(!INCREASE_SW){
            temp = 3;
            break;
        }

        if(!DECREASE_SW){
            temp = 4;
            break;
        }
      }//end of while
        DelayMs(20);    //debounce
        return temp;
    }

     
     
    Last edited: Sep 9, 2009
  6. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    Uhmm its giving an error

    illegal type for switch expression
    illegal conversion of integer to pointer

    Code (text):

    [COLOR="Red"]switch(WaitForInput){[/COLOR]
    [COLOR="DarkOrchid"]    case 1:[/COLOR]
            //User Pressed ENTER do something
            break;
    [COLOR="DarkOrchid"]    case 2:[/COLOR]
            //User Pressed HOME do something
            break;
    [COLOR="DarkOrchid"]    case 3:[/COLOR]
            //User Pressed INCREASE do something
            break;
    [COLOR="DarkOrchid"]    case 4:[/COLOR]
            //User Pressed DECREASE do something
            break;
    }
     
    Last edited: Sep 9, 2009
  7. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    oops try this:

    Code (text):

    switch(WaitForInput()){
        case 1:
            //User Pressed ENTER do something
            break;
        case 2:
            //User Pressed HOME do something
            break;
        case 3:
            //User Pressed INCREASE do something
            break;
        case 4:
            //User Pressed DECREASE do something
            break;
    }

     
    if that fails then simply:

    Code (text):

    input_sw = WaitForInput();

    switch(input_sw){
        case 1:
            //User Pressed ENTER do something
            break;
        case 2:
            //User Pressed HOME do something
            break;
        case 3:
            //User Pressed INCREASE do something
            break;
        case 4:
            //User Pressed DECREASE do something
            break;
    }
     
     
    Last edited: Sep 9, 2009
    • Like Like x 1
  8. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    hehe, the 1st 1 worked, now for the lol testing it on the circuit;)
     
  9. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    heh good luck. I leave in about 1 hours for errands then come home then wait about 1 hours till i have to goto work. so enjoy and have fun. and if you need help ill try to post .
     
  10. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    yay lol getting somewhere:). i tested it now.

    when i power up without pressing switches it displays:

    infrared liquid level detector
    clears then
    enter/settings
    clears then
    infrared liquid level detector
    clears then
    enter/settings

    and keeps doing this.......


    when i press the home button down continuously :
    it displays
    "infrared liquid level detector" continuously

    thats correct because the home button takes you to the home screen

    when i release the home button then:

    infrared liquid level detector
    clears then
    enter/settings
    clears then
    infrared liquid level detector
    clears then
    enter/settings

    and keeps doing this.......


    uhmm im going to play around to see if i can get it to stay at enter/settings screen
     
  11. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    Thanks again n again n again:). Im very happy now....that im seeing some progress.
    Going to continue to make all the buttons work now. ill b back:)for sure
     
    Last edited: Sep 9, 2009
  12. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    heh was bored and about to leave but i have a gift

    Code (text):

    #include <pic.h>
    #include "pic.h"
    #include "delay.h"
    #include "math.h"
    #include <stdio.h>
    #include <stdlib.h>

    char input_sw;
    char mnuPOS;

    unsigned char MyVal;
    unsigned char MyValLCD[2];
    unsigned char MyMaxVal;
    unsigned char MyMinVal;

    #define HOME_SW RC2             //HOME switch  
    #define INCREASE_SW RC3         //INCREASE switch
    #define DECREASE_SW RC4         //DECREASE switch
    #define ENTERSETTINGS_SW RA4        //ENTERSETTINGS switch

    void init(void);
    char WaitForInput(void);
    void home_screen(void);
    void EnterScreen(void);
    void ShowDigits(unsigned char val);
    void main(void);

    void init(void)
    {  

        OSCCON|=0x60; //set fosc to 4Mhz
        TRISB=0x00;
        TRISC=0xFC;
            TRISA = 0b10000010;     // RA7 high imp, RA3 is serial out,
        ANSEL=0x02;            //set RA1 as analog input for GP2 sensor
        ANSELH=0x00;
        lcd_init(); //call LCD initialisation
    }

    char WaitForInput(void){
      char temp;

      while(1){
        if(!ENTERSETTINGS_SW){
            temp = 1;
            break;
        }

        if(!HOME_SW){
            temp = 2;
            break;
        }

        if(!INCREASE_SW){
            temp = 3;
            break;
        }

        if(!DECREASE_SW){
            temp = 4;
            break;
        }
      }//end of while
        DelayMs(20);    //debounce
        return temp;
    }
       
    void home_screen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts("INFRARED LIQUID"); //home screen message (line 1)
        lcd_goto_L2();
        lcd_puts("LEVEL DETECTOR"); //home screen message (line 2)
    }

    void EnterScreen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" ENTER/SETTINGS ");
        DelayS(1);
        lcd_clear();
    }

    void ShowDigits(unsigned char val){

        MyValLCD[0] = val /10;    //returns the quotient (if temp = 35 the result is 3)
        MyValLCD[1] = val % 10;     //Returns remainder   (if temp = 35 the result is 5)

        MyValLCD[0] += 0x30;    //to ASCII
        MyValLCD[1] += 0x30;    //to ASCII

        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" ENTER/SETTINGS ");
        lcd_goto_L2();
        lcd_data(MyValLCD[0]);  //to LCD
        lcd_data(MyValLCD[1]);  //to LCD
    }

    void main(void)
    {
        init(); // initialise I/O ports, LCD
        home_screen();

        MyVal = 0;
        MyMinVal = 0;
        MyMaxVal = 99;

    while(1){
        input_sw = WaitForInput();

        switch(input_sw){
          case 1:
            EnterScreen();
            mnuPOS = 1;
            break;
          case 2:
            home_screen();
            mnuPOS = 2;
            break;
        }
       
        while(mnuPOS == 1){
            input_sw = WaitForInput();
           
          switch(input_sw){
            case 1:
                mnuPOS = 2;
                home_screen();
                break;
            case 3:
                if(MyVal < MyMaxVal)
                    MyVal++;
                ShowDigits(MyVal);
                break;
            case 4:
                if(MyVal > MyMinVal)
                    MyVal--;
                ShowDigits(MyVal);
                break;
          }
        }
       
        //Do something here with the new Value which is a decimal in MyVal.
    }

         
    }



     
     
  13. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    Hehe, that was a nice surprise:) when i logged in again. Thanks lol i hope you not counting how many times i said that :rolleyes: I tried the code. i commented home screen() in the main code otherwise it only displays infra red liquid level detector and ignores the button presses.

    Code (text):
    void main(void)
    {
        init(); // initialise I/O ports, LCD
        //home_screen();

    ALSO
    it works when i replace:


    Code (text):
    char WaitForInput(void){
      char temp;

      while(1){
        if(!ENTERSETTINGS_SW){
            temp = 1;
            break;
        }

        if(!HOME_SW){
            temp = 2;
            break;
        }

        if(!INCREASE_SW){
            temp = 3;
            break;
        }

        if(!DECREASE_SW){
            temp = 4;
            break;
        }
      }//end of while
        DelayMs(20);    //debounce
        return temp;
    }
     

    with:

    Code (text):
    char WaitForInput(void){
    char done;
    char temp;
    done = 0;

    while(!done){
        if(!ENTERSETTINGS_SW){
            temp = 1;
            done = 0xff;
        }

        if(!HOME_SW){
            temp = 2;
            done = 0xff;
        }

        if(!INCREASE_SW){
            temp = 3;
            done = 0xff;
        }

        if(!DECREASE_SW){
            temp = 4;
            done = 0xff;
        }
    }//end of while
        DelayMs(20);    //debounce
        return temp;
    }
     
    if i dont replace it then pressing the buttons has no affect...it keeps displaying "enter/settings"



    when i replace it and power on:


    "enter/settings" is displayed continuously

    when i press home button: infra red liquid level detect is displayed.
    it does not display the full word "detector"

    when i release home button: "enter/settings" is displayed continuously


    when i press increase button: the screen remains blank
    when i release increase button:"enter/settings" is displayed continuously
    uhmmm it does not show the number of times the button is pressed on the LCD

    when i press decrease button: the screen remains blank
    when i release decrease button:"enter/settings" is displayed continuously
    it does not show the number of times the button is pressed on the LCD

    when i press home/settings button:"enter/settings" is displayed continuously
    when i release home/settings button:"enter/settings" is displayed continuously
     
    Last edited: Sep 9, 2009
  14. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    im thinking maybe this:

    Code (text):
    lcd_data(MyValLCD[0]);  //to LCD
    lcd_data(MyValLCD[1]);  //to LCD
    is affecting the "detect" word from being "detector".

    i was bread boarding a switch mode power supply-boost regulator
    3.2V to 5V, im waiting for the batteries to charge so i can test it...hehe.
     
  15. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    that should not affect the other text.
    Can you post full code?
    Try this:
    Code (text):

    #include <pic.h>
    #include "pic.h"
    #include "delay.h"
    #include "math.h"
    #include <stdio.h>
    #include <stdlib.h>

    char input_sw;
    char mnuPOS;

    unsigned char MyVal;
    unsigned char MyValLCD[2];
    unsigned char MyMaxVal;
    unsigned char MyMinVal;

    #define HOME_SW RC2             //HOME switch  
    #define INCREASE_SW RC3         //INCREASE switch
    #define DECREASE_SW RC4         //DECREASE switch
    #define ENTERSETTINGS_SW RA4        //ENTERSETTINGS switch

    void init(void);
    char WaitForInput(void);
    void home_screen(void);
    void EnterScreen(void);
    void ShowDigits(unsigned char val);
    void main(void);

    void init(void)
    {  

        OSCCON|=0x60; //set fosc to 4Mhz
        TRISB=0x00;
        TRISC=0xFC;
            TRISA = 0b10000010;     // RA7 high imp, RA3 is serial out,
        ANSEL=0x02;            //set RA1 as analog input for GP2 sensor
        ANSELH=0x00;
        lcd_init(); //call LCD initialisation
    }

    char WaitForInput(void){
    char done;
    char temp;
    done = 0;

    while(!done){
        if(!ENTERSETTINGS_SW){
            temp = 1;
            done = 0xff;
        }

        if(!HOME_SW){
            temp = 2;
            done = 0xff;
        }

        if(!INCREASE_SW){
            temp = 3;
            done = 0xff;
        }

        if(!DECREASE_SW){
            temp = 4;
            done = 0xff;
        }
    }//end of while
        DelayMs(150);    //debounce
        return temp;
    }

       
    void home_screen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts("INFRARED LIQUID "); //home screen message (line 1)
        lcd_goto_L2();
        lcd_puts("LEVEL DETECTOR  "); //home screen message (line 2)
    }

    void EnterScreen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" ENTER/SETTINGS ");
        DelayS(1);
        lcd_clear();
    }

    void ShowDigits(unsigned char val){

        MyValLCD[0] = val /10;    //returns the quotient (if temp = 35 the result is 3)
        MyValLCD[1] = val % 10;     //Returns remainder   (if temp = 35 the result is 5)

        MyValLCD[0] += 0x30;    //to ASCII
        MyValLCD[1] += 0x30;    //to ASCII

        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" ENTER/SETTINGS ");
        lcd_goto_L2();
        lcd_data(MyValLCD[0]);  //to LCD
        lcd_data(MyValLCD[1]);  //to LCD
    }

    void main(void)
    {
        init();         // initialise I/O ports, LCD
        DelayMs(20);    // init delay
        home_screen();  //display home screen

        MyVal = 0;
        MyMinVal = 0;
        MyMaxVal = 99;

        mnuPOS = 2;
    while(1){
        input_sw = WaitForInput();

        switch(input_sw){
          case 1:
            EnterScreen();
            mnuPOS = 1;
            break;
          case 2:
            home_screen();
            mnuPOS = 2;
            break;
        }
       
        while(mnuPOS == 1){
            input_sw = WaitForInput();
            DelayMs(50);    //debounce #2 for a total of 200ms (user can press button 5 times in 1 second)
           
          switch(input_sw){
            case 1:
                mnuPOS = 2;
                home_screen();
                break;
            case 3:
                if(MyVal < MyMaxVal)
                    MyVal++;
                ShowDigits(MyVal);
                break;
            case 4:
                if(MyVal > MyMinVal)
                    MyVal--;
                ShowDigits(MyVal);
                break;
          }
        }
       
        //Do something here with the new Value which is a decimal in MyVal.
    }

         
    }
     
     
  16. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    Heres the code i used and remarked on

    Code (text):
    #include <pic.h>
    #include "pic.h"
    #include "delay.h"
    #include "math.h"
    #include <stdio.h>
    #include <stdlib.h>
     
    void FloatToStr(float , char[]);
    void DelayMs(unsigned char);
    void lcd_cmd(unsigned char);
    void lcd_data(unsigned char);
    void lcd_clear(void);
    void lcd_puts(const char[]);
    void lcd_goto_L1(void);
    void lcd_goto_L2(void);
    void lcd_cursor(unsigned char);
    void lcd_init(void);

    void init(void);
    char WaitForInput(void);
    void home_screen(void);
    void EnterScreen(void);
    void ShowDigits(unsigned char val);
    void main(void);



    void calc_distance(void);

         

    #define LCD_RS RC0      //LCD RS pin
    #define LCD_EN RC1      //LCD EN pin
    #define LCD_STROBE()    LCD_EN = 1; asm("nop"); asm("nop"); LCD_EN = 0

    unsigned char cm10;     //
    unsigned char cm;       //
    unsigned int math;      // used for voltage calculations
    unsigned char NumDec;
    unsigned char NumSep[2];
       
    unsigned char i,j,k;
    char temp[8];
    int height=50, SensorPos=10;
    char input_sw;

     
    char mnuPOS;

    unsigned char MyVal;
    unsigned char MyValLCD[2];
    unsigned char MyMaxVal;
    unsigned char MyMinVal;



    #define HOME_SW RC2             //HOME switch  
    #define INCREASE_SW RC3         //INCREASE switch
    #define DECREASE_SW RC4         //DECREASE switch
    #define ENTERSETTINGS_SW RA4    //ENTERSETTINGS switch








    [COLOR="Purple"]///////////////////////CONVERT FLOAT TO STRING///////////////////[/COLOR]
    // This function was taken from the CAVR library. It was modified slightly
    // to suit our design.
    void FloatToStr(float n, char str[])
    {
    float scale;
    unsigned char d,f;
    f=0;i=0;
    if (n<0.0) {n=-n; str[f]='-'; f++;};
    n=n+0.005;
    scale=1.0;
    while (n>=scale) {scale=scale*10.0; ++i;};
    if (i==0) {str[f]='0'; f++;}
    else
    while (i--)
          {
          scale=floor(0.5+scale/10.0);
          d=(unsigned char) (n/scale);
          str[f]=d+'0';
          n=n-scale*d;
          f++;
          };

    str[f]='.';
    f++;
    for (j=0;j<=1;j++) //2 decimal points
          {
          n=n*10.0;
          d=(unsigned char) n;
          str[f]=d+'0';
          n=n-d;
          f++;
          };
    str[f]='\0';
    }
    ///////////////////END CONVERT FLOAT TO STRING///////////////////

    /////////////////////////////DELAY///////////////////////////////
    void DelayMs(unsigned char cnt)
    {
    #if XTAL_FREQ <= 2MHZ
        do {
            DelayUs(996);
        } while(--cnt);
    #endif

    #if    XTAL_FREQ > 2MHZ
        unsigned char   p;
        do {
            p = 4;
            do {
                DelayUs(250);
            } while(--p);
        } while(--cnt);
    #endif
    }

    void DelayS(unsigned char cnt)
    {
        for (j=0; j<(cnt*10); j++)
            DelayMs(100);
    }
    ///////////////////////////DELAY END/////////////////////////////

    //////////////////////////////LCD SETUP//////////////////////////
    /* send a command to the LCD */
    void lcd_cmd(unsigned char c)
    {
        DelayMs(20); //wait for LCD to be ready
        LCD_RS = 0;  //write instruction
        PORTB = (c & 0xF0); //load upper nibble on LCD data lines
        LCD_STROBE(); //send instruction to LCD
        PORTB = ((c << 4) & 0xF0); //load upper nibble on LCD data lines
        LCD_STROBE(); //send instruction to LCD    
    }

    /* send data to the LCD */
    void lcd_data(unsigned char c)
    {
        DelayMs(20); //wait for LCD to be ready
        PORTB = 0x00;
        LCD_RS = 1; //write data
        PORTB |= (c & 0xF0); //load upper nibble on LCD data lines    
        LCD_STROBE(); //send instruction to LCD
        PORTB &= 0x00; //load upper nibble on LCD data lines
        PORTB |= ( (c << 4) & 0xF0);
        LCD_STROBE(); //send instruction to LCD
    }

    /*Clear the LCD*/
    void lcd_clear(void)
    {
        lcd_cmd(0x01); //command to clear LCD
    }

    /*write a string of chars to the LCD*/
    void lcd_puts(const char s[])
    {
        j = -1;
        while(s[++j]!=('\0')) // send characters until null character reached
            lcd_data(s[j]);
    }

    /*go to beginning of line 1*/
    void lcd_goto_L1(void)
    {
        lcd_cmd(0b10000000); // command to go to line 1
    }

    /*go to beginning of line 2*/
    void lcd_goto_L2(void)
    {
        lcd_cmd(0b11000000); // command to go to line 2
    }

    /*move cursor "x" positions to the right*/
    void lcd_cursor(unsigned char x)
    {
        lcd_cmd(((x)&0x7F)|0x80);
    }

    /*initialise the LCD - put into 4 bit mode*/
    void lcd_init(void)
    {
        LCD_RS = 0;
        LCD_EN = 0;
        DelayMs(20); //wait for LCD startup
        lcd_cmd(0x28);  // 4-bit mode
        lcd_cmd(0x08);  // display off
        lcd_cmd(0x01);  // clear display
        lcd_cmd(0x0C);  // disp. on, cursor off, cursor blink off
        lcd_cmd(0x06);  // entry mode
        lcd_cmd(0x80);  // initialise DDRAM address to zero
    }
    [COLOR="Purple"]//////////////////////////LCD SETUP END//////////////////////////[/COLOR]


     
     

    void init(void)
    {  

        OSCCON|=0x60; //set fosc to 4Mhz
        TRISB=0x00;
        TRISC=0xFC;
        TRISA = 0b10000010;     // RA7 high imp, RA3 is serial out,
        ANSEL=0x02;            //set RA1 as analog input for GP2 sensor
        ANSELH=0x00;
        lcd_init(); //call LCD initialisation
    }

    char WaitForInput(void){
    char done;
    char temp;
    done = 0;

    while(!done){
        if(!ENTERSETTINGS_SW){
            temp = 1;
            done = 0xff;
        }

        if(!HOME_SW){
            temp = 2;
            done = 0xff;
        }

        if(!INCREASE_SW){
            temp = 3;
            done = 0xff;
        }

        if(!DECREASE_SW){
            temp = 4;
            done = 0xff;
        }
    }//end of while
        DelayMs(20);    //debounce
        return temp;
    }

    void home_screen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts("INFRARED LIQUID"); //home screen message (line 1)
        lcd_goto_L2();
        lcd_puts("LEVEL DETECTOR"); //home screen message (line 2)
    }

    void EnterScreen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" ENTER/SETTINGS ");
        DelayS(1);
        lcd_clear();
    }

    void ShowDigits(unsigned char val){

        MyValLCD[0] = val /10;    //returns the quotient (if temp = 35 the result is 3)
        MyValLCD[1] = val % 10;     //Returns remainder   (if temp = 35 the result is 5)

        MyValLCD[0] += 0x30;    //to ASCII
        MyValLCD[1] += 0x30;    //to ASCII

        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" ENTER/SETTINGS ");
        lcd_goto_L2();
        lcd_data(MyValLCD[0]);  //to LCD
        lcd_data(MyValLCD[1]);  //to LCD
    }

     
    void calc_distance(void)
    {
        // from the transeiver datasheet the analog voltage is
        // the inverse of distance, so distance can be calculated
        // d = (1 / volts) then just scaled to suit the transeiver

        // load ADC value in 16bit math var
        math = ADRESH;
        math = (math * 256);
        math += ADRESL;

        // now invert it; (1 / volts) use (6050 / volts) for scaling
        math = (6050 / math);
        if(math >= 2) math -=2;     // fix linear error (-2)
        if(math > 99) math = 99;    // max limit at 99cm

        // convert from 0-99 to 2 decimal digits, 0-99cm
        cm10=0;
        while(math >= 10)
        {
            cm10++;
            math -= 10;
        }
        cm = math;
    }
     
    void main(void)
    {
        init(); // initialise I/O ports, LCD
      [COLOR="Red"]  //home_screen();[/COLOR]

        MyVal = 0;
        MyMinVal = 0;
        MyMaxVal = 99;

    while(1){
        input_sw = WaitForInput();

        switch(input_sw){
          case 1:
            EnterScreen();
            mnuPOS = 1;
            break;
          case 2:
            home_screen();
            mnuPOS = 2;
            break;
        }
       
        while(mnuPOS == 1){
            input_sw = WaitForInput();
           
          switch(input_sw){
            case 1:
                mnuPOS = 2;
                home_screen();
                break;
            case 3:
                if(MyVal < MyMaxVal)
                    MyVal++;
                ShowDigits(MyVal);
                break;
            case 4:
                if(MyVal > MyMinVal)
                    MyVal--;
                ShowDigits(MyVal);
                break;
          }
        }
       
        //Do something here with the new Value which is a decimal in MyVal.
    }
     
         
    }
     
     
  17. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    try this and tell me what happens:
    Code (text):

    #include <pic.h>
    #include "pic.h"
    #include "delay.h"
    #include "math.h"
    #include <stdio.h>
    #include <stdlib.h>
     
    void FloatToStr(float , char[]);
    void DelayMs(unsigned char);
    void lcd_cmd(unsigned char);
    void lcd_data(unsigned char);
    void lcd_clear(void);
    void lcd_puts(const char[]);
    void lcd_goto_L1(void);
    void lcd_goto_L2(void);
    void lcd_cursor(unsigned char);
    void lcd_init(void);

    void init(void);
    char WaitForInput(void);
    void home_screen(void);
    void EnterScreen(void);
    void ShowDigits(unsigned char val);
    void main(void);



    void calc_distance(void);

         

    #define LCD_RS RC0      //LCD RS pin
    #define LCD_EN RC1      //LCD EN pin
    #define LCD_STROBE()    LCD_EN = 1; asm("nop"); asm("nop"); LCD_EN = 0

    unsigned char cm10;     //
    unsigned char cm;       //
    unsigned int math;      // used for voltage calculations
    unsigned char NumDec;
    unsigned char NumSep[2];
       
    unsigned char i,j,k;
    char temp[8];
    int height=50, SensorPos=10;
    char input_sw;

     
    char mnuPOS;

    unsigned char MyVal;
    unsigned char MyValLCD[2];
    unsigned char MyMaxVal;
    unsigned char MyMinVal;



    #define HOME_SW RC2             //HOME switch  
    #define INCREASE_SW RC3         //INCREASE switch
    #define DECREASE_SW RC4         //DECREASE switch
    #define ENTERSETTINGS_SW RA4    //ENTERSETTINGS switch



    ///////////////////////CONVERT FLOAT TO STRING///////////////////
    // This function was taken from the CAVR library. It was modified slightly
    // to suit our design.
    void FloatToStr(float n, char str[])
    {
    float scale;
    unsigned char d,f;
    f=0;i=0;
    if (n<0.0) {n=-n; str[f]='-'; f++;};
    n=n+0.005;
    scale=1.0;
    while (n>=scale) {scale=scale*10.0; ++i;};
    if (i==0) {str[f]='0'; f++;}
    else
    while (i--)
          {
          scale=floor(0.5+scale/10.0);
          d=(unsigned char) (n/scale);
          str[f]=d+'0';
          n=n-scale*d;
          f++;
          };

    str[f]='.';
    f++;
    for (j=0;j<=1;j++) //2 decimal points
          {
          n=n*10.0;
          d=(unsigned char) n;
          str[f]=d+'0';
          n=n-d;
          f++;
          };
    str[f]='\0';
    }
    ///////////////////END CONVERT FLOAT TO STRING///////////////////

    /////////////////////////////DELAY///////////////////////////////
    void DelayMs(unsigned char cnt)
    {
    #if XTAL_FREQ <= 2MHZ
        do {
            DelayUs(996);
        } while(--cnt);
    #endif

    #if    XTAL_FREQ > 2MHZ
        unsigned char   p;
        do {
            p = 4;
            do {
                DelayUs(250);
            } while(--p);
        } while(--cnt);
    #endif
    }

    void DelayS(unsigned char cnt)
    {
        for (j=0; j<(cnt*10); j++)
            DelayMs(100);
    }
    ///////////////////////////DELAY END/////////////////////////////

    //////////////////////////////LCD SETUP//////////////////////////
    /* send a command to the LCD */
    void lcd_cmd(unsigned char c)
    {
        DelayMs(20); //wait for LCD to be ready
        LCD_RS = 0;  //write instruction
        PORTB = (c & 0xF0); //load upper nibble on LCD data lines
        LCD_STROBE(); //send instruction to LCD
        PORTB = ((c << 4) & 0xF0); //load upper nibble on LCD data lines
        LCD_STROBE(); //send instruction to LCD    
    }

    /* send data to the LCD */
    void lcd_data(unsigned char c)
    {
        DelayMs(20); //wait for LCD to be ready
        PORTB = 0x00;
        LCD_RS = 1; //write data
        PORTB |= (c & 0xF0); //load upper nibble on LCD data lines    
        LCD_STROBE(); //send instruction to LCD
        PORTB &= 0x00; //load upper nibble on LCD data lines
        PORTB |= ( (c << 4) & 0xF0);
        LCD_STROBE(); //send instruction to LCD
    }

    /*Clear the LCD*/
    void lcd_clear(void)
    {
        lcd_cmd(0x01); //command to clear LCD
    }

    /*write a string of chars to the LCD*/
    void lcd_puts(const char s[])
    {
        j = -1;
        while(s[++j]!=('\0')) // send characters until null character reached
            lcd_data(s[j]);
    }

    /*go to beginning of line 1*/
    void lcd_goto_L1(void)
    {
        lcd_cmd(0b10000000); // command to go to line 1
    }

    /*go to beginning of line 2*/
    void lcd_goto_L2(void)
    {
        lcd_cmd(0b11000000); // command to go to line 2
    }

    /*move cursor "x" positions to the right*/
    void lcd_cursor(unsigned char x)
    {
        lcd_cmd(((x)&0x7F)|0x80);
    }

    /*initialise the LCD - put into 4 bit mode*/
    void lcd_init(void)
    {
        LCD_RS = 0;
        LCD_EN = 0;
        DelayMs(20); //wait for LCD startup
        lcd_cmd(0x28);  // 4-bit mode
        lcd_cmd(0x08);  // display off
        lcd_cmd(0x01);  // clear display
        lcd_cmd(0x0C);  // disp. on, cursor off, cursor blink off
        lcd_cmd(0x06);  // entry mode
        lcd_cmd(0x80);  // initialise DDRAM address to zero
    }
    //////////////////////////LCD SETUP END//////////////////////////


     
     

    void init(void)
    {  

        OSCCON|=0x60; //set fosc to 4Mhz
        TRISB=0x00;
        TRISC=0xFC;
        TRISA = 0b10000010;     // RA7 high imp, RA3 is serial out,
        ANSEL=0x02;            //set RA1 as analog input for GP2 sensor
        ANSELH=0x00;
        lcd_init(); //call LCD initialisation
    }

    char WaitForInput(void){
    char done;
    char temp;
    done = 0;

    while(!done){
        if(!ENTERSETTINGS_SW){
            temp = 1;
            done = 0xff;
        }

        if(!HOME_SW){
            temp = 2;
            done = 0xff;
        }

        if(!INCREASE_SW){
            temp = 3;
            done = 0xff;
        }

        if(!DECREASE_SW){
            temp = 4;
            done = 0xff;
        }
    }//end of while
        DelayMs(150);    //debounce
        return temp;
    }

    void home_screen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts("INFRARED LIQUID"); //home screen message (line 1)
        lcd_goto_L2();
        lcd_puts("LEVEL DETECTOR"); //home screen message (line 2)
    }

    void EnterScreen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" ENTER/SETTINGS ");
    }

    void ShowDigits(unsigned char val){

        MyValLCD[0] = val /10;    //returns the quotient (if temp = 35 the result is 3)
        MyValLCD[1] = val % 10;     //Returns remainder   (if temp = 35 the result is 5)

        MyValLCD[0] += 0x30;    //to ASCII
        MyValLCD[1] += 0x30;    //to ASCII

        EnterScreen();
        lcd_goto_L2();
        lcd_data(MyValLCD[0]);  //to LCD
        lcd_data(MyValLCD[1]);  //to LCD
    }

     
    void calc_distance(void)
    {
        // from the transeiver datasheet the analog voltage is
        // the inverse of distance, so distance can be calculated
        // d = (1 / volts) then just scaled to suit the transeiver

        // load ADC value in 16bit math var
        math = ADRESH;
        math = (math * 256);
        math += ADRESL;

        // now invert it; (1 / volts) use (6050 / volts) for scaling
        math = (6050 / math);
        if(math >= 2) math -=2;     // fix linear error (-2)
        if(math > 99) math = 99;    // max limit at 99cm

        // convert from 0-99 to 2 decimal digits, 0-99cm
        cm10=0;
        while(math >= 10)
        {
            cm10++;
            math -= 10;
        }
        cm = math;
    }
     
    void main(void)
    {
        init(); // initialise I/O ports, LCD
        //home_screen();

        MyVal = 0;
        MyMinVal = 0;
        MyMaxVal = 99;

    while(1){
        input_sw = WaitForInput();

        switch(input_sw){
          case 1:
            EnterScreen();
            mnuPOS = 1;
            DelayMS(50);
            break;
          case 2:
            home_screen();
            mnuPOS = 2;
            break;
        }
       
        while(mnuPOS == 1){
            input_sw = WaitForInput();
           
          switch(input_sw){
            case 1:
                mnuPOS = 2;
                home_screen();
                break;
            case 3:
                if(MyVal < MyMaxVal)
                    MyVal++;
                ShowDigits(MyVal);
                break;
            case 4:
                if(MyVal > MyMinVal)
                    MyVal--;
                ShowDigits(MyVal);
                break;
          }
        }
       
        //Do something here with the new Value which is a decimal in MyVal.
    }
     
         
    }

     
     
  18. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    Im using the new code you suggested and now

    when i power on:


    "infrared liquid level detector is displayed" then it clears and
    "enter/settings" is displayed continuously then it clears and
    "infrared liquid level detector is displayed" then it clears and
    "enter/settings" is displayed continuously then it clears and so forth.


    when i press home button: infra red liquid level detector is displayed continuously

    when i release home button:

    "infrared liquid level detector is displayed" then it clears and
    "enter/settings" is displayed continuously then it clears and
    "infrared liquid level detector is displayed" then it clears and
    "enter/settings" is displayed continuously then it clears and so forth.
    Code (text):

    when i [B]press increase button[/B]: it displays enter/settings on 1st line
                                             then 01                        on 2nd line

                                             it displays enter/settings on 1st line
                                             then 02                        on 2nd line
    and continues increasing...
    but i need the 1st digit to increase fro 0 to 9 and rollover to 0.

    when i release increase button:"enter/settings" is displayed continuously

    Code (text):

    when i [B]press decrease button[/B]: it displays enter/settings on 1st line
                                             then 02                        on 2nd line

                                             it displays enter/settings on 1st line
                                             then 01                        on 2nd line

                                             it displays enter/settings on 1st line
                                             then 00                       on 2nd line

                                             it displays enter/settings on 1st line
                                             then 00                        on 2nd line
    and 00 is the lowest it decreases to
    But i need the 2nd digit to decrease from 9 to 0 and rollover to 9.

    when i release decrease button:"enter/settings" is displayed continuously


    when i press home/settings button:
    "infrared liquid level detector is displayed" then it clears and
    "enter/settings" is displayed continuously then it clears and
    "infrared liquid level detector is displayed" then it clears and
    "enter/settings" is displayed continuously then it clears and so forth.

    when i release home/settings button:
    "infrared liquid level detector is displayed" then it clears and
    "enter/settings" is displayed continuously then it clears and
    "infrared liquid level detector is displayed" then it clears and
    "enter/settings" is displayed continuously then it clears and so forth.
     
    Last edited: Sep 9, 2009
  19. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    i think you might have a hardware issue. Are all the buttons pulled high?

    As soon as it goes on it should not say anything. It should be blank and you have to press the home button for it to show that "infrared liquid level detector"

    Hence why i suggest you uncomment the :

    Code (text):

    void main(void)
    {
        init(); // initialise I/O ports, LCD
            [b]home_screen();[/b]

     
     
    Last edited: Sep 9, 2009
  20. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    Maybe the configuration bits in MPLAB are not set corrrectly???that would affect the micro right. im using momentary push button switches....
     
  21. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    im going to uncomment home and c what happens. When i tried your new code....home is uncommented and the same remarks apply.
     
    Last edited: Sep 9, 2009

Share This Page