Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Understanding how to drive an Optrex F-51851 LCD graphical display ?

Status
Not open for further replies.

CaptainBlood

New Member
Hi dear all.
I'm writing software to drive a F-51851 lcd display which uses 2 NJU6676 to drive a 240*64 dots screen. It so happens I have no hardware prototype to support testing yet.

My major issue is understanding when to care updating the CS1/CS2 bits flags.

Should PowerON/Poweroff sequences be duplicated for each controller ?

Regarding row and col adressing :
I seems like row/col adressing should follow a scheme where the whole display is splitted in four quadrants. So Depending on the value col (row) should be adressed on the proper controller accordingly. So im some cases a row/col should be defined through the same controller, in other cases a controller switch should be achieved prior to the second setting. Can anyone can confirm this ?

Regarding display data read and write :
How to define the right controller to fetch/display a data ? Does it depend on the concerned col only ?

Here's a list of the docs I have :
F-51851 LCD Module Technical Spec and 20090225 OAI-80018AA-7601-B STEP-Series Application Note.pdf, both from Optrex.
NJU6676 from JRC.

Thanks for your attention.

P.S. I'm aware this display is reaching end of life cycle, so I plan to upgrade project. But up to now replacement is only black/white, not green as expected. Futhermore I have 2 parts I costly acquired so I wish to use them in prototypes. Replacement part F-55471 seems to have minor cabling and functionnal differences. So functionnal understanding should be preserved.
 
Last edited:
I believe that LCD has an inbuilt controller, with a standard 8-bit interface.

**broken link removed**
https://www.electro-tech-online.com/custompdfs/2010/08/AN034Driving240x64LCD.pdf
TC51320 LCD Controller for Optrex F-51320 128x64 Graphic Display

Although I can't see any data on high level functions (like text mode, over lays) I suspect its similar to a KS0108 used in 128x64 displays. That too uses chip selects to select different halves of the display.

The timing diagrams in the datasheet above, and possibly in the other links will help you determine when to update /CS but it will depend on what CPU interface you use. Most LCD's can be configured for 8080 series, or 6800 series interfaces. The 6800 being probably the easiest - as this has an 'E' strobe, which determines when all the other lines are read. In that case you would pull the CS lines low/high to select which controller (ie: which half of the display to control), select data/instruction, set your data, then clock it in with the E strobe. The actual order you set up these lines doesn't really matter at all, unless you're running it at full speed and coming close to the timing limitations (unlikely). The controller only cares about whats on the lines when the E goes through a transition, or in the case of an 8080 interface, when either the /RD, or the /WR lines are pulled low.

I would search for graphic LCD routines (for either 128x64, or 240x64) for your microcontroller of choice. The interfaces are VERY similar between LCD controllers, the difference being the actual data (instructions) and timing.

If you're still having problems, I'll watch this thread.
 
Last edited:
Thanks for your reply. Sorry for being late but I spent a lot of time trying to understand the specification of the LCD logical controller (and programming too).
Your links are correct. I almost came to conclude it functions the way your described. Thanks for your resume.

The issues I'm planning to face later on will be more electronic oriented.

1) The LCD contrast is sensitive to temperature. So power supply to the display itself (not the logic) should be designed in this respect. The programmable part of such a logic is very likely to be implemented in the MCU that drives the LCD display logic.
1.1) My current LCD (not the replacement part) power supply for display cannot rely on the display power unit integrated in each of the two ICs. It seems I have to Quad Pump externally.
1.2) The combination of theses two problems I will consider as a whole problem by it self. I will solve that out later.

2) The MCU I wish to drive the LCD with has output raise and fall timing below those required by the display unit.
Whether I use Intel or Motorola, I will have a max of two signal wires concerned this issue.
Maybe an IC "buffer" is the solution ? May be a design with a very few componants is possible and financially competitive with the other solution ?

Do you have any idea on the second subject ? Sorry but I'm a IT who has to solve Electronics issues.

Thanks for your attention and interest.
 
Last edited:
Hi again,

I must say its refreshing to see someone who is thorough with regard to specifications :) Many just slap a circuit together and come on here to ask why it doesn't work. - And those are usually 'IT guys' as well! Good to see you're not assuming that electronics is a subset of IT and is easy. Sorry for my dig at IT guys :)

