Help needed with I2C LCD + Arduino - DS-LCDD5 - Page 1
Forum section: electronics / beginners

author: jdev99
author_rank: Regular Contributor
timestamp: October 25, 2021, 10:56:11 am
content: I found a couple of these modules (a PIC18 daughter board on the back of a common 16x2 LCD)It says in the datasheet that it can be controlled via I2C, but my skill level is too low to figure out how to do it.Can somebody please give me advice on how to proceed?The "I2C Scanner" sketch finds it, but the usual I2C-LCD libraries don't work on it.Thank you.

author: LateLesley
author_rank: Frequent Contributor
timestamp: October 25, 2021, 11:36:58 am
content: HI,Where you might be having difficulty with the standard libraries, is in the adressing of the display.Most 16x2 displays have an address 0x27, and can be changed all the way down to 0x20.But according to the manual on your display, the address is 0x28 - so you could need to check the sketches adresses are defined properly.so where you would normally seeCode:LiquidCrystal_I2C lcd(0x27, 16, 2);you would need to set the line up asCode:LiquidCrystal_I2C lcd(0x28, 16, 2);You can try going through this article here -https://create.arduino.cc/projecthub/akshayjoseph666/interface-i2c-16x2-lcd-with-arduino-uno-just-4-wires-273b24But keep in mind to use the correct address for your display. Hopefully that will get you a bit further forward. I'm not sure the LiquidCrystal library will have the right codes to control that display. If not, you might have to set up I2C manually, and then send the codes directly to the display, as detailed the display manual on page 3/4.I hope that helps.Oh, and if you send characters to the display, and see nothing, check the contrast. It might be worth setting the display up to flash the cursor, then set the contrast, just to make sure it is displaying something.You should be able to do that with the LCD Control Commands on page 4

author: jdev99
author_rank: Regular Contributor
timestamp: October 25, 2021, 11:57:06 am
content: Quote from: LateLesley on October 25, 2021, 11:36:58 amThank you for the quick reply. The "I2C scanner" did actually identify this module at address 0x14, which I then used in a test sketch. I think the problem is , as you mentioned, this module requires it's own way of addressing, that's why the usual libraries don't work. They mention how to do it on page 3 and 4, but that is where I get stuck, too complicated for me.I will 1st have to learn more about the programming side it seems.

author: DrG
author_rank: Super Contributor
timestamp: October 25, 2021, 12:39:40 pm
content: You have not said what you are attaching it to - Arduino UNO, PIC, ? EDIT: I see the title says Arduino - is that an UNO? Is it a 5v Arduino?http://www.i-lcd.com/PDFs/Drivers/Technical%20data%20on%20DS-LCDD5%20Interface%20Module%20(IDS).pdfTake a look at this data sheet which has examples of both RS232-type serial and I2C (this may be for an earlier version). You will NOT be able to use "standard" Arduino libraries as they are not intended for this module.Start with making sure that you have the correct connections (power, GND, etc). You will need pullup resistors on the I2C.The good news is that once you get things connected correctly, it is very easy to use...again, look at the document in the link and consider the examples and first make sure you have the connections correct. A picture and more info would make it easier to help you.

author: LateLesley
author_rank: Frequent Contributor
timestamp: October 25, 2021, 02:10:11 pm
content: Quote from: jdev99 on October 25, 2021, 11:57:06 amWell, the documentation is quite good. You can basically send the bytes directly.You can do this with the Wire.h library, and just send each byte in order, as specified in the display manual.Two links to help -https://www.arduino.cc/en/reference/wirehttps://www.arduino.cc/en/Tutorial/LibraryExamples/MasterWriterIn the second link, you are only concerned with the master side, and making sure you send to the correct address.Also make sure you are using the correct pins for SCL and SDA on the arduino.I'd try sending to 0x14 first, since that's what the i2c scan found. failing that, you can try it on 0x28. And just use the wire.write command to send each byte in order, as detailed in the display's manual. Also make sure you are using the correct pins for SCL and SDA on the arduino.Try that, and see how you get on.

