NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Microcontroller Programming » Writing the C code for another LCD, the EADOGM
January 27, 2010 by Frozenlock |
Those are cheap and easy to connect little LCD screen. The only drawback so far is the almost inexistent C coding for it. So I took a huge mug of coffee and tried... for 2 days. Whatever I do, I can't make anything appear on the screen! (Except when I cut the power, then I sometimes see a line in the screen for a second, before returning blank as before.) I can't use the code included in the Nerdkit, because I use SPI. Here is the code I gathered on the net and re-wrote as needed. If someone see a mistake, pleeeeeeeeease, say it! :P 1st part: the includes, variables and macros:
Now the first function. It takes any of the defined Hex number and send it through the SPI wire, with the "clock" sending the necessary up-down each time.
Now the LCD_ini. Depending on how the LCD is wired, the initiation might be different. Datasheet (PDF) This is where I screw up, I think...
A little reset function
And finally the main:
My LCD is wired as the "wide range" shows in the datasheet. |
---|---|
January 27, 2010 by Frozenlock |
Oh and my MCU is powered with 5v, so it means my outputs also are... Can this be a problem for the 3.3v powered LCD? Thanks ;-) Frozenlock |
January 28, 2010 by Frozenlock |
Good news! After some tinkering in the C code I am now able to see the entire screen as "black". At least now I know my LCD is working, as well as my initialization. Next step: writing something on the screen. |
January 29, 2010 by Frozenlock |
Update: I'm now able to send anything I want to the screen, weeeeeeee! (Pixel by pixel) I have some problem with a part of my code though.. I would like to be able to find the size of a string. Here's the code:
It seems that no matter what I write in the string, I always obtain the condition for the letter 'A'. Any ideas why? |
January 29, 2010 by N3Roaster |
The sizeof operator is used to find the size of a type or structure. As you've noticed, it cannot be used to determine the bounds of an array as the size of a pointer is always the same (char input[] is just another way of writing char *input). Furthermore, there is nothing in a C style string that says how long the string is. A C style string is, however, terminated with a null character so it is possible to know when you've hit the end of the string. The standard library has a strlen() function which can be called to obtain the length of such a string. If you always know the length of the string when you call this function (that is, you're hard coding them rather than getting them from some external source), another option is to modify your function to take a second parameter with the length of the string. That saves you the overhead of the function call or looking for the null terminator yourself. |
January 29, 2010 by mrobbins (NerdKits Staff) |
Hi Frozenlock, N3Roaster is definitely pointing you in the right direction. In fact, the way the "sizeof" operator works is quite strange in C for arrays -- teachable moment! Let me show you this quick program snippet you can try:
And, saving that as test.c and running, here are the results
Notice that in both cases (the first being in the same function where the array is allocated, and the second being in another function), strlen provides the 6 that we may be looking for. But the results of sizeof are very different. In the first case, we get 10. That's because the compiler knows that the array b[] was defined to have length 10 in that same function -- so the compiler is really just replacing sizeof(b) with 10 at compile time. However, when doing the same thing in the called test_param_array function, the function could have theoretically been called with any length character array. Here, the close relationship in C between arrays and pointers comes out, and (on my 32-bit machine) I get sizeof(x) = 4, where 4 bytes is the size of a pointer! If you were to try the same code on the microcontroller, I'm fairly sure you'd see sizeof(x) = 2, because it uses 16-bit pointers. Summary of how to fix this: depending on exactly what you're trying to do, you need to use strlen, or pass around the length of the array as a separate parameter. Hope that helps -- let us know if this is confusing. Post pics of the LCD working! Mike |
January 29, 2010 by Frozenlock |
Well, as I said, if I want to show something on the LCD, I need to write it pixel by pixel. I want to make some kind of database with all the preconfigured letter. I.E.: The letter "A" can be shown by sending 0x00,0x7E,0x09,0x09,0x7E. I had in mind something like this: Function string_to_lcd("blablablabla") Scan the string for the number of different letter. (12 in this case) For each letter, search the ascii code in the database and print it to the LCD. I tried with the strlen, but it only seems to work when the string is DIRECTLY in the function. number=strlen("abcd"); return the right answer, but char x = "abcd"; number=strlen(x); doesn't. I'll keep you informed. |
January 29, 2010 by N3Roaster |
First make sure that you're really passing in a pointer to your character array. The
Now, you know that if you pass that to a function with a prototype something like
you don't know how long that string is going to be from within that function, but you do know that it should have that null character in its last position. That means that you can do something along the lines of:
At the end of the loop, |
January 31, 2010 by Frozenlock |
Brilliant! I understand now why Mike told you were showing me the right direction. I must say that all this "pointer" thing confuses me somehow. I read some texts on the subject, but it still feels unnatural... This is what I've added to your lines:
(character being an array with every ASCII symbol) Well, this is what I intend to add. Of course, I hit a wall again. If I write
everything works flawlessly and I get the character on my LCD. But if I try to make it into a for loop,
then I have a big black line on my LCD, as if I was sending an unending "1" stream. Again, I'll keep you informed on my progress. Thanks! Frozenlock |
January 31, 2010 by Frozenlock |
Ok, I am about to throw everything by the window... I've been working on this for days now and I always hit something that's supposed to work, but in C, it just doesn't. If I write
My LCD shows an "A" When I try to put this into another function, all hell breaks loose!! So I have my main with the function:
And here is the function:
Why? Whyyyyy? Is it not the SAME EXACT THING? I must have tried every single possible combination(with [], with "", with '', with (), with *, with int, with char....) but it just never works!! |
January 31, 2010 by pbfy0 |
I don't know what the -32 is doing, because that would subtract from the character and make space null. I'd just do it like this.
you'd need to give it a string in |
February 01, 2010 by N3Roaster |
The -32 is probably just there to exploit the fact that the first 32 characters in ASCII encoding aren't printing characters, thus the character array doesn't need to waste entries on them. The bytes to send for the character 'a' would therefore be in row 65 of the table. The space wouldn't be null, it would be array index 0. (This is why I've never liked the convention of using the same symbol for 0, the null character, and the null pointer. They're very different semantically.) Assuming there's 8 bytes in the table for each of the remaining 94 printing characters, the entire character array should use 752 bytes of space. If that's all going into SRAM, that only leaves you with 272 bytes for everything else. That may or may not be problematic. I'd be interested in more details regarding
|
February 01, 2010 by mrobbins (NerdKits Staff) |
Hi Frozenlock, Is it also possible that you are running into the issue where static strings in your C code (that are not defined as being in program memory) might not get copied into the compiled program? See this post from an earlier discussion where wayward explains how you can change your Makefile to include the data and bss sections of the compiled program. Mike |
February 01, 2010 by Frozenlock |
Hello pbfy0, N3Roaster is right, the "-32" is because I only have the writable ascii character in my array. I didn't though about the limited memory, I will check that! I think the characters for the NerdKit's LCD are already in an IC within the LCD, which would explain why it doesn't eat up as much space. A possible solution to use less memory might be to use only capital letters and the 10 numbers. I'll check if it is needed soon. For now, I'll post some long overdue pictures. First, the LCD: Second, what the LCD shows when I put everything in the main, like this:
To write "NerdKits!", I had to go as far as i=9. And this is what happens when I try to move it into another function, you know, my "all Hell breaks loose!!" For those wondering, the diodes in the + column is to lower the voltage from 5V to around 3.3V. I haven't try it on the 5V yet. I will try everything you've posted here. Thank you all!! Frozenlock |
February 01, 2010 by Rick_S |
Another thing you might look into is placing your array into the eeprom and only reading out what you need to print what you want. That way it won't eat up flash space and the only ram used will be for what is being currently displayed.... Just a thought, Rick |
February 02, 2010 by Frozenlock |
It works! I've done what pbfy0 suggested, and it worked! I've also transferred the character array in the progmem, so now it looks like that:
I had to apply some minor changes to pbfy0's code in order to be able to retrieve the needed data in the array:
Thank you very much to all of you! I would never have been able to find this on my own! Frozenlock |
February 03, 2010 by Frozenlock |
I have another question... If I want to write numbers, how can I transfer them into a string and then into the PSRT()? |
February 03, 2010 by Frozenlock |
Hello there! Now that my code is working, I'm able to do pretty much anything quite easily. I can even DRAW anything I want, as long as it's 132 by 32 pixels. I use bmp2h_conv V6 to convert the bmp into an array filled with hex numbers. Here is a little demonstration:
I have also successfully removed the diodes (3.3V) and... well... replaced it with nothing. Apparently, the LCD is able to take it's power from somewhere else, on 5V! Yay! Also removed 3 capacitances without noticeable effects. I still need some help to understand how to write numbers though. Example:
I want the LCD to show this 32. How? |
February 04, 2010 by Frozenlock |
I tried the function snprintf, but it seems flawed... Here is my code:
It works if I directly put a number into the char, for example: char string_num = "123" But oddly, it doesn't work when I use snprintf to convert an interger to a string. Worse, the LCD ALWAYS show the same 10 characters regardless of the array's size or the number. A little hint, please! Frozenlock |
February 04, 2010 by bretm |
I don't have a lot of experience with this, but I'd guess you're running into the same problem with strings being in RAM instead of program memory and not getting copied to the chip because they're in the .data segment instead of the .text segment. Your formatting string "%i" should probably be PSTR("%i"), and sprintf should probably be sprintf_P. Another way to do it is to figure out the characters yourself, one digit at a time:
|
February 05, 2010 by Frozenlock |
PSTR("%i") worked like a charm, thanks a lot! |
February 11, 2010 by Frozenlock |
Me again, with yet another problem! Whatever I do, I'm unable to make my LCD show numbers bigger than 1024. Being a power of 2, my guess is that the source of the problem is somewhere in my variable definition, but I've failed to pinpoint the location. |
February 11, 2010 by Frozenlock |
My apologies, it was an hardware problem. |
March 24, 2010 by Phrank916 |
Frozenlock: Is there any chance you might have created an LCD.h file for this display yet? I've decided to use one of these displays for a future project: making a "bike computer". I think a graphical display like this would be best because I could have the large numbers for the current speed and then some smaller numbers showing other stats like distance traveled and time, etc. I've decided on the bright white one from Mouser which doesn't require a backlight, since I'll really only be using it in the daytime. So, if you don't have a drop-and-go file yet, could you share some code and maybe I could work on it? Unless it's pretty much all in the thread above. I don't have the LCD yet so I haven't really studied the code above. Although, when I do get the display, I'm very interested in NOT reinventing the wheel! heheh ;) Ted |
March 24, 2010 by Phrank916 |
Oops that was the wrong part number, this is the one I want |
March 24, 2010 by Frozenlock |
Sure, here is the code I use: EA dogm code Be sure to include the dogini2.c in your main. (#include "dogini2.c" ) You might want to search a little further. I once saw some code for the bigger LCDs which wasn't working with mine. Perhaps they would with yours... Anyhow, the most important step is the initialization and the contrast settings. If something is wrong in those, you will have no way of knowing if your LCD is working. Also, don't forget to set it up with the proper pixel number. In your main, if you want to write a string, use the command
If you want to write a number
Don't hesitate to ask if you have any other question. By the way, is there a way to upload to this forum? |
Please log in to post a reply.
Did you know that you can turn a $20 digital scale into a live weight sensor using our kit with a few extra parts? Learn more...
|