SOLVED: How to wire an mjkdz I2C board to a 20 x 4 LCD

Sometimes cheap is fine :wink:

There are two versions (at least) of the mjkdz board. The one you have is the 22 turn trimmer and has address 0x20 by default. The other one has a single turn pot and is 0x27 by default. I have both and have worked through connection issues just like you.

First, download the New Liquid Crystal library - https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

Make sure you remove the existing standard LiquidCrystal and LiquidCrystal_I2C libraries. Don't just rename them, you have to remove them from the 'libraries' folder completely or there will be a conflict.

If your LCD connections are (Left to Right) - VSS, VDD, VO, RS, RW, E, D0, D1, D2, D3, D4, D5, D6, D7, A (or LED+), K (or LED-) then the connection goes to the following bits on the I2C chip

RS - 6
RW - 5
E - 4
D4 - 0
D5 - 1
D6 - 2
D7 - 3
Backlight - 7

This makes your constructor 4,5,6,0,1,2,3,7 so use the following example sketch:-

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define lcdAddr 0x20 // set the address of the I2C device the LCD is connected to

// create an lcd instance with correct constructor for how the lcd is wired to the I2C chip
LiquidCrystal_I2C lcd(lcdAdrr, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE); // addr, EN, RW, RS, D4, D5, D6, D7, Backlight, POLARITY

// Creat a set of new characters
const uint8_t charBitmap[][8] = {
   { 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 },
   { 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 },
   { 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 },
   { 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 },
   { 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 },
   { 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 },
   { 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 },
   { 0x0, 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0x0 }
   
};

void setup()
{
   int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));

  lcd.begin(20,4);  // initialize the lcd as 20x4 (16,2 for 16x2)
  
  lcd.setBacklight(1); // switch on the backlight

  for ( int i = 0; i < charBitmapSize; i++ )
   {
      lcd.createChar ( i, (uint8_t *)charBitmap[i] );
   }

  lcd.home ();  // go home to character 0 on line 0 (1st line)
  lcd.print("Hello, ARDUINO ");  
  lcd.setCursor(0,1);  // character 0 on line 1 (2nd line)
  lcd.print (" FORUM - fm   ");
  lcd.setCursor(0,2) // character 0 on line 2 (3rd line)
  lcd.print("This is line 3");
  lcd.setCursor(0,3) // character 0 on line 3 (4th line)
  lcd.print("This is line 3");
  delay(1000);
}

void loop()
{
   lcd.clear()
   lcd.home ();
   // Do a little animation by writing to the same location
   for ( int i = 0; i < 2; i++ )
   {
      for ( int j = 0; j < 16; j++ )
      {
         lcd.print (char(random(7)));
      }
      lcd.setCursor ( 0, 1 );
   }
   delay (200);
}

I've just modified that on the fly (mine are 16x2 LCD's) so hopefully it will work straight off for you. If not then look on it as a learning exercise to fix it, now you have the example :wink:

If you have already tried the LCD then I'm assuming you checked to see if there is an onboard resistor for the backlight LED.

With those type of trimmers, I gently bend them over the opposite way, so that they part hang of the board and are accessible when the backpack is on the LCD. It's a lot easier to adjust the contrast whilst the LCD is connected and on. Just keep turning until you get characters.

creatrope:
The last thing that took me long time to figure out is that the backlit pot ....

Just a a clarification. The pot does not control the backlight or its brightness.
The backlight is fixed at a constant brightness.
The pot controls the contrast. Since contrast controls how much light is blocked by pixels,
it will appear to control the brightness of the pixels on inverted displays.
But in reality is is not affecting the backlight brightness or its power consumption.

tack:
If your LCD connections are (Left to Right) - VSS, VDD, VO, RS, RW, E, D0, D1, D2, D3, D4, D5, D6, D7, A (or LED+), K (or LED-) then the connection goes to the following bits on the I2C chip

RS - 6
RW - 5
E - 4
D4 - 0
D5 - 1
D6 - 2
D7 - 3
Backlight - 7