author: jdev99
author_rank: Regular Contributor
timestamp: October 25, 2021, 04:12:13 pm
content: I must be missing something basic, this is my setup and code:Arduino UNO, SDA(A4), SCL(A5), 10k pullup resistors on each.As mentioned before, the "I2C scanner" sketch , detects the module at 0x14, and according to the data sheet the address becomes 0x28 when writing to the module, if I understand correct.Any other advice?Code:/*I2C scanner. Scanning ...Found address: 20 (0x14)Done.Found 1 device(s).Example: (from data sheet)To write ‘Hello’ to the display:Byte 1 - 00101000 binary , 28 hex // I2C addressByte 2 - 00000000 binary , 00 hex // Register addressByte 3 - ‘H’ ASCIIByte 4 - ‘e’ ASCIIByte 5 - ‘l’ ASCIIByte 6 - ‘l’ ASCIIByte 7 - ‘o’ ASCII*///************************************************//// Include Arduino Wire library for I2C#include <Wire.h>// Define Slave I2C Address#define SLAVE_ADDR 0x14 // 7bit address = 0010100D, 0x14 hexvoid setup () {Wire.begin(); // Initialize I2C communications as Master}void loop () {// Write something to the SlaveWire.beginTransmission(0x14); // 0x14 (SLAVE_ADDR) 0010100Wire.write(0x28); // (7bit SLAVE_ADDR + another 0 at LSB to enable write = 0x28 00101000Wire.write(0x00); // Register address "0"Wire.write("1"); // some textWire.endTransmission();delay(500);}

author: DrG
author_rank: Super Contributor
timestamp: October 25, 2021, 04:40:01 pm
content: Before you jump to I2C, I would encourage you to do the following....This is how I would approach getting your boards with the display working.First I would determine the board that I have. Is it exactly the one shown in the data sheet that you posted or is it more like the one that is shown in the data sheet that I linked? Can you not take a picture of the board and show it to us?Next, I would determine which Arduino I was using. There are many of them and some work on 3.3v and some work on 5v. You need to know which you have because if it is a 3.3v Arduino, there are other things you need to consider.For the sake of argument, I will ‘guess’ it is a 5v board, like an UNO and the board+display you have is one of the two seen in the datasheets.First I would want to determine if the display is ‘alive’. To do this I would connect +5v and GND to the connectors on the board marked +5v and GND, respectively. If you have a 5V UNO, you have these connections available. Do not connect anything else to the Arduino or your board. Now, power up the Arduino and look at the display.Find that little contrast adjustment on your board. Using a tiny screw driver (plastic one if you have one) turn that little potentiometer all the way to the left and then all the way to the right. If the board and display are alive, you should see bright rectangles on the display where the characters will later be seen at one of the extremes. Assuming, that you do, adjust the potentiometer to where you can just see the white rectangles.The easiest test at this point is to connect SI (labelled on your board) to +5V. Then see if you get a version number on the display. If you got this far ok, but don’t see a message on the display, don’t worry about it as they may have taken that out in a later version.If you got this far and all is well, then you need to figure out a couple of things. First, you will never get an Arduino library like the one that you were trying to use to work because they are not designed for your board. In fact, the purpose of the library is, in a very real sense, already present on the firmware on your board. Basically, it has its own library on board. It looks pretty clear that you can use either ttl-rs232 serial (which you can use the Arduino for) or I2C, (which you can also use the Arduino for).But, jumping into I2C; not showing us any pictures of the board, not identifying the Arduino, not using pull-up resistors on the I2C lines and not making any attempt to verify that the board and the display are working first, all make it harder for us to help you.

author: jdev99
author_rank: Regular Contributor
timestamp: October 25, 2021, 04:48:25 pm
content: Should have mentioned, I got it working 100% with the 1 wire serial method they describe, but now want to see how it works with I2C, but their examples don't work the way I understand.

author: DrG
author_rank: Super Contributor
timestamp: October 25, 2021, 04:55:11 pm
content: Quote from: jdev99 on October 25, 2021, 04:48:25 pmOk, good and YES, that goes a long way in understanding where you are at. So, are you sure that you have the 10K pull-up resistors installed correctly on the I2C lines (remember, I have no idea how experienced you are). I would have used 1.8K or 2.2K but, let's go with your 10K unless you have the others handy.With everything powered up, Re-run the I2C scanner and verify what it reports.