I realise you are thinking about issues 1.1-1.3 later on but with 'temperature sensitive contrast', I wouldn't worry too much. The variances in temperature required to noticably change the contrast tend to be those used in outside environments, not in an office, or building. Admittedly the liquid crystal in displays does get funny with temperature changes, for the most part I use a trimmer pot to set it so it 'looks good', and leave it. Any tweaks that need to be made to the contrast voltage are pretty small, and would require your MCU to drive either a DAC, or PWM, (both usually output 0-5V, or 0-3.3v) then some analogue to level shift and squeeze the range down. - But as you said, its something to worry about later, I wouldn't be overly concerned with it.

I went over the datasheet (first link in my post) again, and I didn't realize first time that it required an external biasing network. But, if you hadn't already noticed, the second link (page 11) provides a nice schematic for that :D And page ten describes the use of a rather complicated DAC boost inverter for digitally controlling contrast. IMO this is over kill, but some provide some nice information about how one can digitally control the contrast of a display. There are simpler (and cheaper) methods.

About number '2' in your post. Maybe I am jsut being practical here, but I have yet to use a microcontroller with IO rise/fall times that cause problems :) As long as your MCU runs at 5v, as the display, There shouldn't be any issues. The only problem would be if you were to write your code and set pins as 'outputs' when you're reading the display. The LCD module turns its IO's to outputs, your micro has outputs = fried IO pins. A series resistor from MCU IO to LCD IO solves this nicely, say 220 - 1k ohms. This will slow the rise/fall times, but it doesn't matter we're still talking nanoseconds here. For the above reason, a buffer would have to be 'tristate'. Since most logic buffers are unidirectional, in order to read from the display (to check if its busy for example) you would have to turn off your buffer (make the output pins 'tristate', which virtually disconnects them), then read from the LCD pins directly. Its done in many situations, but in this case, I think its just more work for you.

As for MCU/MPU choices. Even an 8-bit PIC/AVR can happily run that display, its just a question of available memory for bitmaps/text, and available IO pins. But of course, generally one decides based on which micro they are comfortable with, or have support for (compilers, programmers, debuggers etc..).

If you get really stuck, I could knock up a schematic of how I think the biasing network/power connections should go. That would leave you with just a digital interface to worry about. Good luck!

Blueteeth.

Ps. if you hadn't guessed, LCD's are my thing.... I must have about 85 sitting around somewhere...sad I know.
 
Hi again,
I apologize again for been so late. But I couldn't connect because I was on a trip to your side of the channel (Middx).

Thanks for answering.
AFAIK although you have no practical experience with my Optrex, it seems your could be the right guy to help me understanding better how my hardware works !!!
1) First regarding your statement
The LCD module turns its IO's to outputs, your micro has outputs = fried IO pins.
Which IO pins should fry ? LCD ? MCU ? Any of the two ? I'm just asking cause my LCD costs me about a 100£, my MCU 3£ ... Got my point ? Fonctionnally speaking I could face the situation. A bit of an explanation : Im writing a generic driver that allows to display characters which height isn't a multiple of 8. And because my MCU has very little memory I can hardly map the symbolic display in the memory of my MCU. So when I display a character I have to "merge" its top and bottom rows with the current displayed surrounding. That why I expect the driver to perform a lot of read data / process and merge / write data. I will anyhow extensively test my driver in simulator before pluging it into the real world. At least you gave a hardware solution to protect both ICs. MCU and LCD will probably both have 5 Vdd as you recommended. Rise and fall issue is specified by : (30~32)ns MCU vs 15ns LCD.

2) If you check the last figure at the end of the following doc https://www.ee.oulu.fi/research/tklab/courses/521423S/2009/pdf/OAI-80018AA-7601-51852-SeriesAN20080104.pdf you may undertand why I'm so worried about contrast variation. Furthermore, the display is a part of a highly packed dashboard. I will have no possibility for a manual control. But as it has been said already this is a final step issue. I'll be very glad when this step is reached.

3) Have you ever dealed with a dual panel lcd display with two ICs in master/slave configuration ?
 
Oops ! Sorry ! Didn't realize post can't be post-edited. So here's the end of the previous one.

I have a problem understanding how to adress part of the screen.
From the doc https://www.ee.oulu.fi/research/tklab/courses/521423S/2009/pdf/OAI-80018AA-7601-51852-SeriesAN20080104.pdf at page 16/last figure some valuable information could be found.

Tough it seems clear for the left part(MASTER) of the screen, the segment adresses from 0x00 to 0x18 for the right part(SLAVE) of the screen are very confusing.
To me 0x00 to 0x18 is the size of the column diff between MASTER and SLAVE. I would have expected 0x00 to x64.
I guess Optrex engineers could answer to this, but what is your opinion ? Is it a typo ? Or what ? Am I missing something in the adressing mecanism ?

