Nokia QVGA TFT LCD for the Arduino Mega. Design and build (part 1 of 2)

In two of my previous articles I showed you how to reverse engineer the Nokia 2730 LCD for connecting to a device with 3.3V I/O’s and then I showed you how to build a 16-channel level converter for connecting devices together that have differing I/O level requirements.

This article brings together the knowledge we have gained in the previous two articles and puts it to use by creating a project that will allow a Nokia QVGA 24-bit colour TFT LCD to be indirectly connected to an Arduino Mega via a level converter, all on one small 50mm PCB.

All quite straightforward so far. The real innovation will be in the graphics library that I present in part two of this article set. The graphics library will use the external memory interface built in to the Arduino Mega to transfer data to the LCD in a single assembly instruction.

There is no faster way to transfer data out of the Arduino Mega to a peripheral. Doing it like this opens up the possibility of full colour bitmap graphics at a respectable refresh speed.

So now you know the endgame, let’s take the time to explain it all in detail.

The Nokia 6300 24-bit QVGA LCD

Perhaps the first surprise of this article is my choice of LCD. Given that the previous article showed how to reverse engineer the Nokia 2730 LCD you could have been forgiven for assuming that this was the one I’d use.

The 6300 panel with protective film attached

Well, since that project I noticed that a great many of Nokia’s QVGA displays seem to vary only slightly in their pinouts and as such the likelihood of them using the same controller would be high. I picked the Nokia 6300 for this project for the following reasons:

  • It’s readily available (on ebay) and costs very little.
  • It claims to support 16M colours (24 bit). You would be forgiven for not noticing the difference between 16M and 262K colours though.
  • It’s pin compatible with a large number of Nokia models: 6300, 6301, 5310, 7500, 8600, 6120C, E90 and E51.
  • The connector is readily available from online sources.

The connector

The connector is the same 24-pin board-to-board connector used in the Nokia 2730. An eagle-eyed reader has identified the manufacturer and the part number. It is made by JST and the part number is 24R-JANK-GSAN-TF. Here’s the datasheet.

It is easy to obtain them either direct from JST’s online shop or in small quantities from online sources. Here are some direct links to the ones that I know of:

The pinout for the connector is shown here:

Here’s a photograph of the LCD side of the connector. If you look closely you can see where the ground pins connect directly into the ‘ground pour’ inside the ribbon cable. This helps to identify where pin 1 is located because the big “1” silkscreen’d on to the FPC is in the wrong place.

The connector on the LCD FPC cable

The backlight

Like the 2730 before it, the 6300 backlight consists of 4 white LEDs in series requiring around 13V to power them. Just like before, I will use the OnSemi NCP5007 constant current backlight driver to do the heavy lifting here.

The NCP5007 in SOT23-5 package

The NCP5007 will be configured to supply a constant 20mA through the backlight circuit and we will use a PWM signal on the ENABLE pin to vary the brightness.

Power supply design

We need both 5V and 3.3V inputs for this design. 5V will be used to power the backlight driver as well as set the reference level for the Arduino side of the level converter. 3.3V will be used to set the reference for the LCD side of the regulator.

The backlight draws the most power from this design so I will optionally allow 5V to be supplied externally from a supply that shares a common ground with the Arduino itself.

TFTs like these draw a very small amount of current, typically less than 10mA so I will supply it indirectly from a GPIO pin through the level converter. This allows me to control the order in which power is applied. Many TFTs prefer their I/O supply to come up before the panel supply and for safety I’m going to assume that this is the case with this device. Had the device required significant amounts of current I would have had to use a couple of transistors to switch the current on and off.

Arduino interface design

The Nokia 6300, like the Nokia 2730, uses an 8-bit 8080 protocol to communicate with the LCD. The 8080 protocol consists of a chip select signal, 8 bits of data, read and write lines and another line that is used to indicate whether you want to transfer data or set a command register value.

The 8080 protocol write cycle

The above image summarises the state of the 8080 bus during a write cycle. The key point to note is that data is transferred to the controller on the rising edge of the WR line. Can we get this line from the Arduino Mega’s external memory interface? Well yes, we can. The following diagram from the datasheet shows the timing of the external memory bus.

The ATMega1280 external memory timing

