Newhaven 20x2 Char LCD: How to set char position? - Page 1
Forum section: electronics / beginners

author: king.oslo
author_rank: Frequent Contributor
timestamp: July 11, 2012, 01:34:07 am
content: Hello there,This is the display:http://www.newhavendisplay.com/nhdc0220bizfsrgbfbw3vm-p-2411.html?zenid=ddohrg6ghk2v2uhpgqqef59o53This is my code:Code:// setup displayi2c_start();i2c_write(0b01111000); // slave addressi2c_write(0b00000000); // control byte (I think)i2c_write(0b00111000); //(0x38); // func set?i2c_write(0b00111001); //(0x39); // func set?i2c_write(0b00010100); //(0x14); // bias set?i2c_write(0b01110100); //(0x78); // contrast seti2c_write(0b01011110); //(0x5E); // Power/ICON Control/ Contrast seti2c_write(0b01101101); //(0x6D); // Follower controli2c_write(0b00001100); //(0x0C); // Display oni2c_write(0b00000001); //(0x01); // Clear displayi2c_write(0b00000110); //(0x06); // Entry mode seti2c_stop();// Send my first name (Marius) to display. I want first letter: "M" at char position 7.i2c_start();i2c_write(0b01111000); // slave addressi2c_write(0b10000000); // control bytei2c_write(0b10000110); // data byte -- Position (This must be incorrect)i2c_write(0b01000000); // control bytei2c_write(0b01001101); // Letter "M"i2c_write(0b01100001); // Letter "a"i2c_write(0b01110010); // Letter "r"i2c_write(0b01101001); // Letter "i"i2c_write(0b01110101); // Letter "u"i2c_write(0b01110011); // Letter "s"The reason I insist that this is wrong is because only the two last letters are displayed on the edge of the display. Please see the attached photograph.What is wrong with my code for positioning on the display?Thanks.Kind regards,Marius

author: amspire
author_rank: Super Contributor
timestamp: July 11, 2012, 02:01:12 am
content: Quote from: king.oslo on July 11, 2012, 01:34:07 amDo the display specs specify delays after some commands like the Clear command and the cursor positioning commands?

author: mariush
author_rank: Super Contributor
timestamp: July 11, 2012, 02:03:07 am
content: Here's the datasheet for a lcd screen that's almost identical to yours:http://www.newhavendisplay.com/specs/NHD-C0220BiZ-FSW-FBW-3V3M.pdfDifference is only the backlight, the above is not RGB.Both yours and this one uses ST7036 as specified in the datasheet, here's the datasheet for that chip:http://www.newhavendisplay.com/app_notes/ST7036.pdfThe documentation says there should be some delays at some points in the initialization - from experience, these matter at least with the parallel driver lcd screens.There's also some code there which may help.Otherwise, not really sure why you only see those letters - my first thought was that you forgot to send a byte and the controller reads the "M" as the "jump to position" control word...I know, not much help, I didn't have to work with i2c yet and i'm too tired to research (5 am here)ps. Yeah, had a second look... depending on the oscillator used on the lcd board, the clear display and return home commands need up to 1 ms to be processed, the others neeed about 26 microseconds. If you push those out on i2c running fast, some commands may be ignored due to the lcd being busy.See page 25 from the ST7036 manualAlso page 36 :Quote

author: king.oslo
author_rank: Frequent Contributor
timestamp: July 11, 2012, 02:36:17 pm
content: Good to see your replies guys. (Off topic: Richard, I am still working on that voltage reference. It is taking a long time, like anything I do. I hope you have patience and is not disappointed in my slow development speed)Delays certainly helped, but it still doesnt work.Oscillator is 10MHz. I2C clock is 100KHz.This is my updated code:Code:1000ms power-on delay.i2c_start();i2c_write(0b01111000); // addressi2c_write(0b00000000);for (int x = 0; x < 10; x++);i2c_write(0x00111000); //(0x38); // func set?for (int x = 0; x < 10; x++);i2c_write(0b00111001); //(0x39); // func set?for (int x = 0; x < 10; x++);i2c_write(0b00010100); //(0x14); // bias set?for (int x = 0; x < 10; x++);i2c_write(0b01110000); //(0x78); // contrast setfor (int x = 0; x < 10; x++);i2c_write(0b01011110); //(0x5E); // Power/ICON Control/ Contrast setfor (int x = 0; x < 10; x++);i2c_write(0b01101101); //(0x6D); // Follower controlfor (int x = 0; x < 2500; x++);i2c_write(0b00001100); //(0x0C); // Display onfor (int x = 0; x < 10; x++);i2c_write(0b00000001); //(0x01); // Clear displayfor (int x = 0; x < 2500; x++);i2c_write(0b00000110); //(0x06); // Entry mode setfor (int x = 0; x < 10; x++);i2c_stop();i2c_start();i2c_write(0b01111000); // addressfor (int x = 0; x < 10; x++);i2c_write(0b10000000); // control bytefor (int x = 0; x < 10; x++);i2c_write(0b10000111); // data byte – POSITION character #8. This still doesnt workfor (int x = 0; x < 10; x++);i2c_write(0b01000000); // control bytefor (int x = 0; x < 10; x++);i2c_write(0b01001101); // data byte Mfor (int x = 0; x < 10; x++);i2c_write(0b01100001); // data byte afor (int x = 0; x < 10; x++);i2c_write(0b01110010); // data byte rfor (int x = 0; x < 10; x++);i2c_write(0b01101001); // data byte ifor (int x = 0; x < 10; x++);i2c_write(0b01110101); // data byte ufor (int x = 0; x < 10; x++);i2c_write(0b01110011); // data byte sfor (int x = 0; x < 10; x++);i2c_stop();It still doesnt work. It displays my name now, but it starts at position 1, not position 8.What are your thoughts?Kind regards,Marius