This makes your constructor 4,5,6,0,1,2,3,7 so use the following example sketch:-

The order of the LCD pinout connections on the LCD module has no bearing on the bit numbers used in the
lcd library constructor.
Almost all hd44780 based LCD modules will use that same 16 pin pinout -
some move things around for the A and K connections since those are
technically not part of hd44780.

When the I2c backpack is designed, the connections between the i2c chip outputs
and the LCD module are created for a fixed LCD module pinout.
All the i2c backpacks I've seen, use that standard 16 pin LCD pinout - but they all are not wired
up the same between the LCD and the PCF8574 and hence require different constructors.

The bit numbers used in the constructor is based on how the PCF8574 i2c chip's
output port is wired up to the LCD module connections.
The wiring is done in etch on the PCB.
Yes there is more than one wiring used on these types of i2c boards.
While most of the "mjkdz" ones out there seem to have wired them up the same,
the only way to really know for sure is to look at the traces on the i2c board
between the PCF8574 chip and the LCD module to see how they wired up
the PCF8574 output port bits.

farkuino,
tack's constructor bits will more than likely work for your i2c backpack.
The other thing to watch out for is the i2c address.
This is because there are several different 8574 chips used and they each have different default base addresses.
Complicating matters, the chips can be strapped for a range of addresses starting at the base address.
Different vendors strap them differently so even though the wiring may be the same and the chip
is the same, the address may be different since the chip has been strapped to not use the default address.

The best thing to do is what creatrope said, go get the i2cscanner sketch.
run it to see what i2c address is used. That way you won't be fighting an
issue due to an incorrect address.

Another thing about these i2c boards, is that they don't have the required i2c pullups on them.
(almost none of them do - not just the lower cost ones)
While they seem to work without them, pullups are required for proper operation
particularly if using more than one i2c device.

If you do a search for mjkdz you will see that there have been several threads recently about
how to set up the constructor for this type of i2c backpack that you might find useful
in trying to gain knowledge and technical expertise about these types of boards.

--- bill

As far as the LCD spin out goes, I only put that there as I've not used a 20x4 display so wasn't 100% sure they were all identical. I'd guessed they were as the backpacks work on those two, but safer to have the OP make sure. :wink:

Hopefully he'll report back if it's worked for him. I know some people can get tremely frustrated when things don't work and get the 'it's no good, I'm fed up, it's rubbish' red mist. I have a couple of mates with low patience levels like that. :stuck_out_tongue:

Thank you to everyone for your suggestions.

I have been celebrating my birthday early :grin: , but will try them out tomorrow and report.