Note the behaviour of the address latch enable (ALE) line. We need an active-low chip select (/CS) signal that is low during the data setup and transfer phase. ALE behaves perfectly in this respect and we will use it for chip-select. This is a critical part of the design. If ALE was not present or did not obey the above timings then this design would fail.

The register/data select line

This is the line used to select whether you’re transferring data or writing to a register. It is somewhat confusing in that it is variously referred to as RS or D/CX depending on which datasheet you’re reading. I’m going to call it RS from now on.

The trick we will use to select or deselect RS is one that we’ve been using on more powerful ARM MCUs for a long time. We will attach RS to external address line A8. That means that if we write to a memory location that has bit 8 set in its address then we will transfer 8 bits with RS high. Conversely if we write to a memory location that has bit 8 reset in its address then we will transfer 8 bits with RS low. A neat trick!

The only precaution that we must take is that we select an address that is not actually in the internal 8Kb SRAM, the address must be up above that range to avoid a clash. We will use address 0x8000 for writing to a register (RS=low) and address 0x8100 for writing data (RS=high).

Selecting a low address line (A8) means that we can free up address lines 10 to 15 for GPIO, saving 6 pins. It doesn’t matter that our selected address locations 0x8000 and 0x8100 are high up in the address range who’s address lines are free’d for GPIO. The ATMega will still correctly control A8. Not only is this design fast, it’s frugal with pins too. Here is the mapping of Arduino pins to their LCD function.

Arduino ATMega Port Function
22 PA0 D0
23 PA1 D1
24 PA2 D2
25 PA3 D3
26 PA4 D4
27 PA5 D5
28 PA6 D6
29 PA7 D7
34 PC3 VIO
35 PC2 VDD
36 PC1 A9 (1)
37 PC0 RS
39 PG2 /CS
40 PG1 /RD (2)
41 PG0 /WR

(1) A9 is not used but cannot be released for GPIO.
(2) /RD is not used but cannot be released for GPIO and is pulled up to VIO.

Our design is write-only to the LCD. We cannot read data back from it, and would never want to.

The schematic

Now that we have a design we can create the schematic in the Eagle designer. All the 5V signals from the Arduino that are destined for the LCD are routed through the level converter and will come out the other side at 3.3V.

The schematic (click for larger PDF)

Parts list

Here’s a list of the parts that I used for this build.

Part Value Device Package
C-6300 NOKIA12X2 24R-JANK-GSAN-TF 12X2
C1 4.7u ceramic 0805
C2 1u ceramic 50V 0805
C3,C4,C6,C7,C8,C9 100n ceramic 0603
C5 4.7u ceramic 0805
D1 CD214A-B140LF schottky DO214AC
L1 22uH LQH3NP_J0 1212
MEGA pin header MA12-2 MA12-2
R1 10R resistor R0805
R3 33K resistor R0805
SV2 pin header MA03-2 MA03-2
U1 NCP5007 NCP5007 SOT23-5

The board

After creating the schematic the next stage is to switch to the CAD designer and lay out the board. I placed the components and routed the traces manually. The connector is placed so that the FPC will wrap around the board edge and allow me to mount the LCD on the other side using double-sided sticky tabs.

With the LCD facing up, the interface pins face down and press directly into the sockets on the Arduino. The pin header is placed as close to the edge of the board as possible so that adjacent Arduino pins are not obscured.

The PCB layout and routing

After staring at the layout until I’m square-eyed (sound familiar to anyone?) I’m feeling confident that the header pins are all where they should be, the connector positioning will result in the LCD ending up in the right place and the silk-screening will end up on the correct side of the board.

The build

With the board design complete I uploaded it to ITead Studio for manufacturing. About two weeks later the boards arrived in the mail. As usual all were perfectly manufactured with no visible flaws.

The component side of the board

The LCD side of the board

I construct the boards by tinning the pads and then reflowing the larger components such as the level converter, LCD connector socket and the NCP5007 using a hot-plate. I then reflow the smaller discrete components using my Aoyue hot-air gun.

After the completed PCB is cleaned and dried the design is completed by pressing the LCD connector into its socket and mounting the panel on double-sided sticky pads. That it fits comfortably on to the pads was a bit of a relief because the metal back of the panel must stand clear of the traces and particularly the vias on that side of the board.