For the rest of the adressing behaviour my understanding is as follows :
Adressing the upper left of the screen should be done in three steps :
1) Segment should be defined through the MASTER (set as master, SLAVE set as slave)
2) Common should be defined through the SLAVE (set as master, the MASTER set as slave)
3) Data to be displayed should be written to the MASTER (set as master, SLACE set as slave)

To resume Segment/Common addressing should be set according to quadrant definition.
Data should be transmitted to the left/right panel depending on the location of its destination.

Do you have the same understanding ?

Thanks for your support, interest and time.
 
Last edited:
Don't worry about the long post, my posts are always full of 'redundancy', as people can always ignore certain parts, but no enough info requires another post :)

Well, I will look into this further later on when I have time. But I have skimmed over page 16 of the link you provided, and quickly read your post.

I'm not sure if you realise (I do'nt want to sound patronising here if you do know) but the numbers 0x00, 0x18 are hexadecimal :) 0x00 being '0' in decimal, and 0x18 being '24' . Often graphic LCD displays are divided up, since one controller IC cannot control all the segments on the display. For larger displays such as 320x240, there are many driver IC's, connected up, and controlled by a single 'master'.

In the case of 128x64, or 240x64, there are usually 2 or four of these IC's. To complicate matters, these master/slave IC's are both drivers and controllers in one! Using CS1/CS2 lines to control which one your interface is talking to. Because of common display resolutions, often such controllers/drivers can drive up to 132 columns, and 32 rows - since 132x32 is a common resolution, and so would only require one of these controllers. For 128x64, two are used for the upper and lower parts of the display. The last 4 columns (display is 128, but driver can do 132) DO exist, they simply aren't on the display which is why some numbers don't immediately make sense. With YOUR display, each controller IC can do 64 rows, and 132 columns - meaning, two of these chips can give a resolution of 264 x 64 (2 x 132, with 64 rows). As your display is only 240 x 64, 24 of the columns aren't used, or addressed. This means your display addressing isn't symmetrical.... the first 132 columns are controlled by the master, and the last (240 - 132 =) 108 columns controlled by the slave.

Rows are called 'com', and columns are called 'segments'. - to make things even more complicated :) Also, since we are dealing with binary/hex, the number '0' counts as a state. So, in addressing terms, the numbers go 0 - 131, and 0 - 107. In hexadecimal, that would be 0x00 - 0x83, and 0x00 - 0x6B. With rows (com) being 64, 0-63, or 0x00 to - 0x3F.

I suspect the 'four quadrants' in the link you provided are showing examples of how one would address different parts of the display. It is not saying the address is split into four parts, but rather giving examples of the address numbers for certain area's of the display.

So, ultimately, say you've already setup your system, and you're simply writing all '1's to the display. (pixels all on). If you just select the master controller, and start writing, the pixels with turn on, in groups of 8, each column. That means a vertical line of 8 pixels will appear at the top left of the display. Each byte writes to one column, but 8 rows. So, you would have to write 132 bytes, and end up with a 'block' of 132 x 8 pixels turned on. After this no more pixels will turn on, because the master can only control the first 132 columns, and unless you change the 'col' address (rows) it stays on that top column of 8 pixels.

Complicated? heck yes! But once you get your head around how it maps the bytes you write to the pixels, you'll realise that it makes life easier when writing text :) As its laid out, if we write 8 bytes for a character, we can have 64/8 = 8 rows of text, with 132/8 = 16.5 characters on each line.... for the master controller.

I must say, it is odd they have made it assymetrical, I would have thought they would use 120 columns for each controller.

Sorry for rambling, I'm just blurting out thoughts/experiences.

Blueteeth
 
My bad, I made a mistake :
I would have expected 0x00 to x64.
should be corrected to
I would have expected 0x00 to x6B.

I think I understood the way to adress cols and rows. I was just resuming my understanding. (too briefly perhaps ...) and asking for confirmation.
Still the references "0x00 to 0x18" for slave segment adressing you can find on that figure at quadrant 2 and 4 in "Application Notes" seem WRONG to me. I will find a way to ask Optrex guys.

It is not saying the address is split into four parts, but rather giving examples of the address numbers for certain area's of the display.
. I've never meant thas. But I think depending of the quadrant containing the "Byte" to adress, there are four differents adressing sequences, one for each quadrant.


