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.

Counting with button and display on LCD

Status
Not open for further replies.

Kryten

New Member
So I got the LCD rutine up and working (Thanks 3v0)

I need som help with putting a "couter" or two buttons (one for increase and one for decrease)

Code:
void main (void)
{	
	int a;
	a = 1;
  // setup PORTA for all digital IO
  	CMCON0 = 0x07;  
	ANSEL = 0x00;  
 	TRISA = 0b000110000;

	lcd_init();
	lcd_goto(0x05);	// select first line
	lcd_puts("LCD ");
	lcd_goto(0x43);// Select second line
	lcd_puts("Test");
	vait_1_sec ();
	lcd_clear ();
	lcd_goto(0x02);
	lcd_puts ("Press button");
	lcd_goto(0x40);
	lcd_puts("Count:");

	while(1);
	{
	lcd_goto(0x48);
	if (1 == RA4)
		{
		a = (a + 1);
		lcd_puts(a);
		}
	else if ( 1 == RA5)
		{
		 a = (a - 1);
		lcd_puts(a);
		}
	}
}

I know something is wrong but not what..

And I Know that I might have declared "a" wrong
 
Last edited:
Update!

Heres the cod as is now
Code:
//////////////////////////////////////////////////////////////
//     Temp from DS18S20 to LCD                            //
//          PIC16F688                                              //
//////////////////////////////////////////////////////////////

#include	<pic.h>
//#include	"delay.h"
#include "include\lcd.h"

__CONFIG (UNPROTECT & MCLRDIS & PWRTDIS & WDTDIS & INTIO & BOREN);

/////////////////////////////////////////////////////////////
// Port setup                                              //
/////////////////////////////////////////////////////////////

#define _XTAL_FREQ 8000000
#define DELAY  (__delay_ms(125))

//#define DS1820_DATAPIN RA0


/////////////////////////////////////////////////////////////
// Div routines                                            //
/////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////
// Dealy setup                                           //
///////////////////////////////////////////////////////////

void vait_1_sec (void)
{
	DELAY;
	DELAY;
	DELAY;
	DELAY;
	DELAY;
	DELAY;
	DELAY;
	DELAY;
}


/////////////////////////////////////////////////////////////
// Main routine                                            //
/////////////////////////////////////////////////////////////


void main (void)
{	
	int a;
	a = 1;
// setup PORTA for all digital IO
  	CMCON0 = 0x07;  
	ANSEL = 0x00;  
 	TRISA = 0b000110000;
  
//	vait_1_sec ();
	lcd_init();
	lcd_goto(0x05);	// select first line
	lcd_puts("Markman");
	lcd_goto(0x43);	// Select second line
	lcd_puts("Electronics");
	__delay_ms(125);
	__delay_ms(125);
	lcd_clear();
	lcd_goto(0x02);
	lcd_puts ("Press button");
	lcd_goto(0x40);
	lcd_puts("Count:");
	lcd_goto(0x47);


	while(1);
	
	{
	if (1 == RA4)
		{
		a = (a + 1);
		lcd_puts(a+"0");
		}
	else if ( 1 == RA5)
		{
		 a = (a - 1);
		lcd_puts(a+"0");
		}
	else {
		a = a;
		lcd_puts(a+"0");
		}
	}
}

Also added the schematis.

The thing is that it wont display the count value. I really need the help I can get.
 

Attachments

  • Schematics.jpg
    Schematics.jpg
    308.7 KB · Views: 224
You need to make the distinction between characters and strings.

I see you are using '0'+a to convert a to ASCII which works fine for a ranging from 0 to 9. But '0'+a is a character and you are using lcd_puts which I expect means put string based on how you use it else where. Try lcd_putc('0'+a);

To handle numbers with more then one character you will need to convert the number to a string and use lcd_prints
 
Why not use a string function like
Code:
unsigned char MyBuff[16];
sprintf(MyBuff,"Count is %i\0",MyCountVariable);
//Then send MyBuff to LCD
lcd_puts(MyBuff);


Can you post current simulation model and code here?
 
