Hi,
I discovered that there are some differences is the I2C backpacks for the HD44780 displays, especially in the pins used for RS/RW/EN and Backlight.
I have some programming experience so I got mine to work by changing #define's hd44780-i2c.c to:
#define RS 0x40
#define RW 0x20
#define EN 0x10
#define BL 0x80
(RS and EN were switched)
I am not experienced enough to add code to make this configurable in LCDd.conf and submit a patch. Maybe someone else can do this? I'm willing to assist anywhere where I can for making this possible.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Looking at the layout of the backpack board attached to my lcd, it appears the connections are totally different from those depicted in the schematic. How would the hd44780-i2c driver need to be modified to work with this layout?
LCD CHIP
RS P0
RW P1
E P2
D4 P4
D5 P5
D6 P6
D7 P7
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That definitely got me closer to a working lcd. I'm now getting the welcome message when LCDd starts, and the goodbye message when it stops. Unfortunately, in between those two I am getting dark rectangles, and the occasional blink or garbage. Since the welcome and goodbye messages are displaying correctly, does that mean that everything is working right with LCDproc? Or is it still possible I've got something wrong at this level?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Disregard that previous post. I don't see any way to edit or delete it, or I would. With a couple of minor adjustments in the python and config files I was using, that modified driver is working perfectly. Thank you!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Okay, I'm still having issues with this. I can get the LCD working, displaying the expected data, but the backlight turns off. I've tried a few variations, but nothing I've tried gets the right data to show up on the screen and the backlight to stay on.
I modified the hd44780-i2c.c file based on the patch above, but had to make a couple of changes. I changed the value of BL, and of Default_Device, as shown below:
Using those, I get data to display correctly on the LCD. if I change the backlight setting in LCDd.conf to backlight=no, the backlight will still turn off, but I get only rectangles on the LCD, no data.
How can I get the display working and keep the backlight on by default?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I checked continuity between the pins of the chip and those of the lcd with a multimeter to confirm that the connections I listed in the earlier post are correct:
LCD CHIP
RS P0
RW P1
E P2
D4 P4
D5 P5
D6 P6
D7 P7
I couldn't find anything that was connected to P3, but I don't have access to the back side of the backpack board, so it may have something on the underside.
I had tried using BL=0x00, and also tried BL=0x08, and just got garbage on the display with those settings. I was surprised that setting BL to 0x80 worked, but that was the only configuration I found that actually resulted in the welcome message, and subsequent data sent from a python script, appearing on the display. Of course, when I set backlight=no in LCDd.conf with BL still set to 0x80, I no longer got data to show up on the screen. I wonder if when I had set backlight=yes, I was getting some data on the screen because whatever was trying to be sent to the backlight happened to match what was needed on that 4th bit to display a character… Probably not very likely I guess.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Looking at that schematic P3 is connected to the base of the back light transistor via signal named BT. If this is true for your board the code should be using:
#define BL 0x08
It looks like there is a bug in the back light function:
Thanks. I made the changes emteejay suggested, and after compiling and copying the new version over the old, I shut my raspberry pi down and brought it back up to try again.
I watched it boot up, and saw that the welcome message was displayed and the backlight did stay on. Wonderful! Then I enabled the autostart script that will send data to the lcd, shut it down to move it, and when it came back up, I'm getting garbage characters on the screen again. The backlight IS staying on now, but I get apparently random characters and symbols on the screen.
I tried disabling the startup script and rebooting, and even tried re-copying the new driver file over the existing, just to be sure it hadn't gotten reverted back somehow. I don't get why it would have appeared to work perfectly the first time, and then not work after that. Still, no luck. I am away from home now, so I haven't been able to spend much time troubleshooting it. I'll have to fiddle with it more tonight or tomorrow.
Thanks again for the help, both of you.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
1. The initialization routine does use i2c_out directly. Therefore just modifying i2c_HD44780_senddata was not enough.
2. The lower nibble calculation did not work as expected.
Here is a complete new version, including the backlight code.
Index: server/drivers/hd44780-i2c.c===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/server/drivers/hd44780-i2c.c,v
retrieving revision 1.14
diff -u -r1.14 hd44780-i2c.c--- server/drivers/hd44780-i2c.c 30 Oct 2010 18:04:21 -0000 1.14+++ server/drivers/hd44780-i2c.c 27 Jan 2013 14:39:31 -0000@@ -76,10 +85,10 @@
void i2c_HD44780_backlight(PrivateData *p, unsigned char state);
void i2c_HD44780_close(PrivateData *p);
-#define RS 0x10-#define RW 0x20-#define EN 0x40-#define BL 0x80+#define RS 0x01+#define RW 0x02+#define EN 0x04+#define BL 0x08
// note that the above bits are all meant for the data port of PCF8574
#define I2C_ADDR_MASK 0x7f
@@ -168,43 +214,43 @@
// powerup the lcd now
/* We'll now send 0x03 a couple of times,
* which is in fact (FUNCSET | IF_8BIT) >> 4 */
- i2c_out(p, 0x03);+ i2c_out(p, 0x30);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, enableLines | 0x03);+ i2c_out(p, enableLines | 0x30);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, 0x03);+ i2c_out(p, 0x30);
hd44780_functions->uPause(p, 15000);
- i2c_out(p, enableLines | 0x03);+ i2c_out(p, enableLines | 0x30);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, 0x03);+ i2c_out(p, 0x30);
hd44780_functions->uPause(p, 5000);
- i2c_out(p, enableLines | 0x03);+ i2c_out(p, enableLines | 0x30);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, 0x03);+ i2c_out(p, 0x30);
hd44780_functions->uPause(p, 100);
- i2c_out(p, enableLines | 0x03);+ i2c_out(p, enableLines | 0x30);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, 0x03);+ i2c_out(p, 0x30);
hd44780_functions->uPause(p, 100);
// now in 8-bit mode... set 4-bit mode
- i2c_out(p, 0x02);+ i2c_out(p, 0x20);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, enableLines | 0x02);+ i2c_out(p, enableLines | 0x20);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, 0x02);+ i2c_out(p, 0x20);
hd44780_functions->uPause(p, 100);
// Set up two-line, small character (5x8) mode
@@ -240,8 +284,8 @@
i2c_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch)
{
unsigned char enableLines = 0, portControl = 0;
- unsigned char h = (ch >> 4) & 0x0f; // high and low nibbles- unsigned char l = ch & 0x0f;+ unsigned char h = ch & 0xf0; // high and low nibbles+ unsigned char l = (ch << 4) & 0xf0;
if (flags == RS_INSTR)
portControl = 0;
@@ -277,7 +321,7 @@
*/
void i2c_HD44780_backlight(PrivateData *p, unsigned char state)
{
- p->backlight_bit = ((!p->have_backlight||state) ? 0 : BL);+ p->backlight_bit = ((p->have_backlight && state) ? BL : 0);
i2c_out(p, p->backlight_bit);
}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I see three possible ways of doing this, in order of complexity.
Have another version of the i2c module that changes the pinouts as above.
add configuration options to specify which pins the d4-d7 and the control lines correspond too.
This could be done changing the #defines to integers, with a H/L or L/H config switch that would >> 4 or << 4 the values as appropriate on init.
do any of the other drivers do this kind of thing?
define the data and control pins in the config file, defaulting to the current set up.
Which solution would be accepted into the code base
would be the easiest to implement - just unsure in what to call it?
Thanks
Rhys
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think a possibility to specifc the pins would be the most versatile solution. You can look into hd44780-rpi.c where such a think is done for the rasberry GPIO pins. I think this should look very similar for both (and more/other) drivers
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I already make a map of the i2c backpack connections, they are indentical with these described in https://github.com/wilberforce/lcdproc
except the BL pin - I was unable to track it. Any help is appreciated.
Last edit: Lalyu Lalev 2016-04-06
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That seems to be working perfectly. I've rebooted a couple of times, enabled the startup script, and I've got good data showing on the display, and the backlight is staying on. Thanks!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm attempting to connect a BV4638 I2C chip but the pin usage is different and I'll be very grateful if someone could assist me in modifying the source code please?
Possible configuration options are: off | open | on.
But in server/drivers/hd44780.c line 171 we have
p->have_backlight = drvthis->config_get_bool(drvthis->name, "backlight", 0, 0);
meaning we test for on/off only, not for open.
The result is that when open is set, the driver thinks there is no backlight and the backlight command does not work (initial backlight setting on startup works however, if patches above were applied).
I see two solutions:
1. either extend config_get_bool() - it takes a few more values already anyway
2. use another default. This will disable backlight only when explicitely "off" was specified. The diff looks like:
Hi,
I discovered that there are some differences is the I2C backpacks for the HD44780 displays, especially in the pins used for RS/RW/EN and Backlight.
I have some programming experience so I got mine to work by changing #define's hd44780-i2c.c to:
#define RS 0x40
#define RW 0x20
#define EN 0x10
#define BL 0x80
(RS and EN were switched)
I am not experienced enough to add code to make this configurable in LCDd.conf and submit a patch. Maybe someone else can do this? I'm willing to assist anywhere where I can for making this possible.
The hd44780-i2c driver is designed to work with the schematic described at http://lcdproc.sourceforge.net/docs/current-user.html#hd44780-i2c.
As you figured out, any pin usage different from the one described there has to be configured in the source code.
Currently there are no plans to make this configurable.
Looking at the layout of the backpack board attached to my lcd, it appears the connections are totally different from those depicted in the schematic. How would the hd44780-i2c driver need to be modified to work with this layout?
Something like this may work. As this forum does not allow to attach files, here comes a small patch a text.
Thanks! I'll give that a shot and post back whether it works.
That definitely got me closer to a working lcd. I'm now getting the welcome message when LCDd starts, and the goodbye message when it stops. Unfortunately, in between those two I am getting dark rectangles, and the occasional blink or garbage. Since the welcome and goodbye messages are displaying correctly, does that mean that everything is working right with LCDproc? Or is it still possible I've got something wrong at this level?
Disregard that previous post. I don't see any way to edit or delete it, or I would. With a couple of minor adjustments in the python and config files I was using, that modified driver is working perfectly. Thank you!
Okay, I'm still having issues with this. I can get the LCD working, displaying the expected data, but the backlight turns off. I've tried a few variations, but nothing I've tried gets the right data to show up on the screen and the backlight to stay on.
I modified the hd44780-i2c.c file based on the patch above, but had to make a couple of changes. I changed the value of BL, and of Default_Device, as shown below:
#define BL 0x80
#define DEFAULT_DEVICE "/dev/i2c-1"
With these settings in the driver section of LCDd.conf:
Using those, I get data to display correctly on the LCD. if I change the backlight setting in LCDd.conf to backlight=no, the backlight will still turn off, but I get only rectangles on the LCD, no data.
How can I get the display working and keep the backlight on by default?
define BL 0x80
is likely to case trouble with your circuit as this is P7 , which is a D7 pin on your display.
To answer this I need to know the circuit you are using for driving the backlight and how it is connected to the I2C chip.
Sainsmart doesn't make a schematic available, but I've found several people suggesting that it's a knockoff of this I2c backpack board:
http://www.dfrobot.com/image/data/DFR0175/I2C%20LCD%20Backpack%20schematic.pdf
I checked continuity between the pins of the chip and those of the lcd with a multimeter to confirm that the connections I listed in the earlier post are correct:
I couldn't find anything that was connected to P3, but I don't have access to the back side of the backpack board, so it may have something on the underside.
I had tried using BL=0x00, and also tried BL=0x08, and just got garbage on the display with those settings. I was surprised that setting BL to 0x80 worked, but that was the only configuration I found that actually resulted in the welcome message, and subsequent data sent from a python script, appearing on the display. Of course, when I set backlight=no in LCDd.conf with BL still set to 0x80, I no longer got data to show up on the screen. I wonder if when I had set backlight=yes, I was getting some data on the screen because whatever was trying to be sent to the backlight happened to match what was needed on that 4th bit to display a character… Probably not very likely I guess.
Looking at that schematic P3 is connected to the base of the back light transistor via signal named BT. If this is true for your board the code should be using:
It looks like there is a bug in the back light function:
is set to 1 for true,
is set to 1 for on and the output must be logic high for on so the logic to set the back light bit should read:
It's not a bug, but on intention. This code is supposed to drive a PNP transistor as in Figure 5.6. HD44780: Backlight Wiring.
As this particular circuit uses a NPN transistor the code from emtejay' comment should work.
Thanks. I made the changes emteejay suggested, and after compiling and copying the new version over the old, I shut my raspberry pi down and brought it back up to try again.
I watched it boot up, and saw that the welcome message was displayed and the backlight did stay on. Wonderful! Then I enabled the autostart script that will send data to the lcd, shut it down to move it, and when it came back up, I'm getting garbage characters on the screen again. The backlight IS staying on now, but I get apparently random characters and symbols on the screen.
I tried disabling the startup script and rebooting, and even tried re-copying the new driver file over the existing, just to be sure it hadn't gotten reverted back somehow. I don't get why it would have appeared to work perfectly the first time, and then not work after that. Still, no luck. I am away from home now, so I haven't been able to spend much time troubleshooting it. I'll have to fiddle with it more tonight or tomorrow.
Thanks again for the help, both of you.
Bug or not?
Isn't the required logic have_backlight && state?
To invert the output just swap the bit definitions:
I spotted two problems which I overlooked:
1. The initialization routine does use i2c_out directly. Therefore just modifying i2c_HD44780_senddata was not enough.
2. The lower nibble calculation did not work as expected.
Here is a complete new version, including the backlight code.
I would like to prepare a patch too allow the selection of the I2C pinout configuration, as above, which is used here:
http://dx.com/p/lcd1602-adapter-board-w-iic-i2c-interface-black-works-with-official-arduino-boards-216865
I see three possible ways of doing this, in order of complexity.
This could be done changing the #defines to integers, with a H/L or L/H config switch that would >> 4 or << 4 the values as appropriate on init.
do any of the other drivers do this kind of thing?
Which solution would be accepted into the code base
Thanks
Rhys
I think a possibility to specifc the pins would be the most versatile solution. You can look into hd44780-rpi.c where such a think is done for the rasberry GPIO pins. I think this should look very similar for both (and more/other) drivers
I have a working version using a conf file to specify the pins. shall i post a diff to here, or is it better post to the maiłing list?
I solved the backlight issue using a config setting:
BacklightInvert: true
its is currently in bitbucket, i can post it to github if someone would like to test it!
Here is an update to lcdproc i2c to allow the pin configurations to be specified via
LCDd.conf.
I have put up on github:
https://github.com/wilberforce/lcdproc
here is an example config:
Hitachi HD44780 driver
[HD44780]
ConnectionType=i2c
Device=/dev/i2c-pi
Port=0x27
Backlight=yes
Size=20x4
DelayBus=false
DelayMult=1
Keypad=no
Speed=0
i2c_line_RS=0x01
i2c_line_RW=0x02
i2c_line_EN=0x04
i2c_line_BL=0x80
i2c_line_D4=0x10
i2c_line_D5=0x20
i2c_line_D6=0x40
i2c_line_D7=0x80
Backlight=yes
BacklightInvert=yes
EOF
I have sent to the lcdproc mailing list, however have not had confirmation on acceptance of the patch.
<hd44780-i2c.c.patch>
<hd44780-low.h.patch>
<hd44780.docbook.patch>
Hi,
Thanks for this modification, but could someone give some hint how to determinate the correct address that must be used for
I already make a map of the i2c backpack connections, they are indentical with these described in https://github.com/wilberforce/lcdproc
except the BL pin - I was unable to track it. Any help is appreciated.
Last edit: Lalyu Lalev 2016-04-06
That seems to be working perfectly. I've rebooted a couple of times, enabled the startup script, and I've got good data showing on the display, and the backlight is staying on. Thanks!
Hello,
I'm attempting to connect a BV4638 I2C chip but the pin usage is different and I'll be very grateful if someone could assist me in modifying the source code please?
link to the chip http://www.byvac.com/bv3/index.php?route=product/product&product_id=149
datasheet http://www.byvac.co.uk/downloads/datasheets/BV4638%20DataSheet.pdf
pin2 D7
pin3 BL
pin7 RS
pin8 E
pin11 D6
pin12 D5
pin13 D4
the chip's address is 0x31.
thanks in advance!
More fun with the backlight
Possible configuration options are: off | open | on.
But in server/drivers/hd44780.c line 171 we have
p->have_backlight = drvthis->config_get_bool(drvthis->name, "backlight", 0, 0);
meaning we test for on/off only, not for open.
The result is that when open is set, the driver thinks there is no backlight and the backlight command does not work (initial backlight setting on startup works however, if patches above were applied).
I see two solutions:
1. either extend config_get_bool() - it takes a few more values already anyway
2. use another default. This will disable backlight only when explicitely "off" was specified. The diff looks like:
hd44780.c.orig 2015-08-10 18:29:58.793086093 +0000
--- hd44780.c 2015-08-10 18:27:39.135758137 +0000***
170,172 *
p->have_keypad = drvthis->config_get_bool(drvthis->name, "keypad", 0, 0);
! p->have_backlight = drvthis->config_get_bool(drvthis->name, "backlight", 0, 0);
p->have_output = drvthis->config_get_bool(drvthis->name, "outputport", 0, 0);
--- 170,172 ----
p->have_keypad = drvthis->config_get_bool(drvthis->name, "keypad", 0, 0);
! p->have_backlight = drvthis->config_get_bool(drvthis->name, "backlight", 0, 1);
p->have_output = drvthis->config_get_bool(drvthis->name, "outputport", 0, 0);**
Last edit: Ralf Schaefer 2015-08-10