HD7780 AVR Library - Page 1
Forum section: electronics / general

author: Simon
author_rank: Unknown
timestamp: October 30, 2017, 09:48:14 am
content: I had a look for a library for the HD44780 display on AVR and came acrosshttp://community.atmel.com/projects/hd44780-librarybut if I try and compile having linked the library I get told that -lhd44780.c can't be found even though the file is called hd44780.c and I can't see how to get round it, I'm also struggliung to get AS7 to put the file where the rest of my library files are in the project so I'm a bit confused. Has anyone used this library or are there any others that are properly documented that I can use without having to reverse engineer them first.I could do what I want to do in arduino but I'm trying to do straight C (on the arduino board to save me the hassle of making something).

author: ebclr
author_rank: Super Contributor
timestamp: October 30, 2017, 10:00:23 am
content: How did you declare?

author: Simon
author_rank: Unknown
timestamp: October 30, 2017, 10:01:40 am
content: As described I included the header file and added the C to my project

author: Simon
author_rank: Unknown
timestamp: October 30, 2017, 10:03:17 am
content: Code:#define CPU_F 16000000UL //Processor frequency in Hz, amend as appropriate.#include "atmega328.h"#include "hd44780.h"#include "hd44780_settings.h"int main(void){while(1){//TODO:: Please write your application code}}the "C" file is listed under "solution items"

author: ebclr
author_rank: Super Contributor
timestamp: October 30, 2017, 10:03:43 am
content: You need to do something like that#include "yourlib.h"This will not work#include <yourlib.h>

author: ebclr
author_rank: Super Contributor
timestamp: October 30, 2017, 10:06:02 am
content: Are you using Atmel studio?

author: Simon
author_rank: Unknown
timestamp: October 30, 2017, 10:08:38 am
content: Quote from: ebclr on October 30, 2017, 10:06:02 amyes

author: Simon
author_rank: Unknown
timestamp: October 30, 2017, 10:39:55 am
content: Yes I already had the path setup as i already have a body of custom libraries of my own there. It's this one in particular that is not playing ball and the first time I try to use a library that is not mine.

author: Simon
author_rank: Unknown
timestamp: October 30, 2017, 12:52:32 pm
content: This is just not working, I have tried setting a path for all of my header files and have put the address of these into anything I can find in the toolchain that wants custom locations and still nothing. It's nuts, it feels like one of those things made over complicated for no reason, it's pretty simple really, I have some files in this location that I'd like the program to know about but it ignores them just the same.....

author: newbrain
author_rank: Super Contributor
timestamp: October 30, 2017, 03:18:13 pm
content: Quote from: Simon on October 30, 2017, 09:48:14 amIt would seem that the source file has been added to the project as a library, and the linker is trying to directly link "hd44780.c" to the binary.That's doomed to fail, even if it could find the file in its libraries paths.Remove the file from the project, and add it back again as a regular source file.It will then be compiled to an object and linked as the other source files are.(Maybe clean up the other paths/options that have been modified).HTH

author: technix
author_rank: Super Contributor
timestamp: October 30, 2017, 08:08:38 pm
content: If the library is given to you as source files (instead of a separate library project or target) you should drop them into your project along with other project files. (Personally I create one folder for each source-style library I used.)

author: Simon
author_rank: Unknown
timestamp: October 30, 2017, 09:43:16 pm
content: Yes the thing is that it won't work like that, as i am working from a constant template I decided to do as suggested in the video above and use the master copy as the one location for all my libraries (C and H files) but now nothing works it's a right mess and I'm very unimpressed with atmel studio as frankly i feel I've got it right.

author: technix
author_rank: Super Contributor
timestamp: October 30, 2017, 10:30:27 pm
content: Quote from: Simon on October 30, 2017, 09:43:16 pmThis is likely a Visual Studio problem, not just an Atmel Studio problem.Personally I think this is where the submodule feature in git comes in handy. In the central storage there is one repository for each template and each optional library. Each instance of the template and the libraries are their own set of files in local project folders, yet they are tagged and referenced by version only instead of copied in the central storage. Something like the following:Code:git initgit submodule add git://git.maxcrib.info/cmsis.git cmsisgit submodule add git://git.maxcrib.info/startup-stm32f303.git platformgit submodule add git://git.maxcrib.info/libusb_stm32.git contrib/libusb_stm32After this I get three submodules in my project folder. They can be used as if they are local files.