Last edited:
AtomSoft. Do you mean the Proteus file and mplab files?
If so I will do later on (dont have access to it yet from work)

Should probably add that im using Hi-Tech compiler
 
Last edited:
Heres the files

AtomSoft..
Here all the files I have ;)
 

Attachments

  • LCD-SIM.zip
    94.6 KB · Views: 151
Done! Replace your

void main(void) code with this one.

Code:
void main (void)
{	
	unsigned char buff[16];
	int a;
	char isNew=1;
	a = 1;
// setup PORTA for all digital IO
  	CMCON0 = 0x07;  
	ANSEL = 0x00;  
 	TRISA = 0b000110000;
  
//	vait_1_sec ();
	lcd_init();
	lcd_goto(0x05);	// select first line
	lcd_puts("Markman");
	lcd_goto(0x43);	// Select second line
	lcd_puts("Electronics");
	__delay_ms(125);
	__delay_ms(125);
	lcd_clear();
	lcd_goto(0x02);
	lcd_puts ("Press button");
	lcd_goto(0x40);
	sprintf(buff,"Count: %i\0",a);
	lcd_puts(buff);


	while(1)
	{
		if(isNew)
		{
			lcd_goto(0x40);
			sprintf(buff,"Count: %i\0",a);
			lcd_puts(buff);
			isNew = 0;
		}
		if (1 == RA4)
		{
			while(RA4==1);	//Debounce 
			a = (a + 1);
			isNew = 1;
		}
		else if ( 1 == RA5)
		{
			while(RA5==1);	//Debounce 
			a = (a - 1);
			isNew = 1;
		}
  	}
}

Also include this file:
Code:
#include <stdio.h>
 
Last edited:
Thank you AtomSoft...

A little follow up question:


By using
Code:
unsinged char buff[16]
Or different name than buff. Will I be abel to display some static text and some dynamic?

I mean by using the
Code:
unsinged char myvariable[16]
Will i be abel to just change the myvariable part. Like if I want to display temp of a 1-wire, and have some text always displaying.
Hope I got it. I know I need to change the code inside the while loop.
 
I think i understand ...

So you can change the name but make sure you change it in the sprintf statement also and when you print it like

Code:
sprintf([COLOR="Red"]myvariable[/COLOR],"Count: %i\0",a);
lcd_puts([COLOR="Red"]myvariable[/COLOR]);

If you want static text you can also do this:
Code:
unsigned char CountTxt[8] = "Count:";
unsigned char myvariable[16];

sprintf(myvariable,"%s %i\0",CountTxt,a);
lcd_puts(myvariable);

Is that what you meant?
 
Last edited:
Yes Jason.

And I really like the way you explained the integer and sprintf befor editing ;)
 
Im still a noob when it comes to C coding. I have a BS in EE and work as a test engineer, but want to learn so I can apply for jobs that are a bit more in the dev area :D
 
Last edited:
Cool! Tech is always changing so noobs are created daily heh

I wish i has a BS in EE. I went to school for a bit then got real sick and had to drop out. (still paying for it heh)
 
@Atom can you help me get this .h (or.c) to return a value to put on my LCD (using the lcd code in this thread)?

Here is the ow_hitech (I have found)
Code:
#include	<htc.h>
#include <STDIO.h>
//#include "Serial.h"

// GLOBAL Defines
#define TRUE	0x01
#define FALSE	0x00
#define DQ RC5
#define _XTAL_FREQ 8000000 

/*==================================================================================
**
** RESET - this should ideally reset the DS18B20 and recieve a Presence Pulse
**
** =================================================================================
*/

unsigned char ow_reset (void)
{
	unsigned char present;
	TRISC &= ~0x01;	// Set port to output
	DQ = 0;				// Pull DQ line Low
	__delay_us(500); 	// Leave low for 500uS
	TRISC |= 0x01;		// Set port to input
	DQ = 1; 			// Allow line to return high
	__delay_us (60); 	// Wait 60uS for present signal
	present = DQ; 		// Get present signal
	__delay_us (60); 	// Wait 60uS for end of time slot
	return (present); 	// Present signal returned
}