The component side of the board

The open holes in between the groups of header pins allow the unused Arduino pins to be accessed for general purpose use. The designers of the Arduino clearly knew what they were doing when they grouped together the external memory pins in the same place.

Unfortunately as you free up unused address pins from A15 downwards they free up from the middle of the external memory pin group. It would have been a nice design touch if they’d free’d from the end of the group instead but you can’t have everything.

The LCD side of the board

It fits perfectly, and it should do because I did carefully measure everything first. However you never really know if you’ve got it right until the hardware arrives and you put it all together.

It is required to connect the 3.3V and GND pins to the Arduino. With the blue jumper connected 5V will be taken directly from the Arduino board and used to power the backlight. With the jumper disconnected I must supply a regulated 5V myself to the 5V (in) pin.

If I want to control the backlight brightness using a PWM signal then I can connect that signal to the EN pin. Alternatively I can jumper the EN pin across and that will tie it high meaning that the backlight will always be at 100% brightness.

The software library

Now that the build is complete we need a software graphics library to exploit the capabilities of our new hardware. Continue reading part two of this two part series of articles where I present an advanced, high performance graphics library with lots of examples to try out and videos to watch.

Temporarily sold out! Some more boards are supposedly on the way to me so if you’re interested then please use my contact page to let me know and I’ll drop you a no-obligation email when they’re ready.

Update: 2 July 2012

I have noted that not all boards obtained on ebay are the same. To my surprise there are slight differences in the behaviour, nothing radical but enough for me to justify a new release of the software driver to deal with this ‘type B’ model. I will refer to the original model as ‘type A’.

The differences found so far are:

  • Type B will not initialise using my 16M driver. They require the 262K driver and then they will look and behave the same as before.
  • The hardware scrolling offset is reversed. Type ‘A’ boards scroll up one line with an offset of 319. These type ‘B’ boards will scroll up one line with an offset of 1.
  • Type ‘B’ boards support the faster 64K driver. Type ‘A’ boards do not. The raw fill rate for the 64K colour mode is 1.32 megapixels/second. It is 1.06 megapixels/second for the 262K and 16M modes on both boards.
  • These type ‘B’ boards seem to have a brighter backlight and could probably run optimally on a 90% PWM duty cycle.

There will be a software update in the next few days (now released, version 1.1.0) to support the difference in hardware scrolling behaviour.

Update: 23 September 2012

Another controller variant has turned up and we’re going to call this one ‘Type C’. It’s showing up in both 6300 and N82 screens. It behaves the same as Type A screens except for the following differences:

  • It won’t go into BGR colour transfer mode, only RGB is supported. Since RGB is supported by all variants I’ve seen RGB will become the default mode in my driver code from 2.2.0 onwards.
  • Page and column addresses are not reversed in landscape mode.

Type C panels are supported from version 2.2.0 of my driver code using a _TypeC suffix to the driver name. e.g. Nokia6300_Landscape_262K_TypeC.

Schematics, CAD and gerbers available

I have open-sourced my PCB design and CAD files so if you’re interested in building your own boards then head on over to my downloads page and grab yourself a copy. The archive includes gerbers for both the SSOP-48 and TSOP-48 level converter footprints.

Some boards for sale

I have some fully constructed boards as well as some bare PCBs for sale while stocks last.

Fully constructed boards

These boards are all fully built, tested and include the TFT panel. The price is £16.90 for UK buyers and £18.49 for worldwide buyers.


Bare PCBs

These PCBs are the same as featured in my article with one important difference. The footprint for the level converter is TSOP48 (DGG suffix) and not the SSOP48 (DL suffix) pictured in the article.