author: newbrain
author_rank: Super Contributor
timestamp: October 30, 2017, 11:14:56 pm
content: QuoteLet's say it's the way VS works. There is no real problem here with VS, and also Eclipse is very similar.The real issue is that the video shows only how to add include paths, as the "library" the YouTuber was using had to be included as a .c file; why would one want to do that is beyond me, in the general case, but maybe it's an Arduinish thing.If that were the case, everything would have worked.The library Simon is using is provided instead as a set of include (.h) and source (.c) files, as most sane reusable C code is.There are clear usage instructions on the library site.In some cases the library can be pre-compiled (to a .a or .lib file, using a separate project), the includes placed in the common include directory and the library added to the Libs folder, since I see a setting.h file, I would expect this is not an option.What's impossible to do is linking a .c as a compiled library: probably something has been messed up in the various attempts made, hence my suggestion to start over.

author: technix
author_rank: Super Contributor
timestamp: October 31, 2017, 04:03:40 am
content: Quote from: newbrain on October 30, 2017, 11:14:56 pmEclipse will pick up files dropped into project folder directly with a quick refresh in the project explorer. Way too often I just create the project and dropping in a few submodules before start coding.

author: Simon
author_rank: Unknown
timestamp: October 31, 2017, 12:45:51 pm
content: Quote from: newbrain on October 30, 2017, 11:14:56 pmI tried putting the files in the same location as the rest of my libraries and including them as i normally do but AS7 would not play ball. So after the advice here i setup a path to a seperate libraries folder and now my existing .h files cannot be found, I don't think there is anything wrong with the library, it looks more like AS7 does not want to work. I have told the program where to find libraries, I have tried <file.h> and "file.h" but neither work.

author: Simon
author_rank: Unknown
timestamp: October 31, 2017, 09:40:13 pm
content: Can anyone recommend another free AVR IDE, Atmel studio seems over complicated with 0 documentation, in brief i have had enough, i used it stupidly and it worked, now i try to use it intelligently and it won't work, clear conclusion, stupid program......

author: mikerj
author_rank: Super Contributor
timestamp: October 31, 2017, 10:24:19 pm
content: Quote from: Simon on October 30, 2017, 09:43:16 pmThe point you are missing is that you don't have a library file, yet you are telling the linker to include it as a library file. This is neither an Atmel or a Visual Studio problem.A library file is an object file, it's pre-compiled code in a handy single file that the linker can use. You have source code, so you have to add it to your project as such.

author: Simon
author_rank: Unknown
timestamp: October 31, 2017, 10:30:49 pm
content: right so when i doCode:#include <header.h>orCode:#include "header.h"what am I doing? and where are these files supposed to be and how i i tell it a fixed location of my choice? why can't hd44780.c be found when ir has been added ? or atmega328.h be found when it is included ?

author: alank2
author_rank: Super Contributor
timestamp: November 01, 2017, 03:36:03 am
content: This is actually my library from a few years ago.In AVR Studio 7 just right click the project name (below the solution, above Dependencies in the Solution Explorer) and choose Add -> Existing (Shift-Alt-A) and add hd44780.c to the project. It will then show up as one of the .c filenames along probably main.c and any others you have. You can use it by #include "hd4780.h" in any C files that you want to be able to call functions to it from. Make sure you copy hd44780_settings_example.h --> hd44780_settings.h and alter its settings for the ports/pins/configuration you need.You don't need to #include the hd44780_settings.h, the #include "hd44780.h" will do it for you.It is a "library" in that it a code to do a particular task, in this case control an hd44780 type display. It is not compiled into a .lib or anything like that. hd44780.c is the source code and would need to be added to your project like other source code would be.

author: Simon
author_rank: Unknown
timestamp: November 01, 2017, 06:55:55 am
content: Ok, well congratulations on the documentation, many don't bother. This has turned into a problem of how do I manage all of my reusable code without copying it into each new project. Added to the fact I use 2 computers and Dropbox but the paths are identical anyway.

author: Simon
author_rank: Unknown
timestamp: November 01, 2017, 07:46:56 am
content: Yes and if I "add existing" it still can't find it! this is stupid, and IDE is supposed to make life easier, this is just being so complicated it defeats the object....

author: Simon
author_rank: Unknown
timestamp: November 01, 2017, 07:48:53 am
content: ok working now.....

author: newbrain
author_rank: Super Contributor
timestamp: November 01, 2017, 09:19:58 am
content: Glad to hear it's working.Complex IDEs are...well, complex.Especially if one is coming from the Arduino not-really-an-IDE toy (but it has its merits, for a complete beginner), there's some learning curve.I'm at ease with VS (and derived, as Atmel Studio), and even know a good number of Open Source advocates that like it over other alternatives: it's a very powerful tool, well organized and helpful, while I find all Eclipse derived stuff confusing.That said, IDEs are a very personal choice.If one wants a lighter, simpler but at the same time powerful enough alternative, setting up VS Code (or Sublime Text or Atom, though I never tried these two) for your specific development is not overly complicated.

