Announcing Clerk, a hardware agnostic HD44780 LCD library

Hi at all,

I’m currently working on a small library to control HD44780 compliant displays. Because it is my first ‘real’ project written in Rust it would be nice if someone could have a look and telling me if I’m doing something terrible wrong :D. I also would like to invite anyone to come up with suggestions for design changes or features before I will stabilize and publish on

Things that aren’t finished yet:

  • Error handling
  • Examples in documentation
  • Some more advanced features of HD44780
  • Testing

And here it goes:


I am currently evaluating possible solutions for setting the cursor address. The problem is that there are many LCDs types with various display sizes. So my idea was to provide an out of the box solution for the most common ones, but also to give the library user a chance to specify a custom addressing scheme.

The actual state is something like this:

Maybe someone has a better idea or any hints.

Now also at Feedback is very welcome.

Nice going! More hardware support is always good!
I had a look at the playground, and I like how your ToAddress Trait allows for overriding the addressing. Good call!

I also like how you separate the line from the offset.

You may want to consider switching to “AsAddress” or “IntoAdress” instead. This post by Ricardo Martins gives a nice overview of the common conversions in Rust, and the implead semantics of each of From, Into, To, As, AsRef, etc.

I’m not too sure about the line enum though. I know there any displays out there with more lines. Or do those use a different, non-compatible API?
No wait, I see now that that’s just for this display, because you implement ToAddress, nice!

Finally, this is probably very embedded-centric. You may want to let the people in the embedded thread know about this, and add this to the list of embedded-relevant crates :slight_smile:

@juleskers Thank you very much for your feedback and the interesting link to the post by Ricardo Martins. I think I will switch some conversions to use From instead of custom traits now. Yesterday I implemented a workaround for the SeekFrom enum, because the way it was implemented it needed additional type annotation for Home and Current. But today I tried again and with some help from the super nice #rust-beginners channel I found a solution to go back to the enum with the additional feature of binding the addressing scheme to a specific instance of the Display. With the type bound to the display Rust will prevent the usage of the wrong addressing when using different display types. Here is the gist.

1 Like

Glad to be of service! :slight_smile:
I think your Display trait has become much more generic with Into<u8> :slight_smile:

The IRC group is indeed a good bunch!

1 Like

Currently I’m working on features for different hardware configurations (4 pin, 8 pin, write only, read, …). For the read only mode I need a couple of delays and while I want the lib to work without stdlib, I can not use sleep here. Now I’m searching for a good and flexible way to let the library user specify the delay implementation.

In my HD44780 library I require clients to implement Delay trait with delay_us function. Just an idea.

Thank you, but during my research about the different displays on the market I found out that some of them have other timing constraints than specified in the original hd44780 spec. Maybe a combination of delay_us and the new trait constants are worth a try.

I am currently working on a small How-to that shows how to connect a HD44780 LCD to a RaspberryPi and how to cross compile and access it via clerk.

Maybe someone does have a good schematic drawing or would like to contribute one that shows how to connect a display to the PI (B+)?

I would also appreciate some spell and grammar checking, because English is not my first language.

1 Like

I started something like that last year:

I didn’t have time to actually test on it a hardware, but I made a simulator to test examples on a computer:

The overall design look quite similar, but I would bet your version is better tested…

1 Like

Thank you very much for sharing this. Tests are a thing I am currently working on. Another idea is to encode the current access state (e.g. DDRAM vs. CGRAM) into the type system, so that accidental reads/write of or into the wrong memory register are caught at compile time. I have the same idea for the pins in mind, but haven’t found a good solution so far.

1 Like

Just released v0.4.0 of clerk.

New feature and fixes are:

  • 8 bit (data-lines) mode (but not tested with hardware, yet)
  • each Pin can now have it’s own type
  • additional high-level communication traits for sending, receiving data
    with them it should be possible to use other connection methods (protocols) like I²C for example
  • internal type Address with ‘software overflow’ to simulate the behaviour of the real address counter when in write only mode
  • configuration for start display data RAM address and timing

I’m currently moving the implementation for accessing the different RAM types (DDRAM, CGRAM) into the type system. This will prevent wrong/accidentally operations on the (wrong) RAM type.

Here is a proposal on how the interface to CGRAM could look like, for those who are interested:

Additions are highly welcome.