Sharp Display Driver 8×8

This is a compact display driver for the LS013B4DN04 display from Sharp. It is text based and writes 8×8 pixel characters on the screen, which allows 12×12 characters.

There is a library with automatic refresh using timer 2 here:

Sharp Display Driver 8×8 Timer 2

DEMO

This demo is an example of the Arduino library.

Requirements

  • Library for Arduino IDE 1.6 or newer
  • Assuming a ATmega328P microcontroller running at 16MHz
    You can use it with other microcontroller, but probably have to adjust the timing manually.

Usage

After creating a global instance of the driver class and pass the used pins for the SPI communication to the driver, you have to initialise the driver with begin() and setFont().

This minimal example is showing all required steps. You find the complete example, including the font, in the example folder of the library.

// Include the header file of the driver.
#include <LRSharpDisplay.h>

// Include the header file of the font.
#include "Fonts.h"

// Create a global instance of the display driver.
//
// Add the chip select, clock and data pins which are connected to the
// display as arguments to the constructor in this order. In this
// example, we use pin 11 for chip select, pin 9 for the clock and
// pin 10 for the data in.
//
lr::SharpDisplay sharpDisplay(11, 9, 10);

void setup() {
  // In the setup method, you have to call begin() to initialize the
  // library and setup communication.
  sharpDisplay.begin();

  // A font is required, you can use the example font for your own
  // project. Just add the "Fonts.h" and "Fonts.cpp" to your project.
  sharpDisplay.setFont(Fonts::a);

  // The display is automatically cleared at the start, so you can
  // start writing text to the display:
  sharpDisplay.writeText(F("Hello World!"));

  // The text is _not_ visible at this point, you have to call
  // refresh() to make the current text buffer visible on the display.

  // Make the text visible on the display.
  sharpDisplay.refresh();
}

void loop() {
  // You must call the refresh method at least once per second to
  // keep a latent charge from building up within the Liquid Crystal cells.
  sharpDisplay.refresh();
  delay(500);
}

Method Documentation

SharpDisplay(uint8_t chipSelectPin, uint8_t clockPin, uint8_t dataPin)

The constructor. Specify the pins for the SPI communication with the display.

void begin()

This method initialises the display. Call this as first method in your setup() method. It will setup the communication and clear the display.

void setFont(const uint8_t *fontData)

This method sets the current used font for the display. You have to set an initial font before you can use the display driver. It is possible to call this method later again to change the font.

uint8_t getScreenWidth()

Use this method to get the screen width in characters.

uint8_t getScreenHeight()

Use this method to get the screen height in characters.

void clear()

This method clears the display. It will also clear the text buffer and fill the buffer with space (0x20) and sets the cursor at position 0, 0.

void refresh()

Refresh the display. This will make the current text buffer visible on the display. You have to call this method after each modification of the screen to make this modification visible.

You can call the refresh method as often you like, it only depends how fast you like to display the changes on the screen.

void setTextInverse(bool enable)

Enable/Disable inverse future text. If you enable inverse text, any subsequent call of text writing methods will write inverse text or characters.

void setCharacter(uint8_t row, uint8_t column, uint8_t character)

This will set a single character on the screen at the specified location.

char getCharacter(uint8_t row, uint8_t column)

Get the character at the specified location.

void setLineText(uint8_t row, const String &text)

This will replace a line on the screen with the given text. If the text is longer than the screen it will cut off and if the text is smaller than the screen, the rest of the line is filled with space characters.

void setLineInverted(uint8_t row, bool inverted)

This will make a line inverse or not inverse. E.g. you can use this method for the selected item in a menu.

void setCursorPosition(uint8_t row, uint8_t column)

This sets the position of the virtual cursor. It will change the location where the writeCharacter() and writeText() methods will start writing text.

void getCursorPosition(uint8_t &row, uint8_t &column)

Use this method to get the location of the virtual cursor.

void writeCharacter(uint8_t c)

This writes a single character on the screen at the current cursor position. You can also send a newline character ‘\n’ to start a new line.

void writeText(const String &text)

This writes test on the screen at the current cursor position. You can use the newline ‘\n’ character to begin a new line. If the text reaches the bottom of the screen, the contents of the screen is scrolled up to make space for the new text.

