NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » A few questions...

October 18, 2009
by n3ueaEMTP
n3ueaEMTP's Avatar

I currently have a project that activates a light & buzzer using a state machine (an adaptation of the traffic light project). I would like to add the new keyboard project to it so that I can change the EEPROM in the field without using a computer. The information that would need changing is text for the LCD. After looking over the keyboard project I have a question:

The keyboard project outputs directly to the LCD & erases each character after printing it to the LCD. Is there a way to combine alpha characters in separate variables into a single variable?

Thanks for any help you could provide.

October 19, 2009
by hevans
(NerdKits Staff)

hevans's Avatar

Hi n3ueaEMTP,

I'm not entirely sure I understand your question, but I'll try to clear strings up as best I can. Strings can be a confusing thing in C, especially to programmers that come from a Java or Python background. In C you are better off thinking of Strings as arrays of characters (which they are). Each string is terminated by a null character, or 0x00.

So, in order to create a string in C, you do something like this.

char a_string[10];
a_string[0] = 0;

This creates an array, 10 chars long with all 0s in it. Since in this case the first char is a null 0x00, then the string is empty.

Now say I read a character from my keyboard, and store it in the variable c. Then I could do

a_string[0] = c;
a_string[1] = 0;

This will set the first character equal to c, and my string will now be one character long. I then put the next character into the next spot, and so on. Notice that when dealing with strings in C, you need to keep track of the current position of your string, this is usually done with a separate variable.

Now say I had added 5 characters to the string, and now wanted to erase all but the first letter. Well just do

a_string[1] = 0x00;

This sets the second char to be a null char, which in C means that is the end of the string.

So the basic idea is that one you have a character array, you can put characters in it any way you want, and everything from the beginning to the first null char is the contents of the string. If you take a look at lines 159-172 of the Interrupts: Interfacing a Microcontroller with a PS/2 Keyboard code you will see that that is all we are doing. Reading a character putting in the next spot in our array, and advancing the null termination.

Note that you do have to be careful in C because you have to predesignate the max size of your string. If you overflow the initial size of the array you allocated, your code will be in trouble. You also need to keep track of the position of your string so you know where to add new characters. It is a bit lower level than Java, but then again that is what we love about C!

When dealing with strings, the libc library has some useful functions for copying, concatenating, doing other string manipulations. A lot of the same functionality is found in the avr-libc library. However if you are dealing with one character at a time you can just put into in a char array.

Hope that explains everything.

Humberto

October 19, 2009
by n3ueaEMTP
n3ueaEMTP's Avatar

Humberto, thanks for answering my question. What I want to be able to do is have an end user connect a keyboard so they can change a scrolling line of text on the LCD.

Thanks

Chris B.

October 20, 2009
by rusirius
rusirius's Avatar

Chris, I couldn't tell from your post rather you realized Humberto fully answered your question or if you were still confused... To shorten it a bit and directly answer your question, yes, you can concatenate multiple variables into one..

You could define one "string" as a "line" of text.. i.e. char display_string[20] = 0;

then if you had three variables (each a char) that you wanted to put in that string you could do: display_string[0] = varA; display_string[1] = varB; display_string[2] = varC; display_string[3] = 0;

The last line wouldn't be "required" if this was the first time, but if you weren't sure there was previous data that was longer, it's safer to do it (that terminates the string)...

Then you could write display_string out to the LCD...

In your situation though you'll probably be wanting to "append" each character as it comes in. There is a nifty way to "search" for the position of the first null char to see where you need to append, but to simplify, you can just use another variable to "Track" where you are at in the string... So...

     char display_string[20] = 0;
     int cur_position = 0;

     if cur_position < 20 and new character has been typed then
           display_string[cur_position] = typed_char;
           display_string[cur_position+1] = 0;
     end if

Is that what you're looking for?

October 20, 2009
by rusirius
rusirius's Avatar

also, note the loop checks for LESS THEN 20... When defining arrays, the elements START from 0... I.e. a 20 element array as above has elements [0] through [19]... If you tried to use display_string[20] you'd bomb out... ;)

October 20, 2009
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Guys,

I had made a mistake in my previous post. The statement

char a_string[20] = 0;

Is not a valid statement. When you declare an array, the variable itself is actually a pointer to the first element of the array. In this case initializing that array in that manner does not even compile. It gives you an invalid initializer error. There are ways to statically initialize an array in C, however because of the architecture of this chip (program is store in flash), it is a bad idea to statically initialize your arrays that are in RAM. A good way to initialize an empty string is to declare:

char a_string[20];
a_string[0] = 0;

That way you are sure that the first element in the array is a null character.

Humberto

October 21, 2009
by rusirius
rusirius's Avatar

LOL, and I piggy backed right off it and never caught it either... go figure... ;)

October 21, 2009
by rusirius
rusirius's Avatar

You know, oddly enough just thinking about this, I think I've encountered this before somewhere in some sample code I was looking through... Can't remember where it was now, maybe in the source for one of the libs or something? Maybe it wasn't even any of the nerdkit stuff... I just remember copying it into another piece of code I was working on to make my life easier, and starring at the compiler error trying to figure out why the heck it wasn't working... I musta spent like 10 minutes before it finally hit me that you couldn't do it.. I figured you guys stuck it in there on purpose to make a little "extra credit thinking"...

November 28, 2009
by n3ueaEMTP
n3ueaEMTP's Avatar

Humberto & rusirius, Sorry it took so long to respond. I had to put this project on the back burner (the code without the keyboard addition filled the 168 {I just ordered a few 328s}).

As I look over the keyboard.c file, I notice the variable str_buf and buf_pos. The lcd outputs the contents of str_buf so it seems if I write str_buf to the EEPROM that should solve my problem, yes? I will need to increase the maximum size of str_buf for the end user so it is more usable. The current 22 characters isn't enough.

The 328s haven't arrived and I don't have a keyboard available to use (laptop only household here) so when all the parts arrive, I'll play with keyboard.c until I understand it fully before integrating it into my (hopefully) marketable project.

Thanks for all your help thus far.

Chris B. n3ueaEMTP

November 29, 2009
by hevans
(NerdKits Staff)

hevans's Avatar

Hi n3ueaEMTP,

You will definitely want to extend to those buffers. My code used 22 characters because that is the width of the LCD screen, and that is all I needed for the demo.

If I remember my keyboard.c code correctly, the main loop sits in an infinite loop displaying whatever is in str_buf into onto the LCD over and over. You will want to be a little smarter about that if you are writing to the EEPROM as you really only want to write it out once every time a new message is entered. It should not be a very complicated change, but you will need to think about it.

Let us know once you are finished. I can't wait to see your product on the market!

Humberto

Post a Reply

Please log in to post a reply.

Did you know that you can control 120 LEDs with just 17 microcontroller pins? Learn more...