author: king.oslo
author_rank: Frequent Contributor
timestamp: July 11, 2012, 04:19:23 pm
content: Update:Please look at the clock line. I noticed these narrow columns on which occur every once in a while. They do not look like ordinary clock cycles. It seems they happen more frequently when the SDA-line is low. Could they potentially be causing the problems I am having?Thank you for your time.Kind regards,Marius

author: jahonen
author_rank: Super Contributor
timestamp: July 11, 2012, 04:39:05 pm
content: Those narrow glitches might be a slave device doing a clock stretch operation (holding scl low), are you sure that your i2c master supports it?Regards,Janne

author: king.oslo
author_rank: Frequent Contributor
timestamp: July 11, 2012, 06:15:01 pm
content: Problem fixed. This is the fixed code. I wrote 0x10101010, not 0b10101010.Second I learnt that I could only let one data byte follow Co = 1 in the control byte.Clock looks fine now. This is my final codeCode:i2c_start();i2c_write(0b01111000); // slave addressfor (int x = 0; x < 10; x++);i2c_write(0b10000000); // control bytefor (int x = 0; x < 10; x++);i2c_write(0b10000111); // data byte -- POSITIONfor (int x = 0; x < 10; x++);i2c_write(0b01000000); // control bytefor (int x = 0; x < 10; x++);i2c_write(0b01001101); // data byte Mfor (int x = 0; x < 10; x++);i2c_write(0b01100001); // data byte afor (int x = 0; x < 10; x++);i2c_write(0b01110010); // data byte rfor (int x = 0; x < 10; x++);i2c_write(0b01101001); // data byte ifor (int x = 0; x < 10; x++);i2c_write(0b01110101); // data byte ufor (int x = 0; x < 10; x++);i2c_write(0b01110011); // data byte sfor (int x = 0; x < 10; x++);i2c_stop();i2c_start();i2c_write(0b01111000); // slave addressfor (int x = 0; x < 10; x++);i2c_write(0b10000000); // control bytefor (int x = 0; x < 10; x++);i2c_write(0b11000101); // data byte -- POSITIONfor (int x = 0; x < 10; x++);i2c_write(0b01000000); // control bytefor (int x = 0; x < 10; x++);i2c_write(0b01110100); // data byte tfor (int x = 0; x < 10; x++);i2c_write(0b01101000); // data byte hfor (int x = 0; x < 10; x++);i2c_write(0b01100001); // data byte afor (int x = 0; x < 10; x++);i2c_write(0b01101110); // data byte nfor (int x = 0; x < 10; x++);i2c_write(0b01101011); // data byte kfor (int x = 0; x < 10; x++);i2c_write(0b01110011); // data byte sfor (int x = 0; x < 10; x++);i2c_write(0b00000000); // data byte _for (int x = 0; x < 10; x++);i2c_write(0b01111001); // data byte yfor (int x = 0; x < 10; x++);i2c_write(0b01101111); // data byte ofor (int x = 0; x < 10; x++);i2c_write(0b01110101); // data byte ufor (int x = 0; x < 10; x++);i2c_write(0b00101110); // data byte .for (int x = 0; x < 10; x++);i2c_stop();

author: markus_b
author_rank: Regular Contributor
timestamp: July 11, 2012, 11:57:46 pm
content: Quote from: king.oslo on July 11, 2012, 06:15:01 pmJust one remark about your delay loops. About any decent c compiler will optimize this loop away as soon as you allow it to use some optimization. You should use some optimization to conserve program space and to improve speed.But your compiler/library should provide a set of calibrated delay routines to help you. I'm using avr-gcc and its avr-libc provides the _delay_ms(<milliseconds>) and _delay_us(<microseconds>) routines for this purpose. These routines are calibrated and reasonably precise.