Help with display/print function for LCD

thatoneguy

Joined Feb 19, 2009
6,359
Buffer size is the longest string, so 16 for one line of a 16x2 LCD, or 32 for both lines, or the longest you'll expect it to be (whichever is shorter), each extra takes a byte of RAM, so don't declare it any longer than you need it to be.
 

Thread Starter

chimera

Joined Oct 21, 2010
122
Buffer size is the longest string, so 16 for one line of a 16x2 LCD, or 32 for both lines, or the longest you'll expect it to be (whichever is shorter), each extra takes a byte of RAM, so don't declare it any longer than you need it to be.

So I can simply say char buffer[15]. That will take care of the only the first 15 characters on the LCD? If so, then I indeed have to be careful with alloting the size. But in my actual code, i left the number of elements blank:

char buffer[];----> I figured in this way, it'll take up as much as it needs to get the job done. Rational thinking or stroke of luck?
 

spinnaker

Joined Oct 29, 2009
7,830
hahah.. true.. all I am seeing is 'A' on the screen. Why is that and How can I deal with that? By parsing the values?
If you would go with my advice then it will be much more simple. There is no reason to do it the way you are doing it unless you are dealing with floating point numbers as integers.

Floating point numbers and math take a lot of memory so you usually want to do all integer math including divides.

Since most of my programs so far have not had tons of floating point math I just use floating point math to make it easier on myself.

The length of your buffer is going to depend on the width of your display. If it is a 16 character display then use 17 (one character for null). I usually pad it a bit if using sprintf. That way I don't need to worry that I get a data overrun if printing a larger number than expected.
 

spinnaker

Joined Oct 29, 2009
7,830
So I can simply say char buffer[15]. That will take care of the only the first 15 characters on the LCD? If so, then I indeed have to be careful with alloting the size. But in my actual code, i left the number of elements blank:

char buffer[];----> I figured in this way, it'll take up as much as it needs to get the job done. Rational thinking or stroke of luck?
You need to allow one character for the null character as I mentioned above.

But are you sure your display is no 16 characters?
 

Thread Starter

chimera

Joined Oct 21, 2010
122
If you would go with my advice then it will be much more simple. There is no reason to do it the way you are doing it unless you are dealing with floating point numbers as integers.
You are suggesting that I should use %i instead of %u in the sprintf? With %i, i cannot see my integer that I am trying to display. But when I use %u, I can

The length of your buffer is going to depend on the width of your display. If it is a 16 character display then use 17 (one character for null). I usually pad it a bit if using sprintf. That way I don't need to worry that I get a data overrun if printing a larger number than expected.
The way the LCD is lined up, if I have to display exactly 16 characters on one line, I go ahead and do it. The null character goes onto the next address, which exsists in the DDRAM of the LCD but does not gets displayed. This data is avaliable on the HD44780 Hitachi LCD 16x2 data sheet.
 

thatoneguy

Joined Feb 19, 2009
6,359
Spinnaker is correct, I forgot that bit.

In C, strings are terminated by NULL, so when using a sprintf statement, it would send the string until NULL (0x00) was encountered, the NULL isn't sent to the LCD. The numeric 0 and NULL are different, as the 0 is an ASCII number that represents "0", and 0x00 is "NULL".
 

spinnaker

Joined Oct 29, 2009
7,830
You are suggesting that I should use %i instead of %u in the sprintf? With %i, i cannot see my integer that I am trying to display. But when I use %u, I can

I keep telling you but you won't try it.

char buffer[17];
int a = 2456

sprintf(buffer, "Value=%i";a);
Print(buffer);


%i and %u are essentially the same. %u is for unsigned integers though I don't recall ever using it that way I think I have always used %i.

The way the LCD is lined up, if I have to display exactly 16 characters on one line, I go ahead and do it. The null character goes onto the next address, which exsists in the DDRAM of the LCD but does not gets displayed. This data is avaliable on the HD44780 Hitachi LCD 16x2 data sheet.
If your Print function is written properly, it will not be sending a null to the LCD. Post your code for Print (char *buffer).
 

Thread Starter

chimera