void scrollScreen(ScrollDirection direction)

You can use this method to scroll the contents of the screen into all four directions.

Important Notes

Important: You must call the refresh() method at least once per second to keep a latent charge from building up within the Liquid Crystal cells.

You can turn the display completely off by setting the DISP pin on the display to low. In this case the refresh is not required anymore.

Important: When displaying static images, Sharp recommends refreshing the image data every two hours to prevent stuck pixels.

Font Format

The font is a simple array of bytes. There are eight bytes per character, each byte is a row in the character from top to down. Each 0-bit in the byte is a black pixel, the font have to be inverted.

Use the Font to Byte application to convert bitmaps into byte arrays for this display driver.

The font can cover 128 characters maximum, but you can provide a shorter font with e.g. only 64 characters without problems.

Download

Download the driver using the following link. Extract the directory and move it into the “library” directory.

Lucky Resistor’s Sharp Display 8×8 Library

Visit the GITHub page for older versions.

29 thoughts on “Sharp Display Driver 8×8”

  1. Hi,
    Thanks for this low ram based approach to displaying text!
    I was wondering if it is possible to get it to run on the bigger 400×240 pixel screen of the 2.7inch Display as well?

    Best regards,

    John

    1. I checked the code of the display driver and it should be quite simple to adjust it for the larger display. In the file LRSharpDisplay8x8.cpp there are two constants: gScreenHeight and gScreenWidth. For your display you have to set the width to 50 and the height to 30. That should be all. I couldn’t test it of course, but the code I wrote seems to build everything from these two variables, so theoretically it should work.

    2. If you extend the screen size, to 50×30, the driver requires ~1.5kB RAM for the screen contents plus the ~1kB for the font data. This is too much for an ATmega328P.

      1. Thank you very much for your fast response!
        I gave the code a try on the Mega 2560 and it works perfectly! Exactly like I need it for my project. Well, except that it requires two much RAM for the 328P. However, I do think there is a solution to that.
        The font is quit small (8×8 on 250px of vertical resolution). I will have a look into reducing the ammount of characters to be displayed to for example 25×15 and then, in the same turn, increasing the character size to maybe 16×16.
        Not sure if that is possible, however I will try it out!
        I will report back here on the weekend once I succeeded! 🙂

      2. Scaling a 8×8 Pixel Font
        Scaling the font by x2 shouldn’t be a huge problem. First you need to update the refreshDisplay and refreshFullDisplay methods. Each pixel row is addressed with the first byte sent to the display. Here you need to put another loop around the code to write two physical rows for each row. Second you have to copy the method sendByteMSB and rename it into sendByteMSBx2 and make sure each bit is sent twice. This is actually everything necessary to scale the 8×8 font up.

        16×16 Pixel Font
        Using a 16×16 pixel font should be feasible too, but consider the size of the font. You need 32 bytes per character and you will probably need at least 64 characters for the display which will require 2kbyte of flash memory.
        For this solution you adjust the gCharacterHeight value to 16 and update the refreshDisplay and refreshFullDisplay methods. Here you have to adjust the multiplier to get the right start of the character: characterStart *= (gCharacterHeight * 2). And you have to duplicate the following lines to calculate the mask and send two bytes of the font data. Best work with a 16bit value here.
        You see the changes in the driver code are quite simple to get a bigger font. One of the most important things for this Sharp Memory displays is this VCOM signal which has to be toggled as regular as possible. The display board from Adafruit did only allow handling this signal from software, it was the main reason to write the timer 2 based version of the driver which I would strongly recommend. See the page here. This library has also a method to install a own callback using the setInterruptCallback method, to get a own function called for each screen refresh which is quite handy. If you design the hardware by yourself, maybe the most failsafe solution would be to handle the VCOM input using an output on the microcontroller controlled by a timer.
        Happy working! 🙂

  2. Hello,

    Is there a way to rotate the text by 90 deg ( clockwise/counterclockwise). I want to display something like this ( on the 2.7 inch display) http://i.imgur.com/de1UYYV.png (ignore the red/green boxes ) .
    Also can the library display the ° degree sign? or am i missing something.

    Best regards, Ivan

    P.S Your site helped me a lot and is very well made, sorry if you already got the comment

    1. Hi Ivan, it is not a big problem to rotate the text, but it requires some fundamental changes in the code. First, you just can rotate the characters in the character bitmap. You can use my example file here (link) and rotate all characters by 90º. Here you can also add the degree symbol to the character set. Then use my Font to Byte application (for Mac) to convert the font into data for the driver. Now you can either write own write methods which draw the text in the correct way to the screen using the setCharacter() methods – or you can modify the driver and rotate the coordinate system.

      If you really want to rotate the coordinate system in the driver, just adjust the getCharacterPosition method. This automatically change the behaviour of most high level functions. It won’t change e.g. scroll functions.

      I hope you are aware, my driver does not support scaled text and drawn graphics. But you can use special characters to “draw” lines and boxes. The idea behind the driver is to use only minimal memory and power to update the screen.

      Hope this helps! Have fun!

    2. Some additions to my previous reply.

      1) I already created a font with the degree character. You can download it here (link).

      2) You do not have to rotate the font, the Font to Byte application will do this for you. Just select “8×8 Fixed Left-Right” as format, instead of the top-down format.

      I hope this helps!

      1. Thank you for your response. Sorry if this is asking to much but i don’t have Mac so i can’t use your Font to Byte, could you do it for me (not rotated).

        I changed my mind about rotating the screen i’m not sure that i know how to do all the stuff you mentioned.

        For scaling the font ( the stuff you explained to JohnH) what exactly do i need to update in the refreshDisplay and refreshFullDisplay ( i can’t find where it is located), if you have time, and want to can you explain it more to me ( and the sendByteMSB) / write what i need to do. I don’t have much programming experience so when you say its not a big problem to me it is 🙁 . Would it be better to scale the 8×8 or 16×16 Pixel Font i use the teensy 3.1 ( don’t care how it works, just want it to work).

        Again sorry for bothering you, and thank you for helping me.

      2. You can use the “Fonts.h” and “Fonts.cpp” files from this project: https://github.com/LuckyResistor/DataLoggerDeluxe These files are already generated and the font has the degree symbol included. For font scaling, be aware that you only can scale every character on the screen. So the number of characters of the screen are reduced to 6×6 on this display. Currently I have no time left to make the adjustments on the driver for you – but I explained it in detail here in the comments. I think the best is if you seek help form a experienced person. Probably there have to be minor adjustments for the teensy platform. I personally do not own a teensy board, so I have no idea if my driver works on this platform – it’s quite a different CPU.

      3. Thank you for the response, 6×6 characters would be for the smaller 1.3″ (96×96) display? i have the 2.7 ( 420×200) )one so i would get 25×15?

        I’ll try to adjust it, but i can’t find what you mean by adjusting refreshDisplay and refreshFullDisplay ( what part of the code is it). For now the library is working well with teensy (at least the stuff i’m using it for)
        Sorry for bothering you.

      4. Yes, of course. For the larger one it’s 400/16=25 x 240/16=15 characters.
        It depends which driver you use. There is the “manual” driver, and the one which uses Timer2. Which driver do you use?

      5. I downloaded it from this site (the Download the driver using the following link.) – don’t see any timer2 ( maybe i’m wrong).

  3. Hi,
    I’m trying to use this library in a project but I’m having trouble using another SPI RAM chip connected on another chip select pin.
    It seems there is some conflict between this two SPI devices.
    The SPI RAM (23LC1024) use the SPI arduino uno hardware pins as the diplay. Of course on another chip select pin.

    I guess, reading the source file, that your display library doesn’t use the hardware spi communication but you implemented a software communication.

    If I don’t initialize the RAM device in firmware the display works correctly.
    It doesn’t happen if I define:

    SpiRAM SpiRam(SPI_CLOCK_DIV8, CS_RAM, CHIP_23LC1024);

    makes a sort of conflict over the SPI communication

    Have you met this kind of trouble so far?

    Thanks in advance

    1. You can not use software and hardware SPI at the same time. As soon you activate the hardware SPI for the RAM module, it will conflict with the software implementation. For the software implementation I control the pins for the SPI manually – as soon hardware SPI is activated, the display driver loses this control, because the pins on this port are switched to the alternate functions.

      If you have enough unassigned pins left, just move the four pins for the display to alternate pins which do not conflict with the RAM. Just pass other values to the constructor of the display driver class.

      More complicated, but as last resort, you have to rewrite my driver to use hardware SPI instead of software SPI. To do this, you have to rewrite the methods sendByteMSB and sendByteLSB. You would ideally write directly to the registers, because so you can implement MSB and LSB by switching the DORD bit in the SPCR register, instead of reversing all bits in a long operation.

      I hope this helps!

  4. Dear Lucky,
    if I close the SPI communication in between a display refreshing it works.
    So the only thing that I did was to modify a library in order to close the hardware spi communication every time.
    Anyway, using the HW spi communication in the display library should be better in order to save part of the RAM and ROM, I suppose.

    But for now everything works as explained before.

    1. Nice to hear everything worked. I choose a software SPI implementation, because you can do bit manipulation while sending the data. E.g. if you want to scale character up 2-times, you just make the methods send each bit twice. Using hardware SPI does not save much space in the flash memory. I assume you can reduce the final size by around 20-30 bytes.

  5. Heyi,
    I am very new in eembedded programming and currently I am working with STM32L476ZEtx board with Sharp LS027B7DH01A Sharp 400×240 display. I need a display driver to write data/string into the display via SPI.
    I find your project very much usefull and also the discussions. But I have one problem, when I added your files into my project, then I need the arduino.h file. I just randomly searched in the google and added it. Now it is looking for
    #include <avr/pgmspace.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>

    #include “binary.h”

    In the internet there are lot of packages that contains those above files. I am confused which one to use actually.
    Can you please suggest me what I can do for this issue?

    1. This driver is specifically written for use with the Arduino IDE, with an Arduino compatible board. You try to use this driver with a very different architecture. As I can see, STMicroelectronics, the producer of your board provides very different development environments to program this microcontroller. Unless you are using an Arduino compatible microcontroller, you have to rewrite the library for your needs – I can not help you with this task.

      Porting this library to another platform is possible, but will take some time. First you need a modern C++ compiler, second you have to replace all Arduino specific elements of the library with ones for your platform. I use various methods and classes from the Arduino library, like setMode, digitalWrite and the String class.

      Sorry for this bad news, I hope you will still succeed with your project! 🙂

  6. Hi Lucky Resistor,
    I tried your 88 scale x2 code on my SHARP 2.7′ 400 * 240, but I have got a problem.
    It limited 15 character on a line and missed 10 character. (400×240 – 25 x 15, 16
    16 font size).
    This is my picture: http://imgur.com/a/Gseb7
    Can you help me to fix this problem!
    Sorry for my English!

    1. So, without the 2×2 scaling, you could use the whole screen? Do you have the modified code somewhere to look at it? I actually never owned a large display like this, so I could never test the driver with it.

      1. Hi,
        I tried your code with 16 x 16 pixel font but it didn’t work, i don’t want use the your scale 2x code. Can you tell me where I need to change ??

        static const uint8_t gScreenHeight = 15;
        static const uint8_t gScreenWidth = 25;
        static uint8_t gScreenCharacters[gScreenHeight*gScreenWidth];
        static const uint8_t gScreenRowRequiresUpdateSize = gScreenHeight/16+1;
        static uint8_t gScreenRowRequiresUpdate[gScreenRowRequiresUpdateSize];

        // The height of a single character.
        static const uint8_t gCharacterHeight = 16;

        // A empty font, to prevent any crashes if no font is set.
        static const uint8_t gNoFont[16] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

      2. A little bit more work is required, because you have to send two bytes for each character. I have no large display here to test a 16×16 pixel font with my driver, so you have to do the changes by yourself. I hope it will be a welcome challenge. 🙂

  7. Thank for your reply!
    I have just modified some where :

    In: LRSharpDisplay.c
    static const uint8_t gScreenHeight = 25;
    static const uint8_t gScreenWidth = 25;

    and it’s working.

Leave a Reply

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

%d bloggers like this: