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.

LCD With microcontroller.....

Status
Not open for further replies.
You mean you want to show ASCII representation of the ADC result?

Code:
( ADRESH*256+ADRESL)*5.0/1023)*10);

This has a floating point in it... You will find it hard to convert float to ascii...

There is a horrible ftoa(); routine in HTC

My advise ( not that you'll take it ) is to use fixed point math.


Code:
 ((long)(ADRESH)*256+ADRESL)*5000/1023);

This yeids 0 to 5000.

Drop in the decimal after the first digit.
 
I am thinking to use itoa() function then something like sprintf as per 3v0 suggestion in chat...
 
Code:
void printFloat(char * flt, long number, char digits)
	{
	if(number < 0)
		{
		number = ABS(number);
		}
	if(digits == 2)
		{
		flt[0] = number / 1000 + 48;
		if(flt[0] == 48) flt[0] = 0x20;
		flt[1] = ((number % 1000) / 100)+ 48;
		flt[2] = 46;
		flt[3] = ((number % 100) / 10)+ 48;
		flt[4] = (number % 10) + 48;
		flt[5] = 0;
		}
	else
		{
		flt[0] = number / 100 + 48;
		if(flt[0] == 48) flt[0] = 0x20;
		flt[1] = ((number % 100) / 10)+ 48;
		flt[2] = 46;
		flt[3] = (number % 10) + 48;
		flt[4] = 0;
		}
	}

1 or 2 decimal places with zero blanking.
 
Code:
flt[1] = ((number % 1000) / 100)+ 48;
		flt[2] = 46;
		flt[3] = ((number % 100) / 10)+ 48;

Hi again,

why are you taking modulus??
 
Are you sure you want me to tell you that.... A bit blatantly obvious.... Take a number 512 .

If I wrote flt[1] = number / 100 + 48 flt would be decimal 53 or hexadecimal 0x35 or ascii "5" which would be correct...
Let assume the bigger number '1512'

flt[1] = number / 100 + 48 would be decimal 62 or hexadecimal 0x3E or ascii '>' Which isn't correct.

With the modulus I don't have to remove the thousands, hundreds and tens each iteration.
 
Please tell me the working then i will understand it easily the routine used to convert the interger to ascii..
one more thing in Lcd_goto for selecting line and column..
ADD: DDRAM AD & CursorAD
are used i have notice and it was working in LCD too..but i don't understand the data sheet say
READDDRAM: Display data RAMCGRAM: Character Generator RAM

what the use of these register...?
 
Ok.. Let say we have to convert the number 4257 to display on the LCD as 4.257V

The digital ADC read of 871 ( using the above equation, which was.... ADC_val * 5000 / 1023..)

1) Divide the number 4257 by 1000 and you get 4, add in the ASCII '0' ( 0x30 ) and put it in the first buffer location flt[0]...
2) Now just put the decimal place in... flt[1] = '.' decimal 46...
3) Remove the thousands by modulus 1000 and you get 257 now divide by 100 to get 2 add the ASCII 0x30 and put it in the buffer flt[2]...
4) Remove the hundreds by modulus 100 and you get 57 now divide by 10 to get 5 add the ASCII 0x30 and put it in the buffer flt[3]...
5) Now you can just do modulus 10 to get the last digit 7 and add the ASCII 0x30 and put it in the buffer flt[4]...
6) Lastly as we are creating a string.. put the NULL in at the end of the buffer flt[5]

flt[0] = '4'
flt[1] = '.'
flt[2] = '2'
flt[3] = '5'
flt[4] = '7'
flt[5] = '\0'

Done..

There are 8 positions ( a total of 64 bytes for the special characters you can make ) this is CGRam and the DDram display data ram is for displaying your font locations 0x80 to 0xA8 and 0xC0 to 0xE8.. I think 4 x 20 is the biggest...
 
There are 8 positions ( a total of 64 bytes for the special characters you can make )

which type of character and how we can make?

and the sprintf function is not working showing error conflicting _sprintf.
Code:
#include <htc.h>
__CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);
#define _XTAL_FREQ 20000000
 
#define DATA PORTB
#define EN RC4
#define RS RC6
#define RW RC5
#define N 40
#define M 20
int number=0;
int ch=0;
unsigned char LCDbuffer[17];

void LCDcmd(char x), LCDdata(char x);
void LCD_goto(char line, char column)	;
int ReadADC();

main(){
	TRISB=0X00;
	TRISC=0X00;
TRISA = 0xff ;
ADCON1=0b00000000;
ADCON0=0b10000001;//000 = channel 0, (RA0/AN0)
	ADIF=0;
	ADIE=1;
	PEIE=1;

__delay_ms(50);
 	LCDcmd(0x38); // init
	__delay_ms(N);
	LCDcmd(0x38); // init
	__delay_ms(N);
	LCDcmd(0x38); // Function set
	__delay_ms(N);
 	LCDcmd(0x06); // Cursor move increase, no display shift
	__delay_ms(N);
	LCDcmd(0x0C); // Display on, cursor off, not blinking

	__delay_ms(N);
	LCDcmd(0x01); // Clear display. goto pos 1
 	__delay_ms(N);

	while(1){
LCD_goto(1,2);
number = ReadADC();
sprintf(LCDbuffer,"%d ",number);







 	
	}


}

 
void LCDcmd(char x)
	{
	__delay_ms(N);
	RS=0;
	RW=0;
	__delay_ms(M);
	EN=1;
	__delay_ms(M);
	DATA = x;	// Command data
	__delay_ms(M);
	EN=0;
	__delay_ms(M);
	}
