Animated Progress Bar Shows LCD New Tricks

A small LCD screen can be extremely helpful with small microcontroller projects. Not everything needs to communicate to a fancy server using an ESP8266. However, if the simplicity of the character displays irks you, it’s possible to spice them up a little bit with custom characters and create animations, like [Fabien] did with his animated Arduino progress bar. (Google Translate from French)
The project started out simply enough: all [Fabien] needed was a progress bar. It’s easy enough to fill in the “characters” on the 2×16 character LCD screen one-by-one to indicate progress, and the first version of this did exactly that. The second version got a little bit fancier by adding a border around the progress bar and doubling its resolution, but the third version is where knowing the inner machinations of the microcontroller really paid off. Using a custom charset reuse optimization, [Fabien] was able to use 19 custom characters at a time when the display will normally only allow for eight. This was accomplished by placing the custom characters in memory in the correct order, to essentially trick the microcontroller into displaying them.
These types of microcontroller hacks get deep into the inner workings of the microcontroller and help expose some tricks that we can all use to understand their operation on a deeper level. Whether you’re using PWM to get a microcontroller to operate a TV, or creating the ATtiny-est MIDI synth, these tricks are crucial to getting exactly what you want out of a small, inexpensive microcontroller.

41 thoughts on “Animated Progress Bar Shows LCD New Tricks

  1. Essentially you’ve got 8 custom characters. You don’t need all 19 custom chars at the same time. By writing to the lcd custom character graphic memory directly, the placeholder character that’s printed on the display changes accordingly. This is the same how the msx1 home computer games usually worked, like the animated backgrounds in aufwiedersehen monty, intro screen of boulderdash etc. And how animated sprites worked too.

    1. Think of it like bank-switching.
      Your cpu may only have enough address lines to use 4K of rom, but you can bank switch in as many different 4K blocks of rom as you wish.

      The lcd can only display 8 custom chars at a given moment, but you can swap in any number of chars as you wish.

      1. Yup.

        Look at the image of the progress bar – there’s a Left Image, lots of Centre Images and a Right Image.

        But there’s only one Left image being displayed, so you can update that single character as needed. Ditto the right.
        As for the Centre Images, there are three states – Empty, Full and Being Updated.

        So the progress bar here needs a total of 5 character cells to display. Left (dynamic), Centre Empty, Centre Full, Centre (dynamic), Right (dynamic).

    2. It’s a tiled display and the character numbers are just indexes to the memory blocks that have the pixel data.
      There is NO pixel memory for the output display as it is NOT a graphical display.
      8 character index number point to RAM instead of character pixel ROM.

      So you have (16 x 2) 32 bytes of screen tiles.
      If the first character (screen tile) has the value 65 (ASCII for “A”) then at the memory block indexed as the block 65 you would have this binary pattern –

      00000
      00100
      01010
      10001
      11111
      10001
      10001
      10001

      which represents the pixels for “A” and that is refreshed to the screen every frame as the screen itself has no (pixel) memory.

      When you use a tile to index to a custom character RAM location everything works in the same way except that it is RAM and can be changed. Any changes to the custom character RAM are effectively immediate changes to whats displayed.

      Because the screen has no (graphical) pixel memory itself, any *previous* state of a custom character memory is not displayed, only the current state of custom character memory can be displayed.

      Old computers from the 80’s worked in the same way because it saves memory (no real frame buffer) and it is much simpler to implement with less logic.

  2. “This was accomplished by placing the custom characters in memory in the correct order, to essentially trick the microcontroller into displaying them.”

    Pardon me, but i can’t see any “microcontroller trickery” taking place here : the LCD controller and its library accept to display up to 8 custom characters, but let you reconfigure your custom characters between any new frame to display (this tutorial calls it “dynamic creations of custom characters”).

    While it is true that a total 19 different characters will be used for this animation, the author already knows that he won’t need more than 8 character *at the same time* (per frame) to display it, because he (cleverly, indeed) chose a complex animation that only needs 8 custom characters simultaneously for each “image” (which is exactly what the controller permits), using an appropriate method.

    So your conclusion here is quite “over the top” : “These types of microcontroller hacks get deep into the inner workings of the microcontroller and help expose some tricks that we can all use to understand their operation on a deeper level.” ….!
    Once again, we could do with less “inner-deep-hack” sentionnalism, but this inadequate and overblown description is clearly not up to Hackaday standards.

    1. The blog entry author was likely born in the 90s, so anything deeper.level than JSON API is considered “trickery” if not “witchcraft”.

      The HD44780 datasheet was published sometime in the 80s, and anyone who reads it can do the same “new trick”.

      Sensationalism is intrinsic feature of the new HaD , a “trick” (sensu stricto) to obfuscate the vacuity of the article.
      Cluttering the text with “extremely” “fancy” “spice them up” “fancier” “inner machinations” “trick the micro-controller” “deep into the inner workings” and using 4x the word “trick”, does not bring anything and sounds like a poor gimmick of Harry Potter.

      1. ahhh, and drew me in thinking I’d learn something new, instead wasted time on knowledge already had :/
        Though that scroll-bar is pretty slick-lookin’ I give the guy props for artistic-ability.

      2. I was born in the 90s and spent most of my childhood reading the x86 manuals (back when they were shipped for free) and coded my own os. So instead of insulting an entire generation, or even just insulting a proud hobbyist that wants to show off his project, why don’t you keep those comments to yourself? .

        For the record: as much as I like writing a “compiled sprites” generator or a pmode bootstrap loader that fits in 512bytes, , I also love json apis.

        Congrats Fabien!

    2. So… it’s actually “guy uses standard feature on hardware”?

      Not criticising the guy who created it, but that’s not in any way a trick, that’s something anyone who used a character LCD would know how to do. Very, very lame, since this “trick” aspect is what led me to read this. Hackaday, sort yourselves out! You have a very unique audience, and the usual (website) tricks actively annoy most of us.

      I remember hacking up bitmap graphics on a Wyse 60 using the same method, redefined characters. It was before I knew about bit-shifting, so I wrote a routine to multiply powers of 2 with a for loop. Doh! Still, worked. If I’d optimised it properly I’d probably have had Doom running on it by now. Was about the time Doom came out, actually.

  3. Assuming the progress bar “fills” from left to right only, why would you need 8 unique characters to display it?
    ll|mm|mm|mm|rr Lx1+Mx1+Rx1=3
    Ll|mm|mm|mm|rr Lx1+Mx1+Rx1=3
    LL|mm|mm|mm|rr Lx1+Mx1+Rx1=3
    LL|Mm|mm|mm|rr Lx1+Mx2+Rx1=4
    LL|MM|mm|mm|rr Lx1+Mx2+Rx1=4
    LL|MM|Mm|mm|rr Lx1+Mx3+Rx1=5
    LL|MM|MM|mm|rr Lx1+Mx2+Rx1=4
    LL|MM|MM|Mm|rr Lx1+Mx2+Rx1=4
    LL|MM|MM|MM|rr Lx1+Mx1+Rx1=3
    LL|MM|MM|MM|Rr Lx1+Mx1+Rx1=3
    LL|MM|MM|MM|RR Lx1+Mx1+Rx1=3

  4. And as the others I have said before me, it’s a neat trick but it’s not a hack in any way.

    Still, we’re in 2016 and a small TFT colour LCD is almost as cheap if not cheaper than a character display so I don’t understand why people still stick with those.

  5. Yeah A (brilliant) display hack using ‘inner workings’ is something like the ZX80 (look it up, it really is impressive how it was ever conceived). Not something where the programmable characters are, well, programmed and then used as characters…

    1. Adding features to something, even software, is a hack, doing it at no additional cost is an elegant hack. Like turning on the advanced features of an oscilloscope or expanding the features of an LCD beyond what most people assume they are capable of. In a word, innovating.

      Even by the H.A.D. definition finding a method to get more out of the LCD is a hack.

      “We are taking back the term “Hacking” which has been soured in the public mind. Hacking is an art form that uses something in a way in which it was not originally intended. This highly creative activity can be highly technical, simply clever, or both. Hackers bask in the glory of building it instead of buying it, repairing it rather than trashing it, and raiding their junk bins for new projects every time they can steal a few moments away.”

  6. I agree with the other commenters here that it is inaccurate to describe this method as a hack or trick that depends on the specifics of the internals of particular microcontroller hardware, and that it is simply a software solution taking advantage of the fact that fewer than 8 unique custom characters are displayed at any given time, even though there are 19 unique characters total.

    An optimization I would consider adding to this would be to update the progress bar displayed by performing only a few cursor and display data write commands instead of printing the entire progress bar each time, since each command requires the microcontroller to busy-wait takes tens to hundreds of microseconds (unless it’s possible to use a precious timer interrupt instead).

  7. It is actually possible to use all 80×16 pixels (95×17 total if you skip the gaps) at the same time on one of those displays to some extent. I recently made a simple (pseudo?) 3D game display on one of those things for a class project. Maybe I should post the details somewhere. It was probably the shittiest 3D rendering known to mankind, but it was fun that it actually worked.

      1. Just a brief explanation of the principle would do. Please, before you forget and it drifts off your mind, and this topic drifts off into the Sub-Etha Waves.

        Even if you can’t be bothered posting source code, the principle where you can access more than 8 x 8 x 5 pixels at once would be very worth knowing, and certainly interesting. If more is possible than people thought, it could inspire lots of uses, of many different types. What you’re suggesting, if it’s a real method to break the limit, is something I bet 99% of HD44780 users don’t know.

        Even the principle would be great.

        1. What RÖB says below is pretty much it. It’s possible to write all the character generator (custom font) RAM and shift the view window an order of magnitude faster than the LCD’s response time. I found that it produces acceptable results if the duty cycle is around 1/4 for each character.

          Then it’s just a matter of finding a pattern of shifting and writing that produces reasonably stable results. I was hoping to actually synchronize it with the LCD’s internal refresh pattern, but I couldn’t find a way. I just adjusted the timing until it was mostly flicker-free.

          The best pattern I found was something like this:
          0___1___2___3___
          4___5___6___7___
          Where the numbers are indices into the CGRAM and the underscores are spaces.
          Shifted to the right every 3ms or so.

          The result it still kind of unstable, but it is good enough for a hack. Not something I would try to sell, but perfect for impressing a professor =).

      2. I did see someone doing something *like* this a long time ago. The hack is that the micro-controller interface is much faster than the LCD refresh rate. The LCD as in liquid crystal sort of averages many refreshes at a slow rate because of the chemical rate.

        I can’t remember how they synchronized with the refresh rate. It wasn’t a reset because that is too slow. It may have been some knowledge about how the display refresh works so they can synchronize the refresh itself.

        It was a “fun” hack but useless apart from that. There are missing pixels because the LCD is NOT a graphic LCD anyway.

        1. That’s pretty much how I did it. I couldn’t find any good way to synchronize the thing so I just found a pattern of writing and shifting it that didn’t produce too much flickering.

          A “fun” hack is the right way to describe it. Good for making interesting patterns with limited hardware, but not something I would try to make a product out of…

          1. Probably right in that it’s only good for fun, but still a brilliant idea! Yep those old TN or whatever LCDs were pretty glacial compared to modern TFT. Very clever!

            Now I wonder about another trick… the Pokemon Mini is a tiny little console Nintendo released about 15 years ago. Used a similar mono LCD, and took wee little cartridges. A few homebrewers, and Nintendo’s own software for it, managed to get 4 shades of grey (including black and white) out of a mono screen, by also abusing the slow reaction of the crystals. You just show 1 picture for 2 frame periods, then another for 1 period. A pixel in both, shows as black, neither is white, the others, 2 greys.

            I dunno how “frame period” is defined, or if it actually matters with the slow LCD. Perhaps you can tie into the refresh, can’t remember, but perhaps you don’t need to.

            So it would be interesting, with the same trick, to do greyscales in a single character cell. You should be able to do all 4 shades in one.

Leave a Reply to LeibowitzCancel reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.