author: DrG
author_rank: Super Contributor
timestamp: October 25, 2021, 05:08:16 pm
content: Assuming the same results, run this code and see if "Hello" appears on the display.void setup () {Wire.begin(); // Initialize I2C communications as Master}void loop () {// Write something to the SlaveWire.beginTransmission(0x28); // left shift reported address 0x14 (SLAVE_ADDR) 0010100Wire.write(0x28);Wire.write(0x00);edit: oops skip these linesWire.write("Hello"); // some textWire.write(0);Wire.endTransmission();while(1);edit; also, you probably don't need that last wire.write(0) as I think that the string is already null terminated.

author: jdev99
author_rank: Regular Contributor
timestamp: October 25, 2021, 07:15:59 pm
content: I replaced the 10k pullups with 1k8 resistors.I2C scanner still reports address 0x14.Changes to the code made no difference.Looking at this example on page 4 of the pdf you linked:Code:/*The following code can be used onthe OOPic (II) to write ‘Hello’ to the display:Dim LCD As New oi2c*/Sub Main ()'Set the LCDD2 I2C address shifted right by 1 bitLCD.Node = &h14 'Device addressLCD.Width = cv8bit 'Control Info is 1-byteLCD.Mode = cv10bit 'I2C mode is 10-BitLCD.NoInc = cvTrue 'No incrementLCD.Location = 0 ‘Point to register R0LCD = &h48 'Write ‘H’LCD = &h65 'Write ‘e’LCD = &h6C 'Write ‘l’LCD = &h6C 'Write ‘l’LCD = &h6F 'Write ‘o’End SubIt seems like they do use 0x14 as the device address and 1 bit for control info, making up 0x28 - maybe??

author: DrG
author_rank: Super Contributor
timestamp: October 25, 2021, 07:29:30 pm
content: Try this.....void setup () {Wire.begin(); // Initialize I2C communications as Master}void loop () {// Write something to the SlaveWire.beginTransmission(0x28); // left shift reported address 0x14 (SLAVE_ADDR) 0010100Wire.write(0x00);Wire.write("Hello"); // some textWire.endTransmission();while(1);I think you need to point to the register first, hence the first write of 0Do a clean power up before you try and make sure you have SDA and SCL connected correctly and the GNDIf that does not work, try it with Wire.beginTransmission(0x14);...and which of the two boards - green or red do you have?

author: DrG
author_rank: Super Contributor
timestamp: October 25, 2021, 07:36:41 pm
content: Quote from: jdev99 on October 25, 2021, 07:15:59 pmI went to 0x28 from 0x14 because I think they are using 8 bit addressing and the scanner is reporting the 7 bit address. It may be using 10 bit. Seehttps://www.totalphase.com/support/articles/200349176-7-bit-8-bit-and-10-bit-I2C-Slave-Addressing#10bit,for example.The LSB is 0/1 for W/R but the wire library knows about that.You are close, but again, which board do you have?

author: jdev99
author_rank: Regular Contributor
timestamp: October 25, 2021, 09:53:21 pm
content: No, still not working.I noticed that they say in the manual that the serial baud rate must be1200-9600bps57600bpsHow do I set it in this case, or does it not matter with I2C?

author: DrG
author_rank: Super Contributor
timestamp: October 25, 2021, 10:03:31 pm
content: Quote from: jdev99 on October 25, 2021, 09:53:21 pmDo you mind saying which board you have?

author: jdev99
author_rank: Regular Contributor
timestamp: October 25, 2021, 10:06:30 pm
content: I use an Arduino UNO R3.

author: DrG
author_rank: Super Contributor
timestamp: October 25, 2021, 10:11:26 pm
content: Quote from: jdev99 on October 25, 2021, 10:06:30 pmI got that. I mean the display board....which one do you have...is it red and just like the one shown in the datasheet that you attached, or is it green, like the one in the datasheet that I linked?

author: jdev99
author_rank: Regular Contributor
timestamp: October 25, 2021, 10:29:31 pm
content: Sorry, the Red board, exactly like the one from my data sheet.

author: DrG
author_rank: Super Contributor
timestamp: October 25, 2021, 10:43:12 pm
content: Quote from: jdev99 on October 25, 2021, 10:29:31 pmOK, let's try this: Using the example from the red board data sheet...To write the character ‘A’ to position 6 ofline 1 on a 16 x 2 type display:Byte 1 - 00101000binary, 28hexByte 2 - 00000001binary, 01hexByte 3 - 134decimal, 86hexByte 1 - 00101000binary, 28hexByte 2 - 00000000binary, 00hexByte 3 - ‘A’ASCIIvoid setup () {Wire.begin();}void loop () {Wire.beginTransmission(0x28); // left shift reported address 0x14 (SLAVE_ADDR) 0010100Wire.write(0x01); // R1 register selectWire.write(0x86); // set cursor at the first positionWire.endTransmission(); // send the data and a stopdelay(100);Wire.beginTransmission(0x28); // left shift reported address 0x14 (SLAVE_ADDR) 0010100Wire.write(0x0); // R0 register commandWire.write(0x41); // ascii code for 'A'Wire.endTransmission(); // send the data and a stopwhile(1);}Try and run this code and see if you can get an 'A' on the screen. It is possible that the other code worked but was writing to a non-visible area of display RAM - maybe it doesn't initialize the way I would think.If it does not work, try again using 0x14, i.e., Wire.beginTransmission(0x14);There should not be a speed problem as the datasheet says the max I2C speed is 400kHz and your Arduino defaults to 100 kHz.If you had a scope, it would help because we could look for ACKs

author: jdev99
author_rank: Regular Contributor
timestamp: October 26, 2021, 01:29:38 pm
content: Thank you for all advice and efforts so far, will try it again later.QuoteMan, I think this covid messed up my head and memory. I do have a Rigol DS1104Z with all options installed, completely forgot about it.Thanks for the reminder.Am a bit under the weather today, got a flu from somewhere, will look at it hopefully tomorrow again.Joe

author: DrG
author_rank: Super Contributor
timestamp: October 26, 2021, 03:22:20 pm
content: Quote from: jdev99 on October 26, 2021, 01:29:38 pmThat's understandable and I hope that you feel better.I have been following your thread on the Arduino forum and I think you are getting pretty much the same approach - although always with 0x14.The thinking behind that code that I last included is that the module does not do a 'normal' initialization which would leave the cursor at a visible location in RAM (i.e., the first position) so that writing a character to R0 results in the character being visible on the screen. This is far-fetched but not so far-fetched as you might think because the board can accept multiple kinds of displays, i.e., 16x2, 20x2, 20x4 or 40x2. Still, a reach. I hope you will give it a try.Other examples, using 0x14, should have worked and I noticed that trying one (from the other forum) using simple backlight control is also a good idea.I think that putting a scope or a logic analyzer will quickly answer whether the address is responsive. It must be, because the scanner picked it up, but maybe something is way off.That nobody can find an Arduino example is a bit odd.The earlier version (the green board) gives instructions on how to change the I2C address, which is stored in NVM. It is possible that all the attempts actually did that inadvertently, but again, I assume that you re-ran the scanner. I wonder what else is stored in NVM and whether inadvertent corruption could be a problem.I can't see anything obvious in the way of a jumper or an enable.There is a sneaky suspicion that something silly is going on (like not getting the SDA/SCL connections right, but again, the scanner did something) and that is why I had hoped a nice pic would have been included (many eyes can be helpful). I assume that you have nothing else attached to the UNO for all of these tests.Bottom line for me is that I don't know why what should have worked, did not work, especially since you said that you have been able to get it to work with the ttl-rs232.I will keep thinking about it and let you know if I come up with something. In any event I hope that you will get it solved and will report back the how and why.

author: jdev99
author_rank: Regular Contributor
timestamp: October 27, 2021, 10:42:33 am
content: So, after I "remembered" that I have an oscilloscope, I hooked it up and noticed that I don't receive an "acknowledge" from the module.Then I played around with the clock speed, and found I do get an "acknowledge" if I set it between 16000kHz and 18000kHz with the "Wire.setClock" command.Then by mere coincidence, I found that text must got to R1 NOT R0 and control commands to R2 NOT R1.But I could not get any of the RGB commands to work.I tried this on all 6 of the modules which I have, same results.I will just stick to serial comms when I need to use any of these.So, either the datasheet is wrong or the firmware in the module is flawed.At least I learned a lot about the workings of I2C in the process, which my goal was.Thank you for all advice.JoeWorking example code:Code:// Include Arduino Wire library for I2C#include <Wire.h>// Define Slave I2C Address#define SLAVE_ADDR 0x14 // 7bit address = 0010100D, 0x14hvoid setup () {Wire.begin(); // Initialize I2C communications as MasterWire.setClock(16000); // only 16000 - 18000 work//Clear displayWire.beginTransmission(0x14);Wire.write(0x02);Wire.write(0x01);Wire.endTransmission();}void loop () {//Start print on line1, pos1Wire.beginTransmission(0x14);Wire.write(0x02);Wire.write(128);Wire.endTransmission();// Write something to the SlaveWire.beginTransmission(0x14); // 0x14 (SLAVE_ADDR) 0010100Wire.write(0x01); // Register address "0"Wire.write("ABCDEFGHIJKLMNOP"); // some textWire.endTransmission();delay(3000);//Clear displayWire.beginTransmission(0x14);Wire.write(0x02);Wire.write(0x01);Wire.endTransmission();//Start print on line2, pos1Wire.beginTransmission(0x14);Wire.write(0x02);Wire.write(192);Wire.endTransmission();// Write something to the SlaveWire.beginTransmission(0x14);Wire.write(0x01);Wire.write("1234567890-=+*/@");Wire.endTransmission();delay(3000);//Clear displayWire.beginTransmission(0x14);Wire.write(0x02);Wire.write(0x01);Wire.endTransmission();}

author: HB9EVI
author_rank: Frequent Contributor
timestamp: October 27, 2021, 11:26:30 am
content: just for interest: what chip do you have on your i2c backpack?

author: DrG
author_rank: Super Contributor
timestamp: October 27, 2021, 01:19:31 pm
content: Quote from: jdev99 on October 27, 2021, 10:42:33 amGood deal that you got some answers.*very* surprising about the I2C speed needing to be in that small band (within limitations of wire set speed) - suspiciously surprisingDid the wave forms still look squared at 100Khz? Different pullup value needed? That is weird and goes against what I thought was the resilience of I2C and speeds.The R1 not R0 is pretty darn near silly. Thing is, that PIC chip can be programmed - it is meant to be accessed through that six pad interface on the board, so who knows if something strange was done to the batch that you have or ??The important thing is that you got it figured out - good deal.

author: jdev99
author_rank: Regular Contributor
timestamp: October 27, 2021, 02:14:04 pm
content: I tried various pullups from 10k to 1k8, made no difference.Above 4k7 the wave shape started to round at the top, but with the 1k8, nice and square.Attached is a screen capture with 1k8, not the best resolution.It shows the I2C address "0x14", the 1st write to "0x00" and the symbol "A" (0x41) and then ? means "no acknowledge".

author: jdev99
author_rank: Regular Contributor
timestamp: October 27, 2021, 02:17:28 pm
content: Quote from: HB9EVI on October 27, 2021, 11:26:30 amIt is a PIC18F13K22. Should definitely handle 100kHz I2C.

author: DrG
author_rank: Super Contributor
timestamp: October 27, 2021, 02:41:16 pm
content: Quote from: jdev99 on October 27, 2021, 02:17:28 pmThat's the part that is no fair. The data sheet that you posted lists the max I2C speed at 400kHz and no minimum. I have used chips that told you that 50kHz was the max I2C speed (even 10kHz during initialization), but telling you it's good to go at 400kHz and then...... no fair.BTW: I wonder why the scanner found it - does that one use a variety of I2C speeds?

author: HB9EVI
author_rank: Frequent Contributor
timestamp: October 27, 2021, 03:07:19 pm
content: hm, a PIC on that place I didn't meet yet; more chips like PCF8574A; strange

author: jdev99
author_rank: Regular Contributor
timestamp: October 27, 2021, 05:10:52 pm
content: Quote from: HB9EVI on October 27, 2021, 03:07:19 pmYes, those PCF8574A are the usual ones, this one was made by a UK company, Designer Systems . The data sheet is with my 1st post.