Joined Oct 21, 2010
122
here is the code for Print and the actual program that I am using it in. I keep telling you that %i doesnt work. BTW, %i is for integers and %c is for characters from what I have gathered.

Rich (BB code):
void Print(char *Text)
{
    char *c;
    c=Text;
    if(!Text) return;
    for( c = Text; *c != '\0'; ++c)
    {
        SendByte(*c, TRUE);
    }
}
main code:
Rich (BB code):
#include <msp430g2231.h>
#include <stdio.h>
#include "lcd.h"

char buffer[17];
int a = 2456;

void main(void) {
    WDTCTL = WDTPW + WDTHOLD;
    P1DIR=0xF9;                // microcontroller
    P1OUT=0;            // microcontroller
    LCD_init();        // Initialize LCD
    clear();    // Clear LCD

sprintf(buffer, "Value=%i",(a+'0'));
Print(buffer);
}
The above only works for 1- %c and 2- for a single integer, because 1- when I use %i, the 'text' shows up but the actual number its self doesnt and 2- When I use %c, then only the 'text' and the first digit shows up (not all of them). I have to send each digits manually by parcing them (not shown in the above main code). Hope this clarifies my situation. But I really do appreciate your help. THANKS!
 

spinnaker

Joined Oct 29, 2009
7,830
here is the code for Print and the actual program that I am using it in. I keep telling you that %i doesnt work. BTW, %i is for integers and %c is for characters from what I have gathered.

Because you are not paying attention to what I am telling you. I have only been printing integers this way to buffers for the last 25 years or so.

Rich (BB code):
void Print(char *Text)
{
    char *c;
    c=Text;
    if(!Text) return;
    for( c = Text; *c != '\0'; ++c)
    {
        SendByte(*c, TRUE);
    }
}
main code:
Rich (BB code):
#include <msp430g2231.h>
#include <stdio.h>
#include "lcd.h"

char buffer[17];
int a = 2456;

void main(void) {
    WDTCTL = WDTPW + WDTHOLD;
    P1DIR=0xF9;                // microcontroller
    P1OUT=0;            // microcontroller
    LCD_init();        // Initialize LCD
    clear();    // Clear LCD

sprintf(buffer, "Value=%i",(a+'0'));
Print(buffer);
}
The above only works for 1- %c and 2- for a single integer, because 1- when I use %i, the 'text' shows up but the actual number its self doesnt and 2- When I use %c, then only the 'text' and the first digit shows up (not all of them). I have to send each digits manually by parcing them (not shown in the above main code). Hope this clarifies my situation. But I really do appreciate your help. THANKS!
Look at what I gave you again.

Change this

sprintf(buffer, "Value=%i",(a+'0'));

to this

sprintf(buffer, "Value=%i",a);


Look at you debugger and see what is going into buffer before sending it to the LCD.
 

Thread Starter

chimera

Joined Oct 21, 2010
122
I dont know why its not printing. I have tried your method again and again, but the integer just wont print. The "value" text prints, but the integer its self does not print.

I am following what your saying and I can tell that you are a seasoned programmer

Rich (BB code):
#include <msp430g2231.h>
#include <stdio.h>
#include "lcd.h"

char buffer[17];
int a = 2456;

void main(void) {
    WDTCTL = WDTPW + WDTHOLD;
    P1DIR=0xF9;                // microcontroller
    P1OUT=0;            // microcontroller
    LCD_init();        // Initialize LCD
    clear();    // Clear LCD

sprintf(buffer, "Value=%i",a);
Print(buffer);
}
Please look at post# 30 to see my Print function, maybe that might be the problem (although it wont caz I can see it working )

By the way, the buffer = 0x0200
[0] = V
[1] = a
[2] = l
[3] = u
[4] = e
[5] = =
[6] = .
[7] = 0
[8] = 3
[9] = .
[10] = .
[11] = .
[12] = .
[13] = .
[14] = .
[15] = .
[16] = ,
 

spinnaker

Joined Oct 29, 2009
7,830
Please look at post# 30 to see my Print function, maybe that might be the problem (although it wont caz I can see it working )