The price including postage is £4 for UK buyers and £5 for worldwide delivery. I can also include one of the 24-pin JST 0.4mm connectors for a small amount extra. Contact me if you want to take me up on that.


  • Brad

    I've just stumbled on your blog from Hackaday and wow, what a great find!

    Still so much to learn and with sources like these it makes it a lot easier! Thank you very much! Great work!

    • Thanks Brad, there's more good stuff to come 🙂

  • Hi,

    Thanks for your nice article. How can you send streaming data using this architecture? I mean, by using the xmem bus, you should always send an address for your data. But these LCDs has instructions for declaring an area of the screen and then streaming data to fill it. Once I tried to do this using a N96 LCD and an ATmega128A, but I realized that: 1. The streaming which has a great effect on performance is not usable, 2. 16-bit mode is not available (not applicable to your configuration), and 3. I didn’t have a nice and speedy solution for the lower xmem addresses which were in the internal SRAM. Then I decided to use the xmem ports but in their normal behavior because they don’t have any other alternative function!

    • The section "The register/data select line" explains how I select whether I'm sending data or a register index.

      • So, you send data by writing to address 0x8100. Then for sending each byte, the CPU spends 2 cycles, one for address and one for data. If you use GPIO, each byte will be sent in only one cycle. As I said, your method is faster in one by one data sending, because there’s no need to manually adjust READ/WRITE, CS, ALE and RS pins. But when it comes to streaming a chunk of data, it’s better to use normal IO because there will be no additional cycle for pulling RS high. Am I right?

        • No it's not because you'd have to manually control WR twice for each data transfer, remember that data is transferred on the rising edge of WR. You can't just repeatedly write to D0..D7 without telling the receiver when he can read it off.

          • You’re right.

            I think there is a better solution. Why not to connect RS pin to ALE pin of the xmem bus? You know this so called instructions are really register addresses. So writing and reading from a register needs just one instruction.

          • Because ALE drives CS. With all the panels I've seen so far you can't just tie CS to ground – it must be driven – though this may not be the case for every panel in existence. Writing a register address already requires only one instruction, same as data. It cannot be made any faster:


            6e76: 2c e2 ldi r18, 0x2C ; 44
            6e78: 20 93 00 80 sts 0x8000, r18 ; ** write to xmem with register select (RS=low)

            and for data:

            6e84: 40 93 00 81 sts 0x8100, r20; ** write to xmem with data selected (RS=high)

  • rony

    what controller chip used by nokia 6300 lcd?

    • The exact manufacturer/part is not publicly known. However it is very close to the MC2PA8201 and to a lesser extent the LDS285.

  • bento

    great find andy, i want to learn much more about this lcd, do you have a complete instruction/command list for controller chip? or maybe you have complete datasheet?

    • I've added the datasheet to my 'Downloads' page. Please go ahead and grab it. Nearly all the commands in this datasheet seem to work but you will find some that don't. For example the gamma setting commands don't work – I expect the gamma is set at the factory.

  • bmn

    Great job ,

    Do you think we can adapt this with nokia 6320 screen ?

    • I'm afraid not. It appears to be an entirely different display.

  • Stephen

    Hi Andy, when will this be back in stock?

    • Hi Stephen,I should have some more in about 10 days.

  • anthony

    Hi, do you have the interface boards or kit of parts available for sale? Some of the parts are very difficult to get in Australia in small quanties? Thanks.

    • Hi Anthony. Unfortunately I don't have any parts for sale. Which parts are you having trouble obtaining? The ancillary components are generally available from global sources such as Mouser and Farnell. The FPC connector can be obtained in single units from 'cellnetos' for $0.81 / unit. The schematics and gerbers for the boards are available on my download page and you can just upload the gerbers to ITead/Seeed/Elecrow and get 10 copies for about $10.

  • Jarrett

    What pitch is that FFC? What's stopping you from just cutting off the hard-to-find-proprietary connector and clipping on something like this?

    • It looks to be slightly over 0.2mm and on some of the screens they're unevenly spaced in that there are some 'fat' traces mixed in with the thin ones that mess up the even spacing. I would not want to try cutting and retrofitting myself but would be interested to hear if anyone manages it.

  • fathin

    great stuff you have here. . .

    a poor student here.
    i can't afford an arduino Mega yet, and having a hard to find level shifters, (maybe i can find the connector @ some cellphone part store, physical store or salvage from broken one, anyway it's minor thing)
    and i have no online accounts (paypal thingy)

    and i'm thinking of some solution,

    1. can i use voltage divider as level shifter to step down 3.3v since we don't need step-up (input) level shifter? or do we need one?

    if i can't
    2. is it possible to wire it to 3.3v 328p (as spi/i2c driver) then connect it to 5v mcu? (i can find 2pin level shifter)

    LCD<3.3V MCU <i2c via 2pin level shifter> MAIN MCU

    if not, what make me can't do it?
    no. of pin? then can i use 40pin arduino compactible avr's: 32, 644p (sanguino), 1284p(mighty)?

    • Hi Fathin, a voltage divider using cheap resistors would probably be fine for the logic signals. I say probably because the presence of the resistors on the logic lines will slow down the signal edge transitions. Whether it actually makes any difference is something you will just have to try in order to find out.

      • fathin

        great! i'll try, then what is the minimum requirement for the mcu? pin number is obvious, but what about clock and stuff?

        • There's no minimum MCU clock but the slower the clock the slower the performance of the display. For a 320×240 QVGA display on the Arduino I would not want to go any slower than the standard 16MHz so that your display updates are fast and the user experience is good.

  • Edward Pineda

    Hello I do not speak English, but I've seen your work, and I think it's great. I had some doubts, but among the main, we would like to know what the datasheet of the screen on which you based you to do all this work. I would like to know this as I am a student of Electronics Engineering and I want to know more about the functioning of this. If you can help me I would appreciate. Congratulations on your work.

    • Hi Edward: The MC2PA8201 is the controller that this work is based on.

  • Prasad

    Thanks a lot Andy.. I’ve been looking for such a stuff for weeks… And I’ve finally found it.

    Like fathin, I m a poor student and I cant get level shifters here in my place. ( I’m in India).
    So I’m planning to use DevBoard with Atmega8 @ 8MHz, custom-built by me with 3V supply (Controller works fine). So that the signal level stays < 3V. Is this a safe signal and power voltage level ? Or still less is required ? Or is there any other voltage level required too ?? I got too much confused after reading electrical specs in the datasheet….!

  • Khoa

    thanks you very much

  • Yans

    Nicely done! Can you tell me please, what type of controller does the LCD use?

  • Yans

    By the way, do you know, that the supply voltage for the LCD really shoud be 2.8V VDD and 1.8V VDDIO maximum, that you are over the absolute maximum rating for the LCD module?

    • Hi, yes I’m aware of the VDDIO risk however we don’t know that the controller is a genuine MC2PA8201, only that it has a compatible command set that is a subset of MIPI DCS. RDDID does not identify it as a Magnachip device.


    If I’m not mistaken, the Nokia 2730 display seems to be either identical or similar to the Nokia C2-05 display (which is the same as the C2-02, C2-03, C2-06, and C2-07 display). Would you be able to confirm this for me? And, if possible, tell me if your work done for the 2730 display would apply to the C2-05 display? Thanks.

  • Peter

    Do you think this design can work with Nokia 6131 LCD display?

  • Rohan

    Thanks Andy for the information. Its difficult to get datasheet for Nokia QVGA 24-bit colour TFT LCD. Thanks a lot!

  • Rodolfo

    Hello Andy,
    how do you solder the connector and other components o the PCB? Do you have some sort of tutorial on this? I am very interested in this project of yours and would like to experiment with it. Does it work with Arduino Uno?
    Thanks, super job!

    • Hi Rodolfo. These days I use my halogen reflow oven – the schematics and design for that can be found on this site. Before I had the oven I used a simple hot plate to do the reflow. The connector for this LCD has a 0.4mm pitch and the pins are very close to the plastic body that will readily melt if you touch it with a soldering iron. If you were to to attempt soldering with an iron then you’d need good magnification, strong lighting and some method of steadying the iron in your hand. It will work on the Arduino Uno – there’s an example on this site that shows that. However you are not left with much flash memory or IO pins to do anything else. You really need a Mega to get the most out of it.

  • Mc Donald

    Dear Andrew do you have library for some newer nokia lcd’s like C2-02 or nokia 220 , 222 ?
    It’s began really hard to find older lcd’s.

    • Hi, sorry I don’t. Nokia discontinued the use of the simple-to-use LCDs quite soon after this one and moved to much higher performance LCDs that are pretty much impossible to drive from a simple MCU.

      • Mc Donald

        Thank you bro.
        It seems that someone from the hackers country (Russia :D) has managed to launch Nokia 220 on Arduino.
        Do you have any info about the chipset number on this LCD?
        I tried to take Arduino library from him, but apparently not interested in publishing it.