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. bryan

    bryan Member

    Joined:
    Jun 21, 2003
    Messages:
    416
    Likes:
    3
    Location:
    Vancouver, Canada
    Thanks, appreciate it...

     
  2. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    Well i tested the sensor on some liquids(water, milk, oil and coke):) last night and its analog output voltage is similar to that of the datasheet...so it does work on liquids...il post the graphs when i get home...its on my desk top and im in uni at the moment....
     
  3. jpanhalt

    jpanhalt Well-Known Member Most Helpful Member

    Joined:
    Jun 21, 2006
    Messages:
    5,897
    Likes:
    502
    Location:
    Cleveland, OH, USA
    Very nice. I love experimentation. Did you vary the depth of the liquid or just the distance from the liquid's surface? The experiment I would sugest is water in a deep bowl. Add about 3 to 4 cm of water and measure at 10 and 20 cm from the surface. Then increase depth of water 10 cm and repeat.

    John

    Edit: On reconsideration, make the initial water depth only 2 to 3 cm. Keep the rest the same.
     
    Last edited: Sep 11, 2009
  4. dave

    Dave New Member

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


     
  5. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0

    I varied the distance, i will be back later-i will try out what you said when i get home jpanhalt, my lift club is leaving soon....got to go now
     
  6. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    heh just dont forget in that junebug page read the comments well...

    // load ADC value in 16bit math var

    so..
    int math
     
  7. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    This was just a rough test i did with the GP2 and various liquids....
    tomorrow i plan to do a more accurate test so each liquid will have the same type of container
     

    Attached Files:

  8. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    Yeah Atomsoft hehe im gonna try to:). Nyty nyt, its 23:04 here......take care
     
    Last edited: Sep 11, 2009
  9. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    jpanhalt...i posted the new measurements on my GP2 sensor thread...if you want to take a look.......
     
  10. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    Hello AtomSoft....this is the original code...i want to modify it slightly so that i can allow the user to ENTER 3 values(which i can use)....so my plan is to make a function out of the code i highlighted in red below....(that is the the part when the user presses enter)

    i want to call that 3 different times so it does something like:

    "enter height"
    call enter/settings (which is now user input function in new code)
    height=MyVal

    "enter range"
    call user_input
    range=MyVal

    "enter surface area"
    call user_input
    area=MyVal

    well i just want to know if the way im assigning height=MyVal is correct in the new code below..............My val is determined in the user input stage...My Val is the number i need to manipulate...so am i assigning it correctly? or do i need to use a return MyVal then height=user_input() ???


    old code:

    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(2); //wait for LCD to be ready shorter delay
        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(2); //wait for LCD to be ready shorter delay
        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
    */

    // These are my inits. Comment them out and use the above for you
        lcd_cmd(0x02);
        lcd_cmd(0x08);
        lcd_cmd(0x02);
        lcd_cmd(0x08);
        lcd_cmd(0x00);
        lcd_cmd(0x06);
        lcd_cmd(0x00);
        lcd_cmd(0x0E);
        lcd_cmd(0x00);
        lcd_cmd(0x01);

    }
    //////////////////////////LCD SETUP END//////////////////////////
       

    void init(void)
    {  
       
        MyVal = 0; //initializn these variables here
        MyMinVal = 0;
        MyMaxVal = 99;
        OSCCON|=0x60; //set fosc to 4Mhz
        TRISB=0x00;
        TRISC=0xFC;
        TRISA = 0b10010010;     // RA7 high imp, RA3 is serial out, RA4 button input
        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 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 home_screen(void){
        mnuPOS = 0;
        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)
      // i dont have a while(1) here any more
    //Im calling the wait for input function here
    input_sw = WaitForInput();

        while(input_sw != 1);  // wait until enter is pressed
       
        EnterScreen();
        mnuPOS = 1;
        DelayMs(2);             //shorter delay
       

        [COLOR="Red"]while(mnuPOS == 1){
            input_sw = WaitForInput();
           
          switch(input_sw){
            case 1:
                mnuPOS = 2; //This tells us the user finished entering
                lcd_goto_L1();
                lcd_puts("     Done!      "); //home screen message (line 1)
                break;
            case 3:
                if(MyVal < MyMaxVal)
                    MyVal++;
                ShowDigits(MyVal);
                break;
            case 4:
                if(MyVal > MyMinVal)
                    MyVal--;
                ShowDigits(MyVal);
                break;

            default:
                break;
          }
         
        }
        DelayS(1);
        //Do something here with the new Value which is a decimal in
        //MyVal. The user is here because all data is entered
        //i added a return here
        //return;
        //im not 100% sure but since its a void i think a return isnt needed[/COLOR]
    }
     

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

    here is the new code.....................


    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 user_input(void);
    void home_screen(void);
    void EnterHeight(void);
    void EnterScreen(void);
    void ShowDigits(unsigned char val);
    void main(void);



    void calc_distance(void);

         

    void init(void)
    {  
       
        MyVal = 0; //initializn these variables here
        MyMinVal = 0;
        MyMaxVal = 99;
        OSCCON|=0x60; //set fosc to 4Mhz
        TRISB=0x00;
        TRISC=0xFC;
        TRISA = 0b10010010;     // RA7 high imp, RA3 is serial out, RA4 button input
        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 EnterHeight(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" ENTER HEIGHT ");
        lcd_goto_L2();
        lcd_puts("Press UP/Down"); //home screen message (line 2)
    }

    void EnterScreen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" [cm] ");
    }

    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 user_input(void)
    {
        while(mnuPOS == 1){
            input_sw = WaitForInput();
           
          switch(input_sw){
            case 1:
                mnuPOS = 2; //This tells us the user finished entering
                lcd_goto_L1();
                lcd_puts("     Done!      "); //home screen message (line 1)
                break;
            case 3:
                if(MyVal < MyMaxVal)
                    MyVal++;
                ShowDigits(MyVal);
                break;
            case 4:
                if(MyVal > MyMinVal)
                    MyVal--;
                ShowDigits(MyVal);
                break;

            default:
                break;
          }
         
        }
        DelayS(1);
        //Do something here with the new Value which is a decimal in
        //MyVal. The user is here because all data is entered
    }

    void home_screen(void){
        mnuPOS = 0;
        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)
     
    input_sw = WaitForInput();

        while(input_sw != 1);  // wait until enter is pressed
       
        EnterScreen();
        EnterHeight();
        mnuPOS = 1;
        DelayMs(2);             //shorter delay
        user_input();
        [B][COLOR="Blue"]height=MyVal;[/COLOR][/B]
    }
     









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

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    from what i see it would be ok if you declare the MyVal as a global.
     
  12. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    wait no. It will get stuck in while() loop brb gonna edit quick
     
  13. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Try this :
    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);
    unsigned char user_input(void);
    void home_screen(void);
    void EnterHeight(void);
    void EnterScreen(void);
    void ShowDigits(unsigned char val);
    void main(void);



    void calc_distance(void);

         

    void init(void)
    {  
       
        MyVal = 0; //initializn these variables here
        MyMinVal = 0;
        MyMaxVal = 99;
        OSCCON|=0x60; //set fosc to 4Mhz
        TRISB=0x00;
        TRISC=0xFC;
        TRISA = 0b10010010;     // RA7 high imp, RA3 is serial out, RA4 button input
        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 EnterHeight(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" ENTER HEIGHT ");
        lcd_goto_L2();
        lcd_puts("Press Up/Down"); //home screen message (line 2)
    }

    void EnterScreen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" [cm] ");
    }

    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;
    }
     //[b]
    unsigned char user_input(void)      //This will return what we want[/b]
    {
        char done = 0;

        MyVal = 0;          //[b]Start on 0[/b]
        while(done == 0){
          input_sw = WaitForInput();
           
          switch(input_sw){
            case 1:
                done = 0xff;            //This tells us the user finished entering
                lcd_goto_L1();
                lcd_puts("     Done!      "); //home screen message (line 1)
                break;
            case 3:
                if(MyVal < MyMaxVal)
                    MyVal++;
                ShowDigits(MyVal);
                break;
            case 4:
                if(MyVal > MyMinVal)
                    MyVal--;
                ShowDigits(MyVal);
                break;

            default:
                break;
          }
         
        }
        DelayS(1);
        return MyVal;
    }

    void home_screen(void){
        mnuPOS = 0;
        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)
     
        input_sw = 0;           //Reset the value

        while(input_sw != 1)    //Wait until enter is pressed
            input_sw = WaitForInput();

        EnterScreen();
        EnterHeight();
        DelayMs(2);             //shorter delay [b]
        height = user_input();  //The HEIGHT var will have the myVal[/b]

    }
     


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

     

    EDIT: What happened to all the variable declarations?
     
    Last edited: Sep 13, 2009
  14. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    b4 when i was playing around & trying my own tricks...it did get stuck in the while loop

    Hey...i am at uni.....when i get home...i will test it out n let you know what happens.........................

    OOOpZ......Cut n paste
     
    Last edited: Sep 14, 2009
  15. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    Hello AtomSoft.....i tried the code and.....as soon as i power up it displays....

    "IR LLD:)"

    enter height
    press up/down

    done!
    press up/down

    " IR LLD"............and it loops the same sequence above....


    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);
    unsigned char user_input(void);
    void home_screen(void);
    void EnterHeight(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];
    unsigned char 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(2); //wait for LCD to be ready shorter delay
        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(2); //wait for LCD to be ready shorter delay
        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(0x02);
     
        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)
    {  
       
        MyVal = 0; //initializn these variables here
        MyMinVal = 0;
        MyMaxVal = 99;
        OSCCON|=0x60; //set fosc to 4Mhz
        TRISB=0x00;
        TRISC=0xFC;
        TRISA = 0b10010010;     // RA7 high imp, RA3 is serial out, RA4 button input
        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 EnterHeight(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" ENTER HEIGHT ");
        lcd_goto_L2();
        lcd_puts("Press Up/Down"); //home screen message (line 2)
    }

    void EnterScreen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" [cm] ");
    }

    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;
    }
     //
    unsigned char user_input(void)      //This will return what we want
    {
        char done = 0;

        MyVal = 0;          //Start on 0
        while(done == 0){
          input_sw = WaitForInput();
           
          switch(input_sw){
            case 1:
                done = 0xff;            //This tells us the user finished entering
                lcd_goto_L1();
                lcd_puts("     Done!      "); //home screen message (line 1)
                break;
            case 3:
                if(MyVal < MyMaxVal)
                    MyVal++;
                ShowDigits(MyVal);
                break;
            case 4:
                if(MyVal > MyMinVal)
                    MyVal--;
                ShowDigits(MyVal);
                break;

            default:
                break;
          }
         
        }
        DelayS(1);
        return MyVal;
    }

    void home_screen(void){
        mnuPOS = 0;
        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)
     
        input_sw = 0;           //Reset the value

        while(input_sw != 1)    //Wait until enter is pressed
            input_sw = WaitForInput();

        EnterScreen();
        EnterHeight();
        DelayMs(2);             //shorter delay
        height = user_input();  //The HEIGHT var will have the myVal

    }
     


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

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    ZzzzzzzzZZZZZzzzzzzzzzzzzzzzzzzzzz...im so tired, was doing my pre-prac for tomorrow...sorry for the late response...
     
  17. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    what do you want it to do? It works fine for me. when i press up or down it says

    [cm]
    01
     
  18. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Here you go complete:

    Code (text):

    #include <pic.h>
    #include "pic.h"
    #include "delay.h"
    #include "math.h"
    #include <stdio.h>
    #include <stdlib.h> //[b]

    void userMenu(char pos); //[/b]  
    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);
    unsigned char user_input(void);
    void home_screen(void);
    void EnterHeight(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];
    //[/b]
    unsigned char height=50;
    unsigned char range;
    unsigned char area;
    unsigned char SensorPos=10;
    //[/b] New Vars
    char input_sw;

     
    char mnuPOS;

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


    unsigned char ;

    #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(2); //wait for LCD to be ready shorter delay
        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(2); //wait for LCD to be ready shorter delay
        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(0x02);
     
        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)
    {  
       
        MyVal = 0; //initializn these variables here
        MyMinVal = 0;
        MyMaxVal = 99;
        OSCCON|=0x60; //set fosc to 4Mhz
        TRISB=0x00;
        TRISC=0xFC;
        TRISA = 0b10010010;     // RA7 high imp, RA3 is serial out, RA4 button input
        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;
    }//[b]
    void userMenu(char pos){
        lcd_clear();
        lcd_goto_L1();

        switch(pos){
            case 0:
                lcd_puts("    HEIGHT    ");
                break;     
            case 1:
                lcd_puts("    RANGE     ");
                break;     
            case 2:
                lcd_puts(" SURFACE AREA ");
                break;     
        }

        lcd_goto_L2();
        lcd_puts("Press Up/Down"); //home screen message (line 2)
    }
    //[/b] New Menu System
    void EnterHeight(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" ENTER HEIGHT ");
        lcd_goto_L2();
        lcd_puts("Press Up/Down"); //home screen message (line 2)
    }

    void EnterScreen(void){
        lcd_clear();
        lcd_goto_L1();
        lcd_puts(" [cm] ");
    }

    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;
    }
     //
    unsigned char user_input(void)      //This will return what we want
    {
        char done = 0;

        MyVal = 0;          //Start on 0
        while(done == 0){
          input_sw = WaitForInput();
           
          switch(input_sw){
            case 1:
                done = 0xff;            //This tells us the user finished entering
                lcd_goto_L1();
                lcd_puts("     Done!      "); //home screen message (line 1)
                break;
            case 3:
                if(MyVal < MyMaxVal)
                    MyVal++;
                EnterScreen();
                ShowDigits(MyVal);
                break;
            case 4:
                if(MyVal > MyMinVal)
                    MyVal--;
                EnterScreen();
                ShowDigits(MyVal);
                break;
            default:
                break;
          }
         
        }
        DelayS(1);
        return MyVal;
    }

    void home_screen(void){
        mnuPOS = 0;
        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)
     
        input_sw = 0;           //Reset the value

        while(input_sw != 1)    //Wait until enter is pressed
            input_sw = WaitForInput();

        //EnterScreen();
        //EnterHeight();
        userMenu(0);
        DelayMs(2);             //shorter delay
        height = user_input();  //The HEIGHT var will have the myVal

        userMenu(1);
        DelayMs(2);             //shorter delay
        range = user_input();   //The HEIGHT var will have the myVal

        userMenu(2);
        DelayMs(2);             //shorter delay
        area = user_input();    //The HEIGHT var will have the myVal
    /*
    "enter height"
    call enter/settings (which is now user input function in new code)
    height=MyVal

    "enter range"
    call user_input
    range=MyVal

    "enter surface area"
    call user_input
    area=MyVal
    */
    }
     


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

     
     
  19. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    well its doing the above stuff without me pressing any buttons....

    o gosh i just looked at mplab config bits again.....i had saved this in a new file and it reset the config bits to default.....:rolleyes:

    im sure it will work after i set the bits correctly again.....thanx AtomSoft.....
     
  20. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    heh no problem. I made the whole menu in the new code posted. I add the range and area stuff
     
  21. fantabulous68

    fantabulous68 Member

    Joined:
    Feb 20, 2007
    Messages:
    323
    Likes:
    0
    lol:) complete :rolleyes: thanx ;):p:)....

    Yeah it sure is working smoothly...:)tried it out now....

    i have to start paying forward my bank balance (im not working yet lol)...if i dont start paying back in kind hehe....
     
    Last edited: Sep 14, 2009

Share This Page