void LCDdata(char x)
	{
	RS=1;
	RW=0;
	__delay_ms(M);
	EN=1;
	__delay_ms(M);
	DATA = x;  //  Print data
	__delay_ms(M);
	EN=0;
	__delay_ms(M);
	}






void LCD_goto(char line, char column)		// combines line and lineW
	{
	unsigned char data = 0x80;				// default to 1
	if(line == 2)data = 0xc0;				// change to 2
	data += column;							// add in  column
	 LCDcmd(data);
	}

int ReadADC()
	{
	int ret = 0;
	__delay_ms(10);
	GO_DONE = 1;						// start conversion
   	while(GO_DONE);					// wait for conversion
   	ret =  (ADRESL & 0x3) << 8;		// get
   	ret +=	ADRESH;					// result
	return ret;
	}
 
Last edited:
OK, its working after adding this..the value on LCd while cahnging pot divider 5V ref ...0 to 255

Code:
	while(1){
LCD_goto(2,2);
number = ReadADC();
sprintf(LCDbuffer,"%d ",number);

LCD_printR(LCDbuffer);

	}
 
One problem I am getting 2.5V max i am using 20K pot divider to ADC and rest pint to GND and Vcc of 5V, why 2.5V Max why not 5V??

Code:
number = ReadADC();
//sprintf(LCDbuffer,"%d.%02dV ",number);
LCDbuffer[0]= (number / 1000)+ 48;
if(LCDbuffer[0] == 48) LCDbuffer[0]= 0x20;
	LCDbuffer[1] = ((number % 1000) / 100)+ 48;
	LCDbuffer[2] = 46;
	LCDbuffer[3] = ((number % 100) / 10)+ 48;
	LCDbuffer[4] = (number % 10) + 48;
	LCDbuffer[5] = 0;

LCD_printR(LCDbuffer);

IS there any problem in setting
ret = (ADRESL & 0x3) << 8; // get
ret += ADRESH;
return ret;
ADCON1=0b00000000;
ADCON0=0b10000001;//000 = channel 0, (RA0/AN0)
 
after adding it showing unknow char not working

Code:
LCD_goto(2,2);
number = ReadADC();
number = number *5000 / 1023;
LCDbuffer[0]= (number / 1000)+ 48;
if(LCDbuffer[0] == 48) LCDbuffer[0]= 0x20;
	LCDbuffer[1] = ((number % 1000) / 100)+ 48;
	LCDbuffer[2] = 46;
	LCDbuffer[3] = ((number % 100) / 10)+ 48;
	LCDbuffer[4] = (number % 10) + 48;
	LCDbuffer[5] = 0;

LCD_printR(LCDbuffer);
 
hi ritesh,

This is commented example of the method used in Basic code for converting a 10bit Binary value to 4 ASCII characters., its for reference ONLY, so that you can see the procedure.

''name the binary word as adcval and call this subr and the ASCII
'output result will be in ascbfr 3,2,1,0, ready for your LCD
'just place the DP in the output to the LCD as required

'examples eg: shown are for a max 5V input voltage to the ADC and displayed as 5.000
'I would advise you drop the last decimal value and display as 5.00

'adcval is the 10 bit Binary value from the ADC [for example let adcval= 987, so 987*5 =4935]

bin2asc:' convert a 10bit binary value to 4 , ASCII characters
ascbfr3 = adcval/ 1000 ' how many 1000's in the value eg: =4 . place in bfr3
temp3 = adcval Mod 1000 ' get remainder from modulus 1000 eg: 935

ascbfr2 = temp3 / 100 ' how many 100's in the previous remainder eg: =9 place in bfr2
temp3 = temp3 Mod 100 ' get remainder from modulus 100 eg: 35

ascbfr1 = temp3 / 10 ' how many 10's in the previous remainder eg: =3 place in bfr1
ascbfr0 = temp3 Mod 10 'get remainder from modulus 10 eg: =5 place bfr0

'ascbfr array results are now in BCD =eg: [0100], [1001], [0011], [0101]

'so convert BCD to ASCII for LCD.
'OR each location with 30h to make ASCII number.
ascbfr4 = ascbfr4 Or 0x30 ' eg: 00000101 OR 00110000 = 00110100 =34h = '4' ASCII
ascbfr3 = ascbfr3 Or 0x30
ascbfr2 = ascbfr2 Or 0x30
ascbfr1 = ascbfr1 Or 0x30
ascbfr0 = ascbfr0 Or 0x30
 
Status
Not open for further replies.

Latest threads

Back
Top