LCD 16X2 charcter

Go To Last Post
23 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello people, im using an LCD 16x2 with atmega, and on the screen there is one charcter that wont be there, i dont know how to take off.

Anyone help?

 

I try using this code but doesnt resolve.

 

for (int k=0; k<=15; k++){ // data1 is my string to pring 16 charcter

     data1[k]=' ';

  sprintf(data1, "%d    Cm   %d",distancia, distancia2); //Print on data1 two vars and 'cm'

 

for (int k=0; k<=15; k++){

dis_data(data1[k]); _delay_us(800);

}

 

 

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Remnants of the cursor? Have you tried to turn it off?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It could be a stored custom character, perhaps in cgram location 0, so prints if you send a null character!

 

Please post a link to where you got your LCD, or a link to its datasheet.

 

Jim

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yeah, that's a null byte. Those LCDs use characters 0x00 through 0x07 as custom user-programmable characters and have defaults for them.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, its an 16x2 with number 1602

datasheet https://www.openhacks.com/upload...

 

Im using with 4bit mode with this configuration:

 

dis_cmd(0x02); //LCD 4 bits

dis_cmd(0x2C); //define o LCD como um de 16x2 4bits 

dis_cmd(0x06); // Increment cursor (shift cursor to right)

dis_cmd(0x80); // move cursor para o 1º point da 1ª line

 

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does it disappear if you turn down the contrast and/or the brightness pot?  

 

Jim

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello Jim,

 

No, do not disappear, and if a took off my FOR (   for (int k=0; k<=15; k++){    data1[k]=' ';}  )  all the position that havent anything to print stays with that symbol. and i saw in datasheet to use 0x01 on configuration to clean screen but if i add that the screen stay blinking 4ever.

 

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Why are you sending character by character for 15 characters irrespective of strlen(data1).

 

A more "normal" string printing routine would print up to but not including the terminating NUL. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

Im printing with ' ' to clear all LCD, if dont it stay this way:

 

 

I dont know why even with all position clear with FOR why still on2 charcter in the screen?

 

Thanks

Last Edited: Mon. Dec 18, 2017 - 08:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
void dis_string(char * str) {
    while(*str) {
        dis_data(*str++);
    }
}

Then

dis_string(data1);

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Joao, when you do the following in your code, do you realize that the characters that follows the %d converted value of distancia2, '0' in this last case, is a null character.  You are printing the string that you want plus all of the characters that follow it including the null character and they are being displayed perfectly!  You need to only print the string itself and not the null characters as clawson indicated earlier and has shown in his code in the post above.

 

sprintf(data1, "%d    Cm   %d",distancia, distancia2); //Print on data1 two vars and 'cm'

for (int k=0; k<=15; k++){
dis_data(data1[k]); _delay_us(800);

EDIT: post above

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Mon. Dec 18, 2017 - 11:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Joao Pinto wrote:

...

  sprintf(data1, "%d    Cm   %d",distancia, distancia2); //Print on data1 two vars and 'cm'

 

for (int k=0; k<=15; k++){

dis_data(data1[k]);

...

Im printing with ' ' to clear all LCD, ...

 

If I want to use sprintf() to format a line that will be put to an LCD during periodic update, I will let sprintf() take care of building the entire line, then output the entire line.  Example:

 

#define LCD_WIDTH 16

...

unsigned char line_buffer[LCD_WIDTH+a few];  //"a few" might be 5 or 6 .

 

...

sprintf (line_buffer, "%5u  Cm  %5u", distance1, distance2); // build at least the full line

 

line_buffer[LCD_WIDTH] = '\0'; // ensure no more than one line

 

... then position to the beginning of an LCD line, and output line_buffer as a strung up to terminating null

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When I update an LCD, I print the data, plus fill the rest of the line with "space" characters to erase any previous data on the line.

I find this works better then doing a clear screen, as that will cause the screen to blink with each update, but does not if I clear any unused positions using a space "0x20" character.

I thought that was what the OP was doing, but it looks like he may be using null or at least not stopping at the null and continuing to fill the line with spaces.

 

 

Jim

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello guys

 

I resolve the problem with this:

 

sprintf(data1, "%d           %d  ",distancia, distancia2); 

data1[7] ='C';

data1[8] ='m';

data1[15] =' ';

 

Its not the best way to do but works fine, i ll keep studying how to do the other way.

 

 

Thanks to all

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you even bother to read #10? You don't need some shonky solution, you need to do it properly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

I really try to use this, but the program dont do /0. Whene the string finish it start again until the lcd line its full. Like:    23    cm   1523 repeat 23.

 

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#ifndef LCD_PRT
	#define LCD_DRT DDRA
	#define LCD_PRT PORTA
#endif
#ifndef	F_CPU
	#define F_CPU 14745600UL
#endif
#include <util/delay.h>
#define LCD_RS 0
#define LCD_RW 1
#define LCD_EN 2

class LCD
{
	public:
	LCD()
	{
		init();
	}
	void init()
	{
		LCD_DRT=0xFF;
		LCD_PRT&=~(1<<LCD_EN);		//make EN=0
		_delay_ms(20);				//startup delay
		cmdSend(0x33);			//33 for 4 bit mode
		_delay_ms(2);
		cmdSend(0x32);			//32 for 4 bit mode
		_delay_ms(2);
		cmdSend(0x28);			//28 for 4 bit mode
		_delay_ms(2);
		cmdSend(0x0C);			//display on cursor off
		_delay_ms(2);
		clearDisplay();
		_delay_ms(2);
		print("Initialized...");
	}
	void clearDisplay()
	{
		cmdSend(0x01);
		_delay_ms(2);
	}

	void dataSend(uint8_t data)
	{
		LCD_PRT=(((data&0xF0)|(1<<LCD_EN)|(1<<LCD_RS))&~(1<<LCD_RW));	//msb data and control to 101
		_delay_us(100);
		LCD_PRT&=~(1<<LCD_EN);						//EN=0
		LCD_PRT=(LCD_PRT&0x0F)|(data<<4);			//shift lsb data
		LCD_PRT|=(1<<LCD_EN);						//make EN=1
		_delay_us(100);
		LCD_PRT&=~(1<<LCD_EN);						//EN=0 - job done
	}

	void cmdSend(uint8_t cmd)
	{
		LCD_PRT=((cmd&0xF0)|(1<<LCD_EN))&~(1<<LCD_RW)&~(1<<LCD_RS);	//msb cmd and control to 100
		_delay_us(100);
		LCD_PRT&=~(1<<LCD_EN);		//EN=0
		_delay_us(100);
		LCD_PRT=(LCD_PRT&0x0F)|(cmd<<4);		//shift lsb cmd
		LCD_PRT|=(1<<LCD_EN);		//EN=1
		_delay_us(100);
		LCD_PRT&=~(1<<LCD_EN);		//EN=0
	}

	void print(char str[])
	{
		clearDisplay();
		_delay_ms(1);
		for(int i=0;str[i]!='\0';i++)
		{
			dataSend(str[i]);
		}
	}
};

Hope this helps...

pass a string like "                " to print()...

[EDIT] Also change clock according to yours...

Show's ON....

Last Edited: Tue. Dec 19, 2017 - 12:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The way I display a string on a display is to have two routines.

The first just writes a single character to the display equivalent to your dis_data() function.

The second is a function to display a string similar to that shown by clawson in Post #10:

void dis_string(char * str) {
    while(*str) {
        dis_data(*str++);
    }
}

then to call the display string function:

char data1[20];   // A buffer to hold the longest string to be generated (+1)
// ... other code ...

// Create the string as needed, 
//   note spaces can be added at the end of the string to overwrite any previous text
sprintf(data1, "%d    Cm   %d  ",distancia, distancia2); // Fill data1 with two vars and 'cm'

// Now display the string
dis_string(data1); 

 

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

SOLVED

 

Intead of unsigned char data1[16];  put just   char data1[16];

 

...

 

sprintf(data1, "%d    Cm   %d  ",distancia, distancia2);

 dis_string(data1); 

 

....

 

Thanks ALL

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, you should modify your displaying routine loop (should be put into a function, anyway, as you were hinted)  like that:

 #define LCDsIZE 16

for (int k=0; k < LCDsIZE ; k++){
 if (data1[k] == 0) break; // copes with null terminated strings
 dis_data(data1[k]); _delay_us(800);

}

This might answer the \0 weird coding and warrants you wonot display more than 16 chars (your LCD display might become bigger or split else).

(using pointers as in 10 is more beautiful, but more difficult to read -ex : fortran users-, is not consistent with your way of writing,   and does not limit the number of chars displayed...) 

 

Edited : looked at (I should have looked at it before...) : http://www.avrfreaks.net/forum/tutc-lcd-tutorial-1001?name=PNphpBB2&file=viewtopic&t=102296

 

Your delays are way too long (should be 50 -80 us...). Hope there are no other unpleasant things (correcting at random until something seems to work is not the best method)

Last Edited: Tue. Dec 19, 2017 - 04:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Joao Pinto wrote:

Hello,

 

SOLVED

 

Intead of unsigned char data1[16];  put just   char data1[16];

 

...

 

sprintf(data1, "%d    Cm   %d  ",distancia, distancia2);

 dis_string(data1); 

 

....

 

Thanks ALL

 

That doesn't seem like it should matter. You'll still have a NUL at the end of the string. But if you added enough spaces that you're getting all 16 spots, then the nul will display off the end of the display. But also you'll potentially write past the end of your buffer. In the example you showed, you had a 1-digit and 3-digit number, so this would be a total of 15 characters, so the NUL should still be showing up, I'd expect. But also you shouldn't be using sprintf into a buffer that might not be large enough for some inputs.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But also you shouldn't be using sprintf into a buffer that might not be large enough for some inputs.

snprintf(data1, sizeof(data1) , "....) can respect the size of the buffer and do the job with a negligeable increase of complexity....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes. snprintf is almost always a better choice.