/*==================================================================================
**
** READ_BIT - the time_delay required for a read bit is 15uS
**
** =================================================================================
*/

unsigned char read_bit (void)
{
	unsigned char i;
	
	TRISC |= 0x01;	// Set port to input
	DQ = 0;			// pull DQ line low to start time slot
	DQ = 1; 		// then return immediatly high

	for (i=0; i<1; i++); 	// require 15us time_delay, 1 cycle appears to be 12uS
	return (DQ); 			// return value of DQ line
}

/*==================================================================================
**
** WRITE_BIT - writes a bit to the one-wire bus
**
** =================================================================================
*/

void write_bit (char b)
{
	unsigned char i;

	TRISC &= ~0x01;	// Set port to output
	DQ = 0;					// pull DQ line low to start time slot
	if (b==1)
		DQ = 1;				// return DQ high of write 1

	__delay_us (60);			// Wait 60uS for end of time slot

	DQ = 1; 				// return DQ immediatly high

	for (i=0; i<1; i++); 	// require 15us time_delay, 1 cycle appears to be 12uS
}

/*==================================================================================
**
** READ_BYTE - reads a byte from the one-wire bus
**
** =================================================================================
*/

unsigned char read_byte (void)
{
	unsigned char i;
	unsigned char value = 0;

	TRISC |= 0x01;			// Set port to input
	for (i=0; i<8; i++) 	// reads in 8 bits of data
	{
		if (read_bit ()) value |= 0x01 << i;	// reads data in and shifts it left
		__delay_us (60); 	// Wait 60uS for end of time slot
	}
	return (value); 		// return value
}

/*==================================================================================
**
** WRITE_BYTE - writes a byte to the one-wire bus
**
** =================================================================================
*/

void write_byte (char val)
{
	unsigned char i;
	unsigned char temp;
	
	TRISC &= ~0x01;	// Set port to output
	for (i=0; i<8; i++) 	// writes byte one bit at a time
	{
		temp = val >> i;	// shifts val right i spaces
		temp &= 0x01;		// copy that bit to temp
		write_bit (temp);	// write bit
	}

	__delay_us (60); 		// Wait 60uS for end of time slot
}

/*==================================================================================
**
** READ_TEMPERATURE - writes a byte to the one-wire bus
**
** =================================================================================
*/

unsigned char Read_Temperature(void)
{
	static char get[10];
	char temp_lsb,temp_msb;
	int k;
	char temp_c;
	unsigned char i;
	
	ow_reset();			// Send reset and receive presence pulse
	write_byte(0xCC); 		// Skip ROM
	write_byte(0x4E); 		// Write Scratchpad
	write_byte(0x00); 		// Write data byte TH
	write_byte(0x00); 		// Write data byte TL
	write_byte(0x7F); 		// Write data byte CONFIG
	write_byte(0x4E); 		// Write Scratchpad
	__delay_us(60);			// 60uS delay
	ow_reset();			// Send reset and receive presence pulse
	write_byte(0xCC); 		// Skip ROM
	write_byte(0xBE); 		// Read ScratchPad
	
	for (k=0;k<9;k++)		// receive & read 9 data bytes
		{
		get[k]=read_byte();
		}
	ow_reset();			// Send reset and receive presence pulse
	write_byte(0xCC); 		// Skip ROM
	write_byte(0x48); 		// Copy Scratchpad

	DQ = 1; 			// return DQ immediatly high
	for (i=0; i<1; i++); 		// require 10mS time_delay, while copy is in progress
	
	printf("\n ScratchPAD DATA = %X %X %X %X %X %X %X %X %X \n",get[8],get[7],get[6],get[5],get[4],get[3],get[2],get[1],get[0]);
	
	temp_msb = get[1]; 		// Sign byte + lsbit
	temp_lsb = get[0]; 		// Temp data plus lsb

	if (temp_msb <= 0x80){temp_lsb = (temp_lsb/2);} // shift to get whole degree
	temp_msb = temp_msb & 0x80; // mask all but the sign bit
	if (temp_msb >= 0x80) {temp_lsb = (~temp_lsb)+1;} // twos complement
	if (temp_msb >= 0x80) {temp_lsb = (temp_lsb/2);}// shift to get whole degree
	if (temp_msb >= 0x80) {temp_lsb = ((-1)*temp_lsb);} // add sign bit

//	printf( "\nTempC= %d degrees C\n", (int)temp_lsb ); // print temp. C
	temp_c = temp_lsb;
	return(temp_c);
}