I was looking at the photo and it seemed that the pins just lined up, but when I did that (using both an old floppy cable, and standard jumper wires), I got no backlight when I applied power to the arduino. I assumed that the pot would be a single turn jobber, not a 22 turn.....I gave it a 60 degree twist left and right (because that's all it took on the ones I bought from my local chip shop), and got nothing.

And I saw the other posts about changing the constructor, and asked wtf they would do that and not just keep one standard way of doing it. But that would take all the fun out of it, right?

And yes, sometimes I get that "it's no good, eff it, and chuck it into my toy box" attitude. But before I do that, I check with the experts.

I finally got an answer back from the seller. They sent me the docs. Too bad I don't speak Chinese.... :astonished: They promised to send me the English ones asap. I'm betting that I will have it running long before then.

Again, thanks to all, and I will report back.

farkuino:
And I saw the other posts about changing the constructor, and asked wtf they would do that and not just keep one standard way of doing it.

For this type of board there is no standard.
The standard interfaces are i2c and hd44780. What is in the middle on the PCB
to connect between the two is left up to the implementor and could be done
in many different ways.

I'm curious what is in the docs they sent you.

But you really won't need it.
It should be possible to figure out everything other than the i2c address
from carefully looking at the PCB.
It uses a PCF8574 which you can tell because it has 16 pins.
The MCP23008 (another popular i2c chip used has 18 or 20 pins depending on package)
The 8574 has a known pinout.
The PCB connects to a hd44780 LCD 16 pin interface. Also a known pinout.
You can find datasheets for the pin definitions of each of those interfaces.
The PCB is a simple two layer board which allows seeing nearly all the traces
(There may be some that dip under the PCF8574).
Usually you can see enough of the traces to figure which
pins on the PCF8574 are hooked up to which LCD pins.
If you can't, sometimes you may have to use an ohm meter to test continuity.
From that you can tell which PCF8574 output port bits are attached to the various LCD pins.

Its a good exercise into learning how to read datasheets
and examining hardware to get a true understanding of
how the board is wired up and works.

When using low cost hardware, which often comes with little to no
support or documentation, this kind of exercise is often necessary.

No better time to jump in feet first....

Here is a link to a PCF8574 datasheet:
http://www.nxp.com/documents/data_sheet/PCF8574.pdf
The pinout you are looking for is on page 5.
You need to figure out what P0 to P7 are hooked to.
That is PCF8574 pins 4,5,6,7,9,10,11,12
Those are the output port bits. How they are connected
to the hd44780 pins determines what goes in the constructor.
If P0 is connected to LCD D4 then 0 is the bit number for D4 in the
constructor.
The constructor uses output port bit numbers not PCF8574 pin numbers.
P0 is 0, P1 is 1, etc...

--- bill

tack:
As far as the LCD spin out goes, I only put that there as I've not used a 20x4 display so wasn't 100% sure they were all identical. I'd guessed they were as the backpacks work on those two, but safer to have the OP make sure. :wink:

Hopefully he'll report back if it's worked for him. I know some people can get tremely frustrated when things don't work and get the 'it's no good, I'm fed up, it's rubbish' red mist. I have a couple of mates with low patience levels like that. :stuck_out_tongue:

OMG (as the kids would say)!

I wanted to do things by the book (i have seen many posts about non-soldered LCDs, wink wink), so I ran the I2C scanner.

x20, and not x27!

I wire it up using my old floppy cable, and the frickin' backlight comes on!

I download the new I2C files and copy it to my library, copy tack's code, and :astonished:

tack wanted to make sure I knew how to fix code......ahahahahaha. A few ; here and there and it was ready to upload.

Mama Pajama! I could see some stirring in the LCD, so I gave the pot a few twists, and MONEY! We have a working mjkdz LCD I2C backpack!

I am now troubleshooting the fact that my "R" in "FORUM" looks like this:



instead of this:



I will mark it solved, since I can see clearly now the LCD.

Again, many thanks to all of your for your tips, expertise, and encouragement.

Glad it's sorted, but the character issue does seem odd and not right.

I think there were three missing ; for you. Had to make you do a little work to get the satisfaction....:wink:

The documentation for the Atmega chips said that SDA was at A4 and SCL was at A5. I used the i2c_scanner and a couple of LEDS and traced the signals to A0 and A1. A0 is SCL and A1 is SDA.

If you have a PCF8574 without the A on it, the physical address is set by connecting pins 1,2,3 to either VSS or VDD. They are A0,A1, and A2, in that order. Add that to 0x20 and you know the address. On my board I can see where they are connected, which is to VSS. If they are all connected to VDD you get an address of 0x27. Mine works at 0x20.

I got my adapter almost the same day that Farkuino got his, and I just got mine working about ten minutes ago. I started on Monday.

Thank you, everyone who helped, and I like that graphic that Tack wrote. I have a nice blue 16 by 2 display.

I also learned that you do have to initialize with lcd.begin(columns, rows). I had a lot of fun figuring out that there was a mistake that I could make that set my MPUs to their factory defaults, so they were running at 1MHz instead of 16, and I got to learn how to edit boards.txt.

TomKi:
I also learned that you do have to initialize with lcd.begin(columns, rows).

It depends on the library.
Some PCF8574 i2c libraries set the geometry in the constructor
and use lcd.init().

And that is what makes it a bit challenging.
There are many different PCF8574 i2c to hd44780
libraries and hardware designs out there. And they all work slightly differently.

As of today, there really is no way to offer a plug and play library solution for an i2c to hd44780 backpack
unless it all comes from the vendor.
Many vendors are not supplying a pre-configured library for their board.

I prefer to use fm's library since it can work on all of the PCF8574(A/N) based backpacks.
(including the ability to concurrently support multiple i2c boards that are wired differently)
The key to this capability is that the constructor configures the library for the hardware.
So the user must properly fill in the constructor to match his hardware.

The problem is many Arduino users don't understand the hardware details of how these
i2c to hd44780 boards work and are assuming (and expecting) that because it is i2c
that it should be "plug and play" and well.... it isn't, and there is no way to get there.

It isn't that difficult to get up and working, but it may require a bit of sleuth work
to look at the i2 board and the traces on it, to determine how the PCF8574 is wired up to the hd44780
interface to be able to properly fill in the constructor
for fm's library since many of the i2c boards come with no documentation.

--- bill

Well, in my case I finally realized that I needed to be sure that the signals were actually getting there. In the process I made a custom boards.txt entry so that I would get the fuses and the wiring variant right. I'm using an Arduino Serial Mark II board I got from Mouser.

I wanted to thank Tack as well for getting my 20x4 LCD to get running with I2C interface, i've got that library alreday but all i was getting is some weird stuff on the screen, i guess devil was hidding in the code :slight_smile:

Thanks again.

Hello everyone! I have the same MJKDZ I2C board. I also ran a I2C scanner, and the port is confirmed to be 0x20. However, I do not have a 20x4 display, I have a 1602 display that I purchased here: http://www.ebay.com/itm/170817946781?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649 Does it work in the same way as the 20x4?

I have connected it in a 1:1 manner like in the photograph of the original poster. So far, I can't get it to work with any sketches that I have tried. Since my I2C port scanner is working, I will assume that the problem is either the connection or software.

I am very new to Arduino and these types of devices, can someone please explain to me how I can get to the point of working example code, so I can do my own programming?

Hi Gordon
Not sure if you got it working by now, Yes LCD you mention is compatible
try turning back light on/off to see if Arduino is talking to I2C board OK
Make sure you adjust LCD contrast using, so far on all my LCDs the contrast trim pot is turned 99% to one end around the point where the screen shows black squares
Hope this helps

For mjkdz LCD with Arduino Leonardo:

Use de address 0x20

Use the fmalpartida library version 1.2.1, file LiquidCrystal_V1.2.1.zip from https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

Pay special attention on LiquidCrystal_I2C lcd(...) call. It must be like this: LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);