As I mentionned in the lost mails, my driver is for text with generic font size. That means it can support any font size. As you can guess my MCU will have to do a lot of calculation ! Characters will often be splitted between different physical rows. So whenever I want to display a character I have to consider the row sharing with adjacent characters. And to make things worst, I can't store a symbolic copy of the screen. So I must read the screen first and merge the proper part of its contents I must keep with the data I want to update. The vertical border is not a biggest issue, by far ... left to right/right to left writing is internally managed. So I's only a matter of proper definition of the limit adress where to trigger jump to the next panel. Unfortunatly There is not such a mecanism to manage top to bottom/ bottom to top writing. So here I've got another challenge. Not to mention assembler is involved, no C in MCU please ;)!

Talking back about the rise/fall timings, the LCD datasheet seems to be requesting 15ns (tr & tf at page 6/23 of your datasheet reference) where my MCU can only do 30/32ns. Both ICs will be at +5Vdd. Hope this will work. Thanks to mention the possibility to FRY IOs. Since you don"t explicit IOs, I guess both ICs are in danger here. I will extensively run my driver in simulator and will protect MCU to LCD wiring as mentionned. LCD is ~80£ so I must be very careful. MCU only 3£. As explaned above writing a character may involve a lot of read/write cycles. So thanks for pointing this possible showstopper.

You will see in the page previous to the last one in "Application Notes" how constrast is sensitive to temperature. The LCD is only a part of a much larger dashboard, with most of its panels dynamically backlighed, ie highest at noon, lowest at midnight. LCD has backlight also. I must consider optimal LCD contrast may be a must, not just an option. And I'll be already very happy when reaching this stage. Not related to LCD, cheap n bits DAC to manage a backlight led network is one of my purely electronic issue. Will open another post for it.

Thanks for your time, interest and support.

Sir Henry Morgan

P.S. Was on your side of the Channel (Middx) for four days. Reason why I replied so late to your prompt answer. Terrible weather this year, but great food as always.
 
Last edited:
Heh, our weather has been dreadful recently, either heavy rain and high winds, or light rain and heavy winds :)

Note the 0x6B in hex is 107 in decimal, not 64. I was refering to the number of columns the right (slave) controller IC controls. The '64' is the number of pixels vertically, but your controller writes 8 bits of these at a time. When you write a byte to the display there is a 1:1 ratio between bits and pixels... as it cannot control the brightness of each pixel (where as PC monitors use up to 32 bits per pixel). So a byte, controls 8 pixels, and with your controller its a column of them. Also, since you have 64 of these, the first is addressed as 0, not 1, so the bottom left pixel is in fact number 63.

This means, if you were to set your LCD to stay on the same column (referred to as 'seg' in your link), it would only take 8 bytes to draw a line form the top, to the bottom of the display. Soooo ultimately, in terms of bytes (not bits or pixels) you have 240 x 8.

You are correct in pointing out the issue with drawing character bitmaps of any size. Because of the 'byte' nature, horizontally, there is no issue... as each byte you write only controls one column. But it writes 8 rows. This is why the font 7x5 is so common. The character is 7 bits high, and theres an extra bit (pixel) to give a space between characters on different lines. Smaller fonts are possible, but require calculation, which is 'often' done with the on board controller on larger displays. But re-reading your post, I guess you already know this :D

About the 0x18 issue, you're right, it is wrong! I've been trying to get my head around that overly complicated diagram (its form a university course, and the lecturer it seems, has screwed up). The slave controls pixels 133 to 240, That is 108 pixels (as we include the 133, AND the 240 pixels). The addressing starts at 0, meaning 0x00 is for pixel 133, and 0x6B is for pixel 240. SO yeah, should be 0x6B. As to why they split the display into upper and lower halves? god knows. Its a terrible diagram for describing the addressing of the display from the interface's perspective.

Seems like you've pretty much got it down. I really wouldn't worry about the rise/fall times. A maximum rise/falll of 15ns seems ridiculously high to be, but I think that is if your interface is running at the highest speed the LCD will allow... that is, if lines don't rise in time for other lines to change... meaning timing gets screwed. Even high speed logic buffers would have issues with that.

And assembly? wow, masochist! I've been writing assembly for PIC's and AVR's since I was 18, only recently gone to C because I'm lazy, and with USB stacks in micro controllers.... one NEEDs C :D

Blueteeth.
 
Thanks to confirm you agree what seems to me to be a mistake. I had an awful time trying to make sense out of it. The spec is dated 2005. Wonder what QA are doing at Optrex ? The only reason I could imaging for such a complicated addressing plan it to balance load between the two ICs. On the other hand it probably drowns the MCU with additional instructions. I will be able to answer this once my driver is finished.
To me these rise and fall max are expected to insure to signal change will be taken into account by the LCD's IC. So my 32ns PIC is very far from such a requirement. Anyhow I will see what happens at experimentation time.