Or should I just put the read temp routine in my main routine in the main c file?? And add something like this to the end
Code:
Read_Temperature();
	lcd_goto(0x40);
	sprintf(buff," %d degrees C\n", temp_c;
 
Last edited:
You are close but temp_c is not global so you wont get results.

Code:
    unsigned char TemperC = 0;

    TemperC = Read_Temperature();
    lcd_goto(0x40);
    sprintf(buff," %d degrees C\n", TemperC ;
    lcd_puts(buff);
 
Close but no sigar ;)
I get this error
Code:
conflicting declarations for variable "_Read_Temperature"
 
That means the actual definition:
Code:
unsigned char Read_Temperature(void);
is different from the one in the file

Code:
unsigned char Read_Temperature(void)
{
	static char get[10];
	char temp_lsb,temp_msb;
	int k;
	char temp_c;
	unsigned char i;
	
	ow_reset();			// Send reset and receive presence pulse
	write_byte(0xCC); 		// Skip ROM
	write_byte(0x4E); 		// Write Scratchpad
	write_byte(0x00); 		// Write data byte TH
	write_byte(0x00); 		// Write data byte TL
	write_byte(0x7F); 		// Write data byte CONFIG
	write_byte(0x4E); 		// Write Scratchpad
	__delay_us(60);			// 60uS delay
	ow_reset();			// Send reset and receive presence pulse
	write_byte(0xCC); 		// Skip ROM
	write_byte(0xBE); 		// Read ScratchPad
	
	for (k=0;k<9;k++)		// receive & read 9 data bytes
		{
		get[k]=read_byte();
		}
	ow_reset();			// Send reset and receive presence pulse
	write_byte(0xCC); 		// Skip ROM
	write_byte(0x48); 		// Copy Scratchpad

	DQ = 1; 			// return DQ immediatly high
	for (i=0; i<1; i++); 		// require 10mS time_delay, while copy is in progress
	
	printf("\n ScratchPAD DATA = %X %X %X %X %X %X %X %X %X \n",get[8],get[7],get[6],get[5],get[4],get[3],get[2],get[1],get[0]);
	
	temp_msb = get[1]; 		// Sign byte + lsbit
	temp_lsb = get[0]; 		// Temp data plus lsb

	if (temp_msb <= 0x80){temp_lsb = (temp_lsb/2);} // shift to get whole degree
	temp_msb = temp_msb & 0x80; // mask all but the sign bit
	if (temp_msb >= 0x80) {temp_lsb = (~temp_lsb)+1;} // twos complement
	if (temp_msb >= 0x80) {temp_lsb = (temp_lsb/2);}// shift to get whole degree
	if (temp_msb >= 0x80) {temp_lsb = ((-1)*temp_lsb);} // add sign bit

//	printf( "\nTempC= %d degrees C\n", (int)temp_lsb ); // print temp. C
	temp_c = temp_lsb;
	return(temp_c);
}

Make sure if your using a header file that

unsigned char Read_Temperature(void);

is the definition ok
 
Ok so igt to have a header file that just contains
Code:
unsigned char Read_Temperature (void);

And all the other rutines I might call foom the main file?

Like the lcd.h

Edit
OK so i made the header file
But i get this error
Code:
Error   [800] C:\Program Files\HI-TECH Software\PICC\9.80\sources\printf.c; 1617. undefined symbol "fpbase"
Error   [800] C:\Program Files\HI-TECH Software\PICC\9.80\sources\printf.c; 1617. undefined symbol "fp__putch"

edit 2

Solved it by commenting out
Code:
 printf
parts, hoping it works
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top