author: Simon
author_rank: Unknown
timestamp: November 01, 2017, 09:22:33 am
content: well I've used it for some time but I've kept everything in the project folder which means it just works but then I am constantly copying stuff.

author: technix
author_rank: Super Contributor
timestamp: November 01, 2017, 10:17:21 am
content: Quote from: Simon on November 01, 2017, 09:22:33 amThis is why I prefer git submodules. Project folder does contain copies of dependencies for the sake of the complex IDEs and source distributions, but in the source control everything appears only once.

author: alank2
author_rank: Super Contributor
timestamp: November 01, 2017, 12:02:56 pm
content: Quote from: Simon on November 01, 2017, 07:46:56 amI hated AS7 when I first started using it. Then I used Atollic TrueStudio and that takes confusing and non-intuitive to a whole new level.Glad you got it working!

author: Simon
author_rank: Unknown
timestamp: November 09, 2017, 08:46:37 am
content: OK so I have the library working (well no more compilation errors involving it or my own headers and C files). I am writing my program but I don't see a way of putting a variable on the screen. Is there a way to do this? what I am trying to do is measure a sensor and then after some simple calculations that extract a meaningful number put that number on screen. I don't see this described in the instruction text, only how to "put character"

author: mikerj
author_rank: Super Contributor
timestamp: November 09, 2017, 09:04:34 am
content: Quote from: Simon on November 09, 2017, 08:46:37 amQuite simply you use a function such as ftoa() or itoa() to convert a number to a string, and then print the string. If you want to do fancy string formatting then use sprintf(), though be aware of the code size and run time overheads.The other option is to add some optimised LCD print functions into your library to deal with numbers.

author: Simon
author_rank: Unknown
timestamp: November 09, 2017, 09:14:26 am
content: I see, what are the functions atof() and atoi() part of ? are they part of the GCC for AVR libraries ?I'm also getting this error: character constant too long for its typefor: lcd_putc('Flow too LOW');so I guess that was meant for one character at a time. that will be painful for one character at a time but doable

author: Simon
author_rank: Unknown
timestamp: November 09, 2017, 09:21:04 am
content: atof() and atoi() seem to do the opposite, convert text to number format variables. I'll have a dig around

author: ebclr
author_rank: Super Contributor
timestamp: November 09, 2017, 10:55:34 am
content: http://efundies.com/avr-and-printf/

author: Simon
author_rank: Unknown
timestamp: November 09, 2017, 11:29:25 am
content: ok but how does printf() help with another function that does not know of it's existence? (My knowledge of C is limited), I'm going on the help file that tells me how to use the LCD library, if it's is not written to cope with my situation how do I get it to work with printf()

author: mikerj
author_rank: Super Contributor
timestamp: November 09, 2017, 11:48:33 am
content: Quote from: Simon on November 09, 2017, 09:21:04 amftoa() and itoa(). You must have read my post just after I submitted it as I accidentally put the wrong functions in and then edited it.printf() calls a function putch() to output a character. The default behaviour of putch() varies, but it can be overridden by defining your own version of putch(). This allows you to use printf to write to any character based device, but again you must be aware of the memory and runtime overhead of printf (and sprintf) which can be very significant on a small 8 bit micro, especially when working with floating point values.

author: Simon
author_rank: Unknown
timestamp: November 09, 2017, 12:18:38 pm
content: Ah I see, I tried googling the variable to charachter but drew a blank, now have named those functiontions information is plentiful.I have had a look through the source files for the library and think i have found a put string function that should do the trick and avoid me having to call putc many many times:Code:/*************************************************************************Display stringInput: string to be displayedReturns: none*************************************************************************/void lcd_puts(const char *s){register char c;while ((c=*s++))lcd_putc(c);}

author: ebclr
author_rank: Super Contributor
timestamp: November 09, 2017, 12:19:07 pm
content: You need to waste some time to learn

author: Simon
author_rank: Unknown
timestamp: November 09, 2017, 12:21:54 pm
content: indeed which is one reason for doing this project in C instead of Arduino, I need to make something and don't quite know how to do it but it's an excuse to learn.puts is not working as hoped.

