Continue to Site

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.

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

READING A PUSHBUTTON & display on LCD

Status
Not open for further replies.
heh replacing time:
Code:
    TRISA = 0b10000010; 	// RA7 high imp, RA3 is serial out,
heh in your init: you should put this
Code:
    TRISA = 0b10010010; 	// RA7 high imp, RA3 is serial out,[b] RA4 button input[/b]
 
Last edited:
oscillator external RC clockout
watchdog timer off
power up timer off
master clear enable external
code protect off
data ee ee protect off
brown out detect BOD enabled, sboren disabled
internal external switchover mode enabled
monitor clock fail-safe enabled
 
i replaced the TRISA line but:


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.

BUT now also sumtimes when i hold down the home button for long:

the screen remains blank until i release it again
 
ok. What are you using to program it? CCS or something?

try this:
Code:
#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 = 0b10010010; 	// 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;
temp = 0;
while(!done){
    if(!ENTERSETTINGS_SW){
		while(!ENTERSETTINGS_SW);
        temp = 1;
        done = 0xff;
    }

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

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

    if(!DECREASE_SW){
		while(!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){
	mnuPOS = 0;
	input_sw = 0;
	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 = 0;
   	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 = 0;
   		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.
}
 
	 
}
 
im using the pic kit 2 demo board with mplab ide v8.01-hi-tech universal toolsuite:hi tech ansi c compiler pic lite....whats ccs???hehe
 
Last edited:
the new code it gives an error:

Error [499] ; 0. undefined symbol:
_DelayMS(ctest.obj)

ok i corrected it....MS to Ms
 
Last edited:
ok i ran the new code and:

when i power up:

infrared liquid level detector is displayed and its stable....not being repeated.


however pressing the buttons has no effect
 
Ok the way this works is to enter settings you need to press enter then use increase and decrease.

What happens when you press enter? nothing?
 
when i power on:
infrared liquid level detector is displayed and its stable....not being repeated.

and when i press enter/settings:
nothing happens....
infrared liquid level detector is still displayed and stable...
 
heh i never used HI-TECH before. Seems cool. And they do have a free lite version which would be great for 10F/12F/16F PICs...

Can you attach the other files like delay.h and such so i can do a decent compile and test this out with MPLAB SIM
 
Yeah sure....sorry for hehe troubling you so late...ill b off to bed soon
 

Attachments

  • pic.h
    12.9 KB · Views: 1,050
  • delay.h
    1.3 KB · Views: 359
  • lcd.h
    595 bytes · Views: 290
hehe lucky me:rolleyes:. The power supply is working:)
 
Last edited:
Ok this code seems ok but for some reason im not sure if its just MPLAB but i cant change PORTC register. So i cant trigger a button press on PORTC but i can to PORTA and it jumps to the enter screen ok but i cant simulate a button press for INCREASE and DECREASE...

Do you think its possible to use Proteus to simulate? Ill have to make a schematic tho :(

Code:
#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 = 0b10010010; 	// RA7 high imp, RA3 is serial out,

	ANSEL=0x02;            //set RA1 as analog input for GP2 sensor
	ANSELH=0x00;

	CM1CON0 = 0;
	CM2CON0 = 0;
	lcd_init(); //call LCD initialisation
}

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

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

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

    if(!DECREASE_SW){
		while(!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){
	mnuPOS = 0;
	input_sw = 0;
	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 = 0;
   	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 = 0;
   		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.
}
 
	 
}
 
Goodmorning Atomsoft...Thanks for trying:). Hehe had to go to bed last night...stayed up till 2am-i ran the above code and same thing happens:


when i power on:
infrared liquid level detector is displayed and its stable....not being repeated.

and when i press enter/settings:
nothing happens....
infrared liquid level detector is still displayed and stable...

Im going to play around with the code that had the number of presses increasing and decreasing....

Do you think its possible to use Proteus to simulate?

Proteus VSM for PIC16 contains everything you need to develop, test and virtually prototype your embedded system designs based around the Microchip Technologies™ PIC16 series of microcontrollers. The unique nature of schematic based microcontroller simulation with Proteus facilitates rapid, flexible and parallel development of both the system hardware and the system firmware. This design synergy allows engineers to evolve their projects more quickly, empowering them with the flexibility to make hardware or firmware changes at will and reducing the time to market. Proteus VSM is discussed in more detail here.


Wow thats pretty neat stuff that can be done with proteus from the picture but it looks complicated to hehe:eek:
 

Attachments

  • picdem2.gif
    picdem2.gif
    66.9 KB · Views: 380
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top