Mbed LCD Driver for N18 display in the works

This evening I started implementing an mbed library for the N18 display actually for the ST7735 controller used in the N18.

So far I have

  1. setBacklight
  2. clearScreen - with background color
  3. setPixel
  4. drawLine
  5. drawRect
  6. drawCircle
  7. drawEllipse
  8. fillRect
  9. fillCircle
  10. fillEllipse
  11. drawBitmap

The fill primitives have a border and fill color.

If you look closely and the (terrible) video, you will see all the above exercised. I still want to add text rendering and font support before I publish the library.

Here what the code looks like for the above demo.


main()
{       
    LCD_ST7735 n18(
        P0_15, // backlight
        P0_10, // reset
        P0_13, // ds
        P0_21, // mosi
        P0_22, // miso
        P1_15, // clk
        P0_11);// cs

    n18.drawRect(34, 50, 94, 110, 0x0fe0);
    n18.drawCircle(64, 80, 30, 0x001f);

    for(int x = 0; x < 128; ++x)
    {
        n18.drawLine(x, 0, 127 - x, 159, 0xf81f);
    }

    for(int y = 0; y < 160; ++y)
    {
        n18.drawLine(0, y, 127, 159 - y, 0xf81f);
    }

    n18.fillRect(10, 10, 117, 149, 0xfc04, 0x441f);

    n18.fillCircle(64, 80, 60, 0xf800, 0x001f);

    while (true) 
    {      
        n18.drawBitmap(56, 72, frame1);
        wait_ms(150);
        n18.drawBitmap(56, 72, frame2);
        wait_ms(150);
        n18.drawBitmap(56, 72, frame3);
        wait_ms(150);
        n18.drawBitmap(56, 72, frame2);
        wait_ms(150);
    }    
}

11 Likes

Excellent!

Supernice, how fast is it for graphics?

Have you looked at the Adafruit_GFX library? In the mbed compiler I see a couple of ports available.

The Adafruit_GFX library uses one generic API and a separate display specific driver library, which makes it easy to use the same code on various displays. For Arduino driver libraries exist from multi-panel led-matrices to small Nokia LCD’s and full color highresolution TFT’s.
Very easy! Not all driver libraries are ported to mbed yet.

BTW. for the Spark Core someone made a multifont version of this library that makes it easy to use different fonts.

@ taylorza - you are unstoppable! Please keep them coming!

@ taylorza - Brilliant work. Would it be possible to run more than one of these on a single mBuino, or are there not enough pins to do so?

@ devhammer

Since these LCDs communicate by SPI, it should be possible to add more than one. You may need to use extra pins for CS or you could try to daisy chain them to save pins, it could be a good experiment :slight_smile:

Out of 7 pins used by the display 3 are shareable by design (MOSI,MISO, CLK)
Two out of the remaining four can be probably used for both displays (RESET, BACKLIGHT, although I would check how much current backlight needs) That leaves DS and CS.

So maximum you can probably connect is 3.

2 Likes

@ Architect, @ rajesh - Cool. Good to know. I think I have at least a couple of these, so that sounds like a good reason to break them out and test. :slight_smile:

I have not done any real performance testing yet, I got the SPI interface working and then implemented a few throw away primitives to check it was all working. I suspect it will be reasonable for updates and a few small animations but probably not video (I will try thought :slight_smile: )

@ maxint - Thanks for all the pointers to the other libraries. Sadly, as apposed to (I suspect) many people on this forum, I do not get to code as part of my day job, so the embedded stuff is my ‘fix’. I just do this for fun and to see if I can learn a thing or two along the way. And others would probably attest, I like doing things with graphics, games etc.

Thanks. @ architect gave a better analysis than I could have, now I wish I had more then 1 N18 so I could test this out… @ Gus, get that order ready, it will be submitted soon :slight_smile:

Just finished fonts and for @ njbuch I tried to do something that shows the speed of updates :slight_smile: .

The marquee has a 100ms delay introduced so that you can read the text as it scrolls. Again, sorry for the graininess of the image, it seems the phone camera and the LCD are not compatible…

3 Likes

No ray trace 3D yet? You already have the code :wink:

You are going to need this on a board we are laying out now.

Awesome

Looks like Pacman is in the works for mBuino.

@ Architect - it would be a sad day if it didn’t.

Very nice…now when can we get our grubby paws on it? :wink:

I will take a look this weekend if I can get something up and running.

mmm, I am not sure I have the energy for that… but you never know.

Thanks. It will be there shortly, just need to add the javadoc documentation to the interface and put some basic input validation. Depending on time this evening I might get it up tonight or tomorrow night.

Once I have posted the code I will work on any optimizations etc.

Btw. Is there any use for an ellipse drawing function? I could add one, but does anyone use it? Also rectangles with rounded corners, are they worth doing? Let me know, they should be easy enough to do.

2 Likes

The first commit of the code is up. Right now it does not do any clipping and there are a few optimizations I can do to increase the throughput, I will do those as I put the library to a real test. There is a sample font included, I used my favorite font the original IBM BIOS font.

The library can be found at the following location

Here is the code for the sample in the last video which shows how to draw bitmaps as well. Sorry it is so long, but the bitmaps are just embedded in the code. I have written a little tool that converts any bitmap to a bitmap compatible with this library, if anyone is interested I will clean it up and post it on codeshare… mmm is codeshare alright to share none NETMF utilities?


 #include "mbed.h"
 #include "LCD_ST7735.h"
 #include "font_IBM.h"

const uint16_t frame1[] = {
    0x10, 0x10,
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
};

const uint16_t frame2[] = {
    0x10, 0x10,
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
};

const uint16_t frame3[] = {
    0x10, 0x10,
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0xffe0, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
    0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 0x001f, 
};

void Marque(LCD_ST7735 &display, char *msg)
{
    display.drawString(font_ibm, 4, 10, msg);    
    char c = msg[0];
    memcpy(msg, msg + 1, strlen(msg) - 1);
    msg[strlen(msg) - 1] = c;
}

main()
{       
    LCD_ST7735 n18(
        P0_15, // backlight
        P0_10, // reset
        P0_13, // ds
        P0_21, // mosi
        P0_22, // miso
        P1_15, // clk
        P0_11);// cs
    
    n18.drawRect(34, 50, 94, 110, 0x0fe0);
    n18.drawCircle(64, 80, 30, 0x001f);
    
    for(int x = 0; x < 128; ++x)
    {
        n18.drawLine(x, 0, 127 - x, 159, 0xf81f);
    }
    
    for(int y = 0; y < 160; ++y)
    {
        n18.drawLine(0, y, 127, 159 - y, 0xf81f);
    }
    
    n18.fillRect(10, 10, 117, 149, 0xfc04, 0x441f);
    
    n18.fillCircle(64, 80, 60, 0xf800, 0x001f);    
    
    char msg[] = "Hello mBuino!  ";    
    while (true) 
    {   
        Marque(n18, msg);
        n18.drawBitmap(56, 72, frame1);
        wait_ms(100);
        Marque(n18, msg);
        n18.drawBitmap(56, 72, frame2);
        wait_ms(100);
        Marque(n18, msg);
        n18.drawBitmap(56, 72, frame3);
        wait_ms(100);
        Marque(n18, msg);
        n18.drawBitmap(56, 72, frame2);
        wait_ms(100);
    }    
}


5 Likes

Ellipse would be good for drawing robot eyes. :slight_smile:

So the frames hold the bitmaps for pacman?