author: alank2
author_rank: Super Contributor
timestamp: November 09, 2017, 01:03:41 pm
content: There are three functions (take a look in the H file):void lcd_putc(char c);void lcd_puts(const char *s);void lcd_puts_P(const char *progmem_s);lcd_putc is designed to put one character - lcd_putc('A');lcd_puts is designed to put a null terminated string in sram to the display lcd_puts("Hello"); or lcd_puts(s1); where s1 is defined as char s1; or similar.lcd_puts_P is designed to put a null terminated string in flash to the display:#include "avr/pgmspace.h"const char MsgPounds [] PROGMEM = "Pounds";lcd_puts_P(MsgPounds);In the case of lcd_puts, you have to render the string first using a function like sprintf. I typically create a global string like char s1; or something and use it like this:sprintf(s1,"%d",i1); //i1 is an integerlcd_puts(s1);You have to understand that the "%d" string above (3 bytes) is wasting your sram as well. That is why there is a sprintf_P function that allows you to replace the "%d" with a flash PROGMEM string:const char MsgPercentUMinutes [] PROGMEM = "%u Minutes";sprintf_P(s1,MsgPercentUMinutes,15+currentsetting*15);lcd_puts(s1);Now the "%u Minutes" is in flash (taking no sram up), s1 is in sram and is reusable across many functions, and lcd_puts will put the results of s1 to the display.Good luck!

author: Simon
author_rank: Unknown
timestamp: November 09, 2017, 01:07:04 pm
content: aha, wrong type of quote marks.....

author: alank2
author_rank: Super Contributor
timestamp: November 09, 2017, 01:11:57 pm
content: Single quotes are for a character (or byte):lcd_putc(65);lcd_putc('A'); //same thingDouble quotes create a null terminated string:lcd_puts("Hello");becomes H e l l o <0> in memory, 5 bytes for each letter and 1 byte for the null terminator. What is sent to the function is not the 6 bytes, but a pointer to the 6 bytes which is why it is defined as having a char* type argument. The * means pointer. char argument = single character, char* argument = pointer to one or more characters.

author: technix
author_rank: Super Contributor
timestamp: November 09, 2017, 01:21:39 pm
content: Quote from: mikerj on November 09, 2017, 11:48:33 amDepending on libc implementation, putch() may call something else further down the line. The version of newlib included in ARM's distribution of GCC chains the calls eventually to _write(). For my STM32 HD44780 driver library I just implemented _write (in fact I have the file handle mechanism and the call dispatcher in place, but still the same story) and calls to fprintf() or write() can go straight to the LCD.

author: Simon
author_rank: Unknown
timestamp: November 09, 2017, 04:35:58 pm
content: well AS seems to quite like sprintf(s1,"%d",i1);

author: alank2
author_rank: Super Contributor
timestamp: November 09, 2017, 04:39:37 pm
content: Quote from: Simon on November 09, 2017, 04:35:58 pmIt will, but consider that "%d" is burning 3 bytes of sram AND flash when it really only needed to use 3 bytes of flash. That is what the PROGMEM and _P version of the function allow. Not a big deal for 3 bytes, but get an entire project full of constant strings and it becomes a big deal very quickly.

author: technix
author_rank: Super Contributor
timestamp: November 09, 2017, 06:29:18 pm
content: Quote from: alank2 on November 09, 2017, 04:39:37 pmA clever linker can squash all identical constant strings into one instance. Although if your code contains a lot of different strings you still run out of resources fast.

author: apurvdate
author_rank: Contributor
timestamp: November 10, 2017, 12:12:40 pm
content: There used to be a "Watch" or "Quick Watch" functionality in AS6. When in debug mode you can see value in watch window. Its a no go if u want real time value display though..I hope its there in AS7 also. FYI I haven't used AS for 2 years...edit: posted reply n then understood your query.. silly me

author: Siwastaja
author_rank: Super Contributor
timestamp: November 11, 2017, 11:47:40 am
content: HD44780 is a prime example of technology which is implemented so simply and in "directly usable" way that, usually, it takes a lot more time to find a library, find out how it works, assess whether it's usable at all (libraries often tend to be completely broken by design), and then, finally, be able to do something with it - than what it takes just to directly write your code - call it a library if you want, but it's usually just a few lines.This is not surprising: HD44780 is an old school "bus" device thatdirectlyaccepts data and just does what you tell it to do, so kinda plug&play. At that time, it wasn't common to think in the modern stupid "hardware abstraction middleware driver blah blah" way. With today's complexity often requiring that, we have forgotten it doesn't always need to be that way.As a semi-noob, when I first time interfaced with HD44780 in 2005, I spent only one (1) HOUR to actually writeeverythingmyself. This is because HD44780 interfacing is about 10 to 20 lines of code, all extremely trivial and well documented. I found this a lot easier than basic MCU things like intializing an AVR timer/counter to produce PWM, which took several hours the first time to get right.