Best Regards,

Damico

The cheap "mjdkz" boards indeed use a PCF8574 which for some curious reason has the branding ground off. One might wonder why - we know it is this chip and there can hardly be too many manufacturers so that they need to conceal their sources.

If you purchase an "I2C expander" board using the PCF8574, you will pay about five times the price.

So, if you are merely looking for an I2C port expander - or two or three etc., don't bother. Just buy the "mjdkz" boards and use them instead. :slight_smile:

Hey guys i have a keypad and 20x4 lcd in the same i2c bus and everything works fine.

but the stepper motor (not 12c) when running or supplied power to the easy driver is dimming the contrast to the lcd.

I have the arduino waiting for a password from the keypad (4x4); when entered correctly the motor is triggered. this is when the contrast dims (check out the attached pictures...

any suggestions?

This has nothing to do with the original thread.
Start a new thread for this discussion.

bperrybap:

[quote author=Keith Brown link=topic=142255.msg1327790#msg1327790 date=1374674576]
Hey guys i have a keypad and 20x4 lcd in the same i2c bus and everything works fine.

but the stepper motor (not 12c) when running or supplied power to the easy driver is dimming the contrast to the lcd.

I have the arduino waiting for a password from the keypad (4x4); when entered correctly the motor is triggered. this is when the contrast dims (check out the attached pictures...

any suggestions?

This has nothing to do with the original thread.
Start a new thread for this discussion.

[/quote]

I thought I was on a different thread...too many windows open i guess.