Well C is great, I love it. But when it come to middle range pic with segmented program pages, each function call with the pagesel to worry about, the instruction cost ans so on, I find it painful. As you probably understood my MCU will have to do a lot of calculation, so waste of CPU may compromise performance. I haven't mentioned it is a real time display, expected to be refreshed every second. sometime completely, sometime partially. Communication is I2C at the moment, but the board design should allow SPI and CAN. I guess you're right about C and USB stacks. By the way my dashboard is slavery connected to a I2CMaster/USB converter. At this moment it is third party hardware, but we may decide once the dashboard is done to implement our own. I favor a chip, which is from Cypress because it can do dynamic firmware loading. It's 8051 like. but up to now I didn't understand how to write for such a chip. For PIC I learned it on my own from scratch. I'm afraid with Cypress I going to give me more that headache if ever I go there. My third party solution doesn't support UART which would allow me to flash my PICs. So I have no solution for the moment, only plans ...
See you.
 
Last edited:
Apologies for the late reply... I recieved an email saying someone had replied to this thread, turns out it was just a board message sent 7 days late :)

Anyways, it directed me to your previous post regarding 'fried IO pins'.

This can be a danger when using bidirectional ports that are connected directly. In the case of your LCD module, you can write AND read the modules internal registers. So, if set to 'read', the modules data lines (D7..D0) become outputs, probably very low drive, but they are jstu meant for logic inputs. Your microcontroller/processor would set its IO's to inputs, in order to read what the module is outputing.

As your IO pins can be controlled by your software, a mistake could mean both your uC's IO's, and the LCD's datalines are outputs at the same time. If one tries to drive a line high, and the other tries to drive it low, you have 5v between two pins - with the only resistance in between being a PCB connection, or perhaps a ribbon cable. Either way the resistance is probably < 1ohm. I = V/R, current able to flow through one pin, to another is the voltage difference between them, divided by the resistance of the connection. For 5V, and R = 1. I = 5 amps. This is 5000mA, which you on board power supply, probably can't do but... it only takes about 30mA to blow the internal transistors driving an output pin. It is like an output IO which is driven to 5V....connected directly to 0V.

That was a rather long winded explaination but there is a very simple precaution: series resistors. These are still used today in commercial products as a 'just incase', and IMO, are mandatory in prototyping... since our hardware or software hasn't been proven, and it can be expensive to replace. In the case of your LCD module the only lines that are bidirecitonal are the data lines. That is D7 to D0. Connect these to your microcontroller with resistors, say 100ohm to 470ohm.

So, on the off-chance you happen to make an error, and both LCD and uC are set to output, there is some current limiting between them. The lower limit of the resistance is down to how much your LCD/uC pins can drive, for precaution we'll say 20mA. V=IR, R = V/I so R = 5/0.02 = 250ohms. 220 ohms is a standard, any lower value and too much current *could* flow. There is one caveat, series resistors slow down your rise/fall times, as they form low-pass filters when coupled with the inherent capacitance of PCB connections. I won't go into numbers, because its all VERY small, and usually only something one cares about when designing >100Mhz RF, or high speed datacomms, but it DOES round off nice sharp edges in digital signals, even slow ones at a few kHz. So, ultimately? I would prototype with say 470ohm's. At least for initial testing. You can always slow down the speed at which you write/read from the display (using delays?)... then speed it up once you have it working. It could be the series resistors slow the rise/fall times enough to corrupt data on the datalines (like flipping a bit in a byte) buty I doubt it. And by then you should be confident enough that your software isn't setting the uC's pins as outputs at the same time as the display, and so you can remove the resistors.

Pseudo code for what I use with a 'similar' display (ie: one that I need to write AND read from):
write:
<set LCD to write>
<set uC data 7-0>
<wait 5us>
<strobe in data to LCD>

read:
<set uC's IO's as INPUT's>
<wait 10us> (to make sure we're definiately not outputing anything)
<set LCD to read> (this makes the LCD modules D7-D0 lines outputs.
<strobe to get data from LCD> (sets a pin on the LCD to make it give up its data)
<uC read data> (get it, and store it in memory)
<set LCD to write> (make sure the LCD sets its IO's back to inputs)
<wait 10us> (wait a bit to make sure)
<set uC's IO's to output> (our IO's are back to outputs again, ready for the next write)

Sorry if that was obvious to you, but the little delays can be lowered once you're confident its all good, all they are there for is to make sure there is no overlap between setting outputs.

All the best,

Blueteeth
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top