By the way, the buffer = 0x0200
[0] = V
[1] = a
[2] = l
[3] = u
[4] = e
[5] = =
[6] = .
[7] = 0
[8] = 3
[9] = .
[10] = .
[11] = .
[12] = .
[13] = .
[14] = .
[15] = .
[16] = ,
If this is the value of your buffer before it makes a call to your Print function then your Print function is not the problem. Or at least not yet. :)


You now look to have everything right. At least in the sprintf statement.

I can't see how you are getting all of those other characters on there. It could be because it is garbage not initialized by the complier.

Try this right before you call sprintf

memset(buffer,0,17);

It will clear the buffer with all zeros.

Set a breakpoint on memset, single step and check the value.


Then check the value after you call sprintf.

This will tell us if the garbage was there before the call or if the sprintf is doing it.

When you debug, the debugger sometimes steps into a function before you have a chance to check the value.

Example:

sprintf(buffer,"Value = %i", a);
Print(buffer); <breakpoint set here

What some debuggers do is enter Print before you get a chance to check buffer.

So you can setup a fake instruction:

sprintf(buffer,"Value = %i", a);
i=0; <breakpoint set here
Print(buffer);

of course you need to define i.


It could be that your compiler doers not support %i. Check your documentation. But good luck. MPLAB does not support %f but it is not documented anywhere I know of.


You can also try %X. It will print in hexidecimal but at least you know it is working.
 

Thread Starter

chimera

Joined Oct 21, 2010
122
When I try to compile it, it says that the memset function is declared implicitly

Rich (BB code):
#include <msp430g2231.h>
#include <stdio.h>
#include "lcd.h"

char buffer[17];
int x;

void main(void) {
    WDTCTL = WDTPW + WDTHOLD;
    P1DIR0xF9;                // microcontroller
    P1OUT=0;                  // microcontroller
    LCD_init();                 // Initialize LCD
    clear();                // Clear LCD
    x=314;
    memset(buffer,0,17);
    sprintf(buffer,"Value=%i",x);
    Print(buffer);
}
 

spinnaker

Joined Oct 29, 2009
7,830
When I try to compile it, it says that the memset function is declared implicitly

Rich (BB code):
#include <msp430g2231.h>
#include <stdio.h>
#include "lcd.h"

char buffer[17];
int x;

void main(void) {
    WDTCTL = WDTPW + WDTHOLD;
    P1DIR0xF9;                // microcontroller
    P1OUT=0;                  // microcontroller
    LCD_init();                 // Initialize LCD
    clear();                // Clear LCD
    x=314;
    memset(buffer,0,17);
    sprintf(buffer,"Value=%i",x);
    Print(buffer);
}

Try

#include <string.h> at the top of your code.

 

spinnaker

Joined Oct 29, 2009
7,830
nope, my compiler does not recongnize <string.h> lol.
That is one bizarre compiler. Do a file find on string.h in the directory that has your compiler files. Make sure it is just not a path issue.

Check your documentation to see if it tells you where memset is defined. The standard is string.h.


In some compilers memset is defined in memory.h.


But you don't really need to do that memset. Just inspect buffer before and after the call to sprintf.

But I would still be curious to see why you don't have a string.h. You have to have it. If you don't I'd suggest dumping that thing and getting something else. It would mean you have a very non standard c compiler.
But I am betting on a path issue.

And you did put #include <string.h> at the top of your code right? And not inside the main function?
 

thatoneguy

Joined Feb 19, 2009
6,359
Have you looked in the helpfile for "String operations"?

It should list useful functions for this, AND tell you the name of the header file you need to include.

Maybe you need to add strings.h to your project? (in addition to including it. that's if you are including "strings.h" and not <strings.h>)
 

spinnaker

Joined Oct 29, 2009
7,830
Have you looked in the helpfile for "String operations"?

It should list useful functions for this, AND tell you the name of the header file you need to include.

Maybe you need to add strings.h to your project? (in addition to including it. that's if you are including "strings.h" and not <strings.h>)
I have yet to see where that is documented in the C18 compiler. So..... :)
 

thatoneguy

Joined Feb 19, 2009
6,359
I was thinking of the reverse.

the sprintf is the correct way to do it, using either %d or%i or any of the other formatting definitions.

It's the same in BoostC and gcc, so it should be the same in CCS (Which is included with launchpad)
 
Top