Go Down

Topic: M2TKLIB Hello World with LiquidCrystal_I2C (Read 4751 times) previous topic - next topic

digimate

I found this data on the connections of my display

Quote
?PIN  CONNECTIONS       
Pin     Symbol   Function
1   VSS   Ground for Logic(0V)
2   VDD   Power supply for Logic(+5V)
3   V0   Power supply for LCD Driver
4   RS   H: Data?L: Instruction Code
5   R/W   H: Read;  L: Write
6   E   Enable signal
7~14   DB0~DB7   Data Bus Line
15   A   Backlight Power(+5V)
16   K   Backlight Power(0V)


and tried to write a 'constructor' as follows (based on the library code I have copied at the bottom of this post

Code: [Select]
LiquidCrystal_I2C lcd ( 0x3F, 6, 5,4 ,
                        7, 8, 9, 10,
                         15,POSITIVE);


All I am getting at the moment is the backlight turns off and nothing is displayed (although there seems to be 2 lines of faint characters (this is a 4 line display)

One thing I thought was odd is that it only has 4 data pins in the constructor, but the table above talks about 8.  I did try pins 11 to 14 instead of 7 to 10, but it doesn't seem to make any difference.

Code: [Select]
   /*!
    @method     
    @abstract   Class constructor.
    @discussion Initializes class variables and defines the I2C address of the
    LCD. The constructor does not initialize the LCD.
   
    @param      lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
    the address can be configured using the on board jumpers.
    @param      En[in] LCD En (Enable) pin connected to the IO extender module
    @param      Rw[in] LCD Rw (Read/write) pin connected to the IO extender module
    @param      Rs[in] LCD Rs (Reset) pin connected to the IO extender module
    @param      d4[in] LCD data 0 pin map on IO extender module
    @param      d5[in] LCD data 1 pin map on IO extender module
    @param      d6[in] LCD data 2 pin map on IO extender module
    @param      d7[in] LCD data 3 pin map on IO extender module
    */
   LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
                     uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7 );
   // Constructor with backlight control
   LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
                     uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
                     uint8_t backlighPin, t_backlighPol pol);

digimate

Another step forward  !      Figured out the constructor numbers are bit numbers, so I had to follow traces on the backpack board to see where the pfc8574 pins were wired to on the LCD display proper.  Then translate those to bit numbers.

For anyone else with a sainsmart LCD display with their "lcd2004" I2C adapter, the following seems to work.

Code: [Select]
LiquidCrystal_I2C lcd ( 0x3F,2,1,0, 4,5,6,7,3,POSITIVE);


olikraus

Good to see that you made some progress here. Do the m2tklib examples work?

I have selected fm's New LiquidCrystal mainly because of the large number of supported display types. It has also a nice software architecture with a common base class (class LCD). All other variants are derived from this base clase. So I was able to use the base class inside m2tk and do the testing with the 8bit parallel variant. Indeed all my testing with the New LiquidCrystal lib had been very successful, so i was hoping that also the I2C variant will work without bigger problems.

@Bill: M2tk calls the "begin()" member function of the LCD base class to init the display. I can't remember if there exists something like a "init()" member function. It turned out, that the LCD base class had the same interface as the original Arduino LiquidCrystal class. And also my tests with the 8 bit hardware setup had not revealed any issue concerning init.

Oliver



digimate

Yes, was just writing this when you posted - now the M2TKLIB Hello World example works, modified as below. Changes are to include <Wire.h>, to include <LiquidCrystal_I2C.h> instead of <LiquidCrystal.h>, and to set it up using "LiquidCrystal_I2C lcd ( 0x3F,2,1,0, 4,5,6,7,3,POSITIVE);"

Code: [Select]
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "M2tk.h"
#include "utility/m2ghnlc.h"

LiquidCrystal_I2C lcd ( 0x3F,2,1,0, 4,5,6,7,3,POSITIVE);

M2_LABEL(hello_world_label, NULL, "Hello World!");
M2tk m2(&hello_world_label, NULL, NULL, m2_gh_nlc);

void setup() {
 m2_SetNewLiquidCrystal(&lcd, 16, 2);
}

void loop() {
 m2.draw();
 delay(500);
}


Thanks for ALL the help !  

bperrybap


@Bill: M2tk calls the "begin()" member function of the LCD base class to init the display. I can't remember if there exists something like a "init()" member function. It turned out, that the LCD base class had the same interface as the original Arduino LiquidCrystal class. And also my tests with the 8 bit hardware setup had not revealed any issue concerning init.


I worked with fm to ensure that the library is transparently compatible with the original LiquidCrystal library.
The reason I brought up the begin()/init() issue is that there are some other i2c libraries out there (which I wouldn't recommend)
but are never the less popular and in use.
Those other i2c libraries have different constructors and specify the geometry in the constructor
and then use a call to init() to initialize them vs begin().
To me this is not smart since it makes them incompatible with the LiquidCrystal initialization.
But since it appears that your code calls the lcd initialization, it will matter to your code
if you decide to support these other i2c to hd44780 libraries.

My personal opinion, don't support those libraries and be done with it.
Just steer people to fm's library which works the same on many different interfaces.

--- bill

olikraus

Quote

I worked with fm to ensure that the library is transparently compatible with the original LiquidCrystal library.

Ah, this explains why it had been that easy to port the existing procedures to New LiquidCrystal lib.

I was requested by several users to support I2C for m2tklib character displays, but i do not plan to support any further libs. In fact, you both confirmed me that this lib is flexible enough to support several other types of hardware also.

Oliver

olikraus

Quote
now the M2TKLIB Hello World example works, modified as below.


Thanks for the feedback. Let me know if there are any questions regarding M2tklib.

Oliver

earlboatman


Yes, was just writing this when you posted - now the M2TKLIB Hello World example works, modified as below. Changes are to include <Wire.h>, to include <LiquidCrystal_I2C.h> instead of <LiquidCrystal.h>, and to set it up using "LiquidCrystal_I2C lcd ( 0x3F,2,1,0, 4,5,6,7,3,POSITIVE);"

Code: [Select]
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "M2tk.h"
#include "utility/m2ghnlc.h"

LiquidCrystal_I2C lcd ( 0x3F,2,1,0, 4,5,6,7,3,POSITIVE);

M2_LABEL(hello_world_label, NULL, "Hello World!");
M2tk m2(&hello_world_label, NULL, NULL, m2_gh_nlc);

void setup() {
 m2_SetNewLiquidCrystal(&lcd, 16, 2);
}

void loop() {
 m2.draw();
 delay(500);
}


Thanks for ALL the help !  



When I try to compile this code I get an error as follows.

Arduino: 1.5.6-r2 (Windows 7), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

Build options changed, rebuilding all

Using library Wire in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire (legacy)

Using library LiquidCrystal_I2C in folder: C:\Users\KB0NRK\Documents\Arduino\libraries\LiquidCrystal_I2C (legacy)

Using library M2tk in folder: C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk (legacy)



C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -MMD -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=156 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\mega -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire -IC:\Users\KB0NRK\Documents\Arduino\libraries\LiquidCrystal_I2C -IC:\Users\KB0NRK\Documents\Arduino\libraries\M2tk C:\Users\KB0NRK\AppData\Local\Temp\build1579395692306476180.tmp\MenuX2L.cpp -o C:\Users\KB0NRK\AppData\Local\Temp\build1579395692306476180.tmp\MenuX2L.cpp.o

In file included from MenuX2L.ino:4:
C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk/utility/m2ghnlc.h:32: error: variable or field 'm2_SetNewLiquidCrystal' declared void
C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk/utility/m2ghnlc.h:32: error: 'LCD' was not declared in this scope
C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk/utility/m2ghnlc.h:32: error: 'lc_ptr' was not declared in this scope
C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk/utility/m2ghnlc.h:32: error: expected primary-expression before 'cols'
C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk/utility/m2ghnlc.h:32: error: expected primary-expression before 'rows'
MenuX2L.ino:6: error: 'POSITIVE' was not declared in this scope
MenuX2L.ino: In function 'void setup()':
MenuX2L.ino:12: error: 'm2_SetNewLiquidCrystal' was not declared in this scope

can you help me?

bperrybap

You either have the wrong library or don't have it properly installed.
For that LiquidCrystal_I2C constructor, you need this library:
https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home

earlboatman


You either have the wrong library or don't have it properly installed.
For that LiquidCrystal_I2C constructor, you need this library:
https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home


I have LiquidCrystal_V1.2.1 installed and use it in other sketches.

If I change the above example with "LiquidCrystal_I2C lcd(0x27, 20, 4);", which works for me it highlights the following line.

m2_SetNewLiquidCrystal(&lcd, 16, 2);

And gives the error -
Arduino: 1.5.6-r2 (Windows 7), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

Build options changed, rebuilding all

Using library Wire in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire (legacy)

Using library LiquidCrystal_I2C in folder: C:\Users\KB0NRK\Documents\Arduino\libraries\LiquidCrystal_I2C (legacy)

Using library M2tk in folder: C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk (legacy)



C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -MMD -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=156 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\mega -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire -IC:\Users\KB0NRK\Documents\Arduino\libraries\LiquidCrystal_I2C -IC:\Users\KB0NRK\Documents\Arduino\libraries\M2tk C:\Users\KB0NRK\AppData\Local\Temp\build1579395692306476180.tmp\MenuX2L.cpp -o C:\Users\KB0NRK\AppData\Local\Temp\build1579395692306476180.tmp\MenuX2L.cpp.o

In file included from MenuX2L.ino:4:
C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk/utility/m2ghnlc.h:32: error: variable or field 'm2_SetNewLiquidCrystal' declared void
C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk/utility/m2ghnlc.h:32: error: 'LCD' was not declared in this scope
C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk/utility/m2ghnlc.h:32: error: 'lc_ptr' was not declared in this scope
C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk/utility/m2ghnlc.h:32: error: expected primary-expression before 'cols'
C:\Users\KB0NRK\Documents\Arduino\libraries\M2tk/utility/m2ghnlc.h:32: error: expected primary-expression before 'rows'
MenuX2L.ino: In function 'void setup()':
MenuX2L.ino:13: error: 'm2_SetNewLiquidCrystal' was not declared in this scope

As you can see I am new to this and need working codeto learn from.
Thanks Earl

bperrybap



You either have the wrong library or don't have it properly installed.
For that LiquidCrystal_I2C constructor, you need this library:
https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home


I have LiquidCrystal_V1.2.1 installed and use it in other sketches.

If I change the above example with "LiquidCrystal_I2C lcd(0x27, 20, 4);", which works for me it highlights the following line.

m2_SetNewLiquidCrystal(&lcd, 16, 2);


Due to the way the IDE has chosen to do builds,
you can't have two libraries installed that use a header file with the same file name.
If you do, it will cause problems.


LiquidCrystal_I2C.h is a library header file in both
fm's library and the LiquidCrystal_I2c library you are using
so you can only have one them installed at time.
Also, keep in mind that those two libraries don't have  the same functionality and are initialized differently.

My recommendation is to use fm's library since that one works on all the PCF8574 based backpacks.
The catch is you must properly fill in the constructor to tell it how the pins on the pcf8574 chip are
wired to the hd44780 interface on the lcd.

--- bill

earlboatman


You either have the wrong library or don't have it properly installed.
For that LiquidCrystal_I2C constructor, you need this library:
https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home


How do you use the LiquidCrystal_I2C constructor? Do I need to change the name of the library to  LiquidCrystal_I2C so it can find the header file?

bperrybap

The IDE will find the header no matter what the directory name of the library is.
It looks in all of the to  find the header file. And that is why you can't have two
libraries with the same library header file name since the IDE may find the library
header in a different library than the one you want.

In terms of using the constructor, it is used to initialize the library object
the parameters are specific to each library.
To see what they are and how to use them you must consult the documentation
for each library.
Below are constructor examples from two different libraries.
Each of these creates a library object called "lcd" for the library.

Code: [Select]
LiquidCrystal_I2C lcd(0x27, 20, 4);
Code: [Select]
LiquidCrystal_I2C lcd ( 0x3F,2,1,0, 4,5,6,7,3,POSITIVE);

Beyond the constructor, there are also initialization functions that must be called.
And those are also specific to the given library.
Here are typical examples of those functions:
Code: [Select]
lcd.init();
Code: [Select]
lcd.begin();

You must first pick which library you want to use and for these two libraries only
one can be installed at a time.
Then use the proper constructor and initialization functions for that library.

With PCF8574 based backpacks, there is no "it just works" solution for all backpacks,
since there is no standardized way to wire up the PCF8574 chip i/o pins to a HD44780 LCD.

The two libraries that you have mentioned are different.

The LiquidCrystal_I2C library will only work on some backpacks since the pin wiring is hard coded.
fm's library since will work on any PCF8574 based backpack but you have to fill in the constructor
with the proper pin mapping for your board.

I prefer fm's library since it will work on any board. But you do have get the constructor
correct to get it to work.


My suggestion at this point, is to drop back to a simpler environment to
get the LCD working before you try toss m2tklib on top of it.
i.e. do some sort of "hello world" to ensure that the LCD is configured properly.

My recommendation is to use fm's library as it is fully compatible with the standard
LiquidCrystal library.
What that means is that to change from using the 4 bit interface, all you have to do
is change the header file(s) you include, change the constructor, and it will "just work".
No changes to the actual sketch code will be needed.

If you go with the LiquidCrystal_I2C library and are luckily enough that it even works
with your backpack, you will have modify your sketch code to change the begin() call as well,
sinc the LiquidCrystal_I2C library requires using an init() function.

--- bill




earlboatman

cleaning out the libraries did i t and also using " lcd.begin(20,4);".

now I can use your menus with some of of my displays.

I also have some Akafugu TWILCD 40x2/40x4/RGB Display Controller Backpacks from http://www.akafugu.jp/posts/products/twilcd/ and want to use RGB with my project and so will half to incorporate the TWILiquidCrystal library.

thanks for your help.

Go Up