Aurock
Posts: 10
Joined: Tue Jan 08, 2013 6:30 pm

Sainsmart 16x2 I2C lcd

Wed Jan 09, 2013 10:23 pm

I purchased a sainsmart IIC/I2C 16x2 LCD pack to use with my raspberry Pi. After following the directions from the link below, I can't seem to get it workign.
http://www.rpiblog.com/2012/07/interfac ... ry-pi.html

I'm new to raspberry pi, this is the first device I've tried to hook up to it, so I am not sure where to begin. If anyone could help me troubleshoot and get this working, I'd appreciate it.

Thanks!

Aurock
Posts: 10
Joined: Tue Jan 08, 2013 6:30 pm

Re: Sainsmart 16x2 I2C lcd

Thu Jan 10, 2013 3:13 am

A few more things I should mention:

i2cdetect shows the lcd connected to address 27. (I assume it's the LCD, 27 is the only address listed, and the lcd is the only I2C device connected.) I adjusted the 2nd line of test_lcd.py to:
lcd = pylcdlib.lcd(0x27,1)

Stairing at the board attached to the back of the lcd, I have tried to follow the traces as well as I can to see what's connected where. It looks like mine is different than what this image from the blog post shows:
Image

I'm a little iffy on a couple of these, but here's how I think my lcd is connected to the PFC8574T chip:

Code: Select all

LCD     CHIP
RS        P0
RW       P1
E           P2
D4        ??  
D5        P5
D6        P6
D7        P7
VDD     Jumper -> A & LED
The trace from D4 goes under the end of the chip. I am guessing it's tied to P4, but can't actually see where it goes.

I see there are a couple of options in pylcdlib.py to accommodate alternate layouts, but the I don't understand the way they are described, so I'm not sure if any of them match what I have. I don't think so... If that's the case, is it possible to add another 'reverse' option to this code which would match my lcd?

Hmm... I'll keep digging, but suggestions are welcome, I'm sure most users here understand this better than i do.

Thanks!

Mr.DadaGuy
Posts: 23
Joined: Thu Aug 22, 2013 5:42 pm

Re: Sainsmart 16x2 I2C lcd

Sat Sep 14, 2013 3:50 pm

Thanks! Using the info above I have got Sainsmart I2C working with Raspberry Pi.

Using this info for setup:

http://think-bowl.com/raspberry-pi/inst ... or-python/

And this code:

Code: Select all

import sys
sys.path.append('/var/www/quick2wire-python-api')

from i2clibraries import i2c_lcd
from time import * 


# Configuration parameters
# I2C Address, Port, Enable pin, RW pin, RS pin, Data 4 pin, Data 5 pin, Data 6 pin, Data 7 pin, Backlight pin (optional)
# below are correct settings for SainSmart IIC/I2C/TWI 1602 Serial LCD Module 

lcd = i2c_lcd.i2c_lcd(0x3f,1, 2, 1, 0, 4, 5, 6, 7, 3)

# If you want to disable the cursor, uncomment the following line
lcd.command(lcd.CMD_Display_Control | lcd.OPT_Enable_Display)

lcd.backLightOn()

lcd.writeString("Python I2C LCD")
lcd.setPosition(2, 3) 
lcd.writeString("For the Pi")

Hope this helps!

Mr.DadaGuy
Posts: 23
Joined: Thu Aug 22, 2013 5:42 pm

Re: Sainsmart 16x2 I2C lcd

Sun Sep 15, 2013 8:31 pm

The above approach (because of dependency on quick2wire) requires Python 3, unfortunately my project is stuck with Python 2. So it turns out I was unable to use this.

However I did figure out an alternative approach using the Think Bowl code. Their deprecated module i2c_lcd_smbus.py works with python2, it's still included in their distribution.

I got it working using this code:

Code: Select all

#!/usr/bin/python

from i2clibraries import i2c_lcd_smbus

lcd = i2c_lcd_smbus.i2c_lcd(0x3f,1, 2, 1, 0, 4, 5, 6, 7, 3)

lcd.command(lcd.CMD_Display_Control | lcd.OPT_Enable_Display)
lcd.backLightOn()
lcd.writeString("Python I2C LCD")
lcd.setPosition(2, 0) 
lcd.writeString("with python 2")


hjchen3724
Posts: 1
Joined: Sat Sep 21, 2013 8:48 am

Re: Sainsmart 16x2 I2C lcd

Sat Sep 21, 2013 9:23 am

Dear Aurock,
I have same problem as you had. Did'nt you solve that problem ? If yes, Please post the solution on this area or mail to me "[email protected]". Any help will be appreciated from you.

Hjchen

marco80
Posts: 2
Joined: Sat Jul 26, 2014 5:23 pm

Re: Sainsmart 16x2 I2C lcd

Sat Jul 26, 2014 5:41 pm

Hi all,
I cannot be able to make it works... :-(

I got this error running the above program:
Traceback (most recent call last):
File "./LCD_dadaguy.sh", line 5, in <module>
lcd = i2c_lcd_smbus.i2c_lcd(0x3f,1, 2, 1, 0, 4, 5, 6, 7, 3)
File "/home/pi/myproject/i2clibraries/i2c_lcd_smbus.py", line 49, in __init__
self._enable(initialize_i2c_data)
File "/home/pi/myproject/i2clibraries/i2c_lcd_smbus.py", line 157, in _enable
self.bus.write_byte(self.addr, data)
IOError: [Errno 5] Input/output error


where LCD_dadaguy.sh is:

Code: Select all

#!/usr/bin/python

from i2clibraries import i2c_lcd_smbus

lcd = i2c_lcd_smbus.i2c_lcd(0x3f,1, 2, 1, 0, 4, 5, 6, 7, 3)

lcd.command(lcd.CMD_Display_Control | lcd.OPT_Enable_Display)
lcd.backLightOn()
lcd.writeString("Python I2C LCD")
lcd.setPosition(2, 0)
lcd.writeString("with python 2")
running i2cdetect -y 1:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

so my i2c is on 0x27 and my LCD is this:
Image
you can see it there:
http://arduino-info.wikispaces.com/LCD-Blue-I2C

on that site seems that this code is working:

Code: Select all

/* YourDuino.com Example Software Sketch
 16 character 2 line I2C Display
 Backpack Interface labelled "YwRobot Arduino LCM1602 IIC V1"
 [email protected] */

/*-----( Import needed libraries )-----*/
#include <Wire.h>  // Comes with Arduino IDE
// Get the LCD I2C Library here: 
// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
// Move any other LCD libraries to another folder or delete them
// See Library "Docs" folder for possible commands etc.
#include <LiquidCrystal_I2C.h>

/*-----( Declare Constants )-----*/
/*-----( Declare objects )-----*/
// set the LCD address to 0x27 for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

/*-----( Declare Variables )-----*/
//NONE

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);  // Used to type in characters

  lcd.begin(16,2);   // initialize the lcd for 16 chars 2 lines, turn on backlight

// ------- Quick 3 blinks of backlight  -------------
  for(int i = 0; i< 3; i++)
  {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on  

//-------- Write characters on the display ------------------
// NOTE: Cursor Position: (CHAR, LINE) start at 0  
  lcd.setCursor(0,0); //Start at character 4 on line 0
  lcd.print("Hello, world!");
  delay(1000);
  lcd.setCursor(0,1);
  lcd.print("HI!YourDuino.com");
  delay(8000);  

// Wait and then tell user they can start the Serial Monitor and type in characters to
// Display. (Set Serial Monitor option to "No Line Ending")
  lcd.clear();
  lcd.setCursor(0,0); //Start at character 0 on line 0
  lcd.print("Use Serial Mon");
  lcd.setCursor(0,1);
  lcd.print("Type to display");  


}/*--(end setup )---*/


void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  {
    // when characters arrive over the serial port...
    if (Serial.available()) {
      // wait a bit for the entire message to arrive
      delay(100);
      // clear the screen
      lcd.clear();
      // read all the available characters
      while (Serial.available() > 0) {
        // display each character to the LCD
        lcd.write(Serial.read());
      }
    }
  }

}/* --(end main loop )-- */


/* ( THE END ) */
but it seems to work only with Arduino....

this guy seems to make this lcd model (but 20x4, mine is 16x2) works with Raspberry:
http://www.extremeelectronics.co.uk/blo ... pberry-pi/

this is the code:

Code: Select all

import smbus
from time import *

#
# Modified from http://www.rpiblog.com/2012/07/interfacing-16×2-lcd-with-raspberry-pi.html to run
# 20×4 line display with YwRobot LCM1602 IIC V1 backpack
#

# General i2c device class so that other devices can be added easily
class i2c_device:
def __init__(self, addr, port):
self.addr = addr
self.bus = smbus.SMBus(port)

def write(self, byte):
self.bus.write_byte(self.addr, byte)

def read(self):
return self.bus.read_byte(self.addr)

def read_nbytes_data(self, data, n): # For sequential reads > 1 byte
return self.bus.read_i2c_block_data(self.addr, data, n)

class lcd:
#initializes objects and lcd
”’
Port definitions
addr, en,rw,rs,d4,d5,d6,d7,bl
0×27, 2, 1, 0, 4, 5, 6, 7, 3

”’

def __init__(self, addr, port):
self.lcd_device = i2c_device(addr, port)

self.backlight=1; #default backlight on

#set 4 bit mode

self.lcd_device_writebl(0×20)
self.lcd_strobe()
sleep(0.0005)
self.lcd_strobe()
sleep(0.0005)
self.lcd_strobe()
sleep(0.0005)

self.lcd_write(0×28)
self.lcd_write(0×08)
self.lcd_write(0×01)
self.lcd_write(0×06)
self.lcd_write(0x0C)
self.lcd_write(0x0F)

#wrapper to self.lcd_device.write fir backlight control
def lcd_device_writebl(self,value):
if self.backlight:
self.lcd_device.write(value | 0×08);
else:
self.lcd_device.write(value)

# control backlight on=1 or off=0
def lcd_backlight(self,on):
self.backlight=on
self.lcd_strobe()

# clocks EN to latch command
def lcd_strobe(self):
#bit 2
self.lcd_device_writebl((self.lcd_device.read() | 0×04))
self.lcd_device_writebl((self.lcd_device.read() & 0xFB))

# write a command to lcd
def lcd_write(self, cmd):
self.lcd_device_writebl((cmd >> 4)<<4)
self.lcd_strobe()
self.lcd_device_writebl((cmd & 0x0F)<<4) self.lcd_strobe() self.lcd_device_writebl(0×0) # write a character to lcd (or character rom) def lcd_write_char(self, charvalue): self.lcd_device_writebl((0×01 | (charvalue >> 4)<<4))
self.lcd_strobe()
self.lcd_device_writebl((0×01 | (charvalue & 0x0F)<<4))
self.lcd_strobe()
self.lcd_device_writebl(0×0)

# put char function
def lcd_putc(self, char):
self.lcd_write_char(ord(char))

# put string function
def lcd_puts(self, string, line):
if line == 1:
self.lcd_write(0×80)
if line == 2:
self.lcd_write(0xC0)
if line == 3:
self.lcd_write(0×94)
if line == 4:
self.lcd_write(0xD4)

for char in string:
self.lcd_putc(char)

# clear lcd and set to home
def lcd_clear(self):
self.lcd_write(0×1)
self.lcd_write(0×2)

# add custom characters (0 – 7)
def lcd_load_custon_chars(self, fontdata):
self.lcd_device.bus.write(0×40);
for char in fontdata:
for line in char:
self.lcd_write_char(line)

 

lcd-test.py


import pylcdlib
lcd = pylcdlib.lcd(0x27,1)
lcd.lcd_write(0x01);
lcd.lcd_puts("Raspberry Pi",1) #display "Raspberry Pi" on line 1
lcd.lcd_puts(" Take a byte!",2) #display "Take a byte!" on line 2
lcd.lcd_puts(" works on all 4",3) #display "Raspberry Pi" on line 1
lcd.lcd_puts("Lines of the display",4) #display "Take a byte!" on line 2
lcd.lcd_backlight(1)

please help, I'm new to Rasperry PI :-)

marco80
Posts: 2
Joined: Sat Jul 26, 2014 5:23 pm

Re: Sainsmart 16x2 I2C lcd

Mon Jul 28, 2014 1:13 pm

I've solved with these script:

https://zarkosoft.box.com/s/k3sgs8ij37wujd4so8yc

this is the lib file: pylcdlib.py

Code: Select all

import smbus
from time import *

# General i2c device class so that other devices can be added easily
class i2c_device:
 def __init__(self, addr, port):
  self.addr = addr
  self.bus = smbus.SMBus(port)

 def write(self, byte):
  self.bus.write_byte(self.addr, byte)

 def read(self):
  return self.bus.read_byte(self.addr)

 def read_nbytes_data(self, data, n): # For sequential reads > 1 byte
  return self.bus.read_i2c_block_data(self.addr, data, n)


class lcd:
 #initializes objects and lcd
 '''
 Port definitions
 addr, en,rw,rs,d4,d5,d6,d7,bl
 0x27, 2, 1, 0, 4, 5, 6, 7, 3
 '''
 def __init__(self, addr, port):
  self.lcd_device = i2c_device(addr, port)
  self.backlight=1; #default backlight on

  #set 4 bit mode
  self.lcd_device_writebl(0x20)
  self.lcd_strobe()
  sleep(0.0005)
  self.lcd_strobe()
  sleep(0.0005)
  self.lcd_strobe()
  sleep(0.0005)

  self.lcd_write(0x28)
  self.lcd_write(0x08)
  self.lcd_write(0x01)
  self.lcd_write(0x06)
  self.lcd_write(0x0C)
  self.lcd_write(0x0F)

#wrapper to self.lcd_device.write fir backlight control
 def lcd_device_writebl(self,value):
  if self.backlight:
   self.lcd_device.write(value | 0x08);
  else:
   self.lcd_device.write(value)

# control backlight on=1 or off=0
 def lcd_backlight(self,on):
  self.backlight=on
  self.lcd_strobe()

 # clocks EN to latch command
 def lcd_strobe(self):
 #bit 2
  self.lcd_device_writebl((self.lcd_device.read() | 0x04))
  self.lcd_device_writebl((self.lcd_device.read() & 0xFB))

 # write a command to lcd
 def lcd_write(self, cmd):
  self.lcd_device_writebl((cmd >> 4)<<4)
  self.lcd_strobe()
  self.lcd_device_writebl((cmd & 0x0F)<<4)
  self.lcd_strobe() 
  self.lcd_device_writebl(0x0) 

 # write a character to lcd (or character rom)
 def lcd_write_char(self, charvalue):
   self.lcd_device_writebl((0x01 | (charvalue >> 4)<<4))
   self.lcd_strobe()
   self.lcd_device_writebl((0x01 | (charvalue & 0x0F)<<4))
   self.lcd_strobe()
   self.lcd_device_writebl(0x0)

 # put char function
 def lcd_putc(self, char):
  self.lcd_write_char(ord(char))

 # put string function
 def lcd_puts(self, string, line):
  if line == 1:
   self.lcd_write(0x80)
  if line == 2:
   self.lcd_write(0xC0)
  if line == 3:
   self.lcd_write(0x94)
  if line == 4:
   self.lcd_write(0xD4)

  for char in string:
   self.lcd_putc(char)

 # clear lcd and set to home
 def lcd_clear(self):
  self.lcd_write(0x1)
  self.lcd_write(0x2)

 # add custom characters (0 - 7)
 def lcd_load_custon_chars(self, fontdata):
  self.lcd_device.bus.write(0x40);
  for char in fontdata:
   for line in char:
    self.lcd_write_char(line)
and this is the test file:

Code: Select all

import pylcdlib
lcd = pylcdlib.lcd(0x27,1)
lcd.lcd_write(0x01);
lcd.lcd_puts("Hello",1) #display "Raspberry Pi" on line 1
lcd.lcd_puts(" World!",2) #display "Take a byte!" on line 2
lcd.lcd_backlight(1)

User avatar
dentex
Posts: 180
Joined: Sun May 20, 2012 7:58 am
Location: Italy
Contact: Website

Re: Sainsmart 16x2 I2C lcd

Sun Feb 01, 2015 7:30 pm

Thank you very much, my LCD works fine with your example code!
One of my projects with the Raspberry Pi:
--------------------------------------------------------
(Raspberry) Pi Aquarium Controller: https://github.com/dentex/piac

User avatar
dentex
Posts: 180
Joined: Sun May 20, 2012 7:58 am
Location: Italy
Contact: Website

Re: Sainsmart 16x2 I2C lcd

Sat Feb 07, 2015 4:20 pm

...well, it works, but if you run the same simple script, as the one above, one time it prints the right text and the next time it prints random symbols and so on, in sequence. Does anyone know why? Sorry I'm a beginner with python, I searched a lot but with no results.

Thanks.
One of my projects with the Raspberry Pi:
--------------------------------------------------------
(Raspberry) Pi Aquarium Controller: https://github.com/dentex/piac

User avatar
dentex
Posts: 180
Joined: Sun May 20, 2012 7:58 am
Location: Italy
Contact: Website

Re: Sainsmart 16x2 I2C lcd

Sat Feb 07, 2015 6:02 pm

I found that duplicating the line

Code: Select all

lcd = pylcdlib.lcd(0x27,1)
lcd = pylcdlib.lcd(0x27,1)
makes the script to work good every time, but why?
One of my projects with the Raspberry Pi:
--------------------------------------------------------
(Raspberry) Pi Aquarium Controller: https://github.com/dentex/piac

kerinr
Posts: 6
Joined: Sun Feb 08, 2015 5:38 am

Re: Sainsmart 16x2 I2C lcd

Sun Feb 08, 2015 5:40 am

It appears as if the script in the box account has been deleted. I am still unable to get the quick2wire.i2c module to work. I have tried again and again without it working. I am not using the smbus, but should I be? Is there an advantage?

User avatar
dentex
Posts: 180
Joined: Sun May 20, 2012 7:58 am
Location: Italy
Contact: Website

Re: Sainsmart 16x2 I2C lcd

Sun Feb 08, 2015 7:01 pm

kerinr wrote:It appears as if the script in the box account has been deleted. I am still unable to get the quick2wire.i2c module to work. I have tried again and again without it working. I am not using the smbus, but should I be? Is there an advantage?
If you have the same LCD/backpack, why don't you try the code above? Please not there are some glitches, though; but it works.
One of my projects with the Raspberry Pi:
--------------------------------------------------------
(Raspberry) Pi Aquarium Controller: https://github.com/dentex/piac

kerinr
Posts: 6
Joined: Sun Feb 08, 2015 5:38 am

Re: Sainsmart 16x2 I2C lcd

Mon Feb 09, 2015 12:32 am

Do you mean marco80's pylcdlib.py and accompanying main program? I am testing that out right now, but I was meaning that the scripts that he had linked to in his Box account have been deleted or I do not have permission to view them. If you happen to have them on hand please share. I'll post back with my results.

kerinr
Posts: 6
Joined: Sun Feb 08, 2015 5:38 am

Re: Sainsmart 16x2 I2C lcd

Mon Feb 09, 2015 12:48 am

Still a no go. I copied it exactly but I keep getting some odd error about an encoding problem (?).

Code: Select all

[email protected] ~/LCD_programming $ sudo python3 testing.py
Traceback (most recent call last):
  File "testing.py", line 1, in <module>
    import pylcdlib
  File "/home/pi/LCD_programming/pylcdlib.py", line 6
    \xa0def __init__(self, addr, port):
        ^
SyntaxError: invalid character in identifier

which is odd because it clearly is not in there. What is this character that I am not seeing?

below is the copied pylcdlib.py file from above.

Code: Select all

import smbus
from time import *

# General i2c device class so that other devices can be added easily
class i2c_device:
 def __init__(self, addr, port):
  self.addr = addr
  self.bus = smbus.SMBus(port)

 def write(self, byte):
  self.bus.write_byte(self.addr, byte)

 def read(self):
  return self.bus.read_byte(self.addr)

 def read_nbytes_data(self, data, n): # For sequential reads > 1 byte
  return self.bus.read_i2c_block_data(self.addr, data, n)


class lcd:
 #initializes objects and lcd
 '''
 Port definitions
 addr, en,rw,rs,d4,d5,d6,d7,bl
 0x27, 2, 1, 0, 4, 5, 6, 7, 3
 '''
 def __init__(self, addr, port):
  self.lcd_device = i2c_device(addr, port)
  self.backlight=1; #default backlight on

  #set 4 bit mode
  self.lcd_device_writebl(0x20)
  self.lcd_strobe()
  sleep(0.0005)
  self.lcd_strobe()
  sleep(0.0005)
  self.lcd_strobe()
  sleep(0.0005)

  self.lcd_write(0x28)
  self.lcd_write(0x08)
  self.lcd_write(0x01)
  self.lcd_write(0x06)
  self.lcd_write(0x0C)
  self.lcd_write(0x0F)

#wrapper to self.lcd_device.write fir backlight control
 def lcd_device_writebl(self,value):
  if self.backlight:
   self.lcd_device.write(value | 0x08);
  else:
   self.lcd_device.write(value)

# control backlight on=1 or off=0
 def lcd_backlight(self,on):
  self.backlight=on
  self.lcd_strobe()

 # clocks EN to latch command
 def lcd_strobe(self):
 #bit 2
  self.lcd_device_writebl((self.lcd_device.read() | 0x04))
  self.lcd_device_writebl((self.lcd_device.read() & 0xFB))

 # write a command to lcd
 def lcd_write(self, cmd):
  self.lcd_device_writebl((cmd >> 4)<<4)
  self.lcd_strobe()
  self.lcd_device_writebl((cmd & 0x0F)<<4)
  self.lcd_strobe() 
  self.lcd_device_writebl(0x0) 

 # write a character to lcd (or character rom)
 def lcd_write_char(self, charvalue):
   self.lcd_device_writebl((0x01 | (charvalue >> 4)<<4))
   self.lcd_strobe()
   self.lcd_device_writebl((0x01 | (charvalue & 0x0F)<<4))
   self.lcd_strobe()
   self.lcd_device_writebl(0x0)

 # put char function
 def lcd_putc(self, char):
  self.lcd_write_char(ord(char))

 # put string function
 def lcd_puts(self, string, line):
  if line == 1:
   self.lcd_write(0x80)
  if line == 2:
   self.lcd_write(0xC0)
  if line == 3:
   self.lcd_write(0x94)
  if line == 4:
   self.lcd_write(0xD4)

  for char in string:
   self.lcd_putc(char)

 # clear lcd and set to home
 def lcd_clear(self):
  self.lcd_write(0x1)
  self.lcd_write(0x2)

 # add custom characters (0 - 7)
 def lcd_load_custon_chars(self, fontdata):
  self.lcd_device.bus.write(0x40);
  for char in fontdata:
   for line in char:
    self.lcd_write_char(line)
Any ideas?

kerinr
Posts: 6
Joined: Sun Feb 08, 2015 5:38 am

Re: Sainsmart 16x2 I2C lcd

Mon Feb 09, 2015 1:09 am

Last post of the day (hopefully). I completely forgot to turn on i2c via raspi-config after my recent reload. Did that and got a different error, although still referring to the copied code. Below is the error. Any ideas?

Code: Select all

[email protected] ~/LCD_programming $ sudo python3 testing.py
Traceback (most recent call last):
  File "testing.py", line 1, in <module>
    import pylcdlib
  File "/home/pi/LCD_programming/pylcdlib.py", line 6
     def __init__(self, addr, port):
        ^
SyntaxError: invalid character in identifier

kerinr
Posts: 6
Joined: Sun Feb 08, 2015 5:38 am

Re: Sainsmart 16x2 I2C lcd

Tue Feb 10, 2015 4:17 am

Alright so I got it to print (finally) however it only prints on the first line. I can use either 1 or 4 and the both print on the first line.
BTW the problem was the indenting... still getting used to python (I'm used to C# or C++). So are the addresses wrong? Has anyone run into this yet?

Code: Select all

    import smbus
    from time import *

    # General i2c device class so that other devices can be added easily
    class i2c_device:
     def __init__(self, addr, port):
      self.addr = addr
      self.bus = smbus.SMBus(port)

     def write(self, byte):
      self.bus.write_byte(self.addr, byte)

     def read(self):
      return self.bus.read_byte(self.addr)

     def read_nbytes_data(self, data, n): # For sequential reads > 1 byte
      return self.bus.read_i2c_block_data(self.addr, data, n)


    class lcd:
     #initializes objects and lcd
     '''
     Port definitions
     addr, en,rw,rs,d4,d5,d6,d7,bl
     0x27, 2, 1, 0, 4, 5, 6, 7, 3
     '''
     def __init__(self, addr, port):
      self.lcd_device = i2c_device(addr, port)
      self.backlight=1; #default backlight on

      #set 4 bit mode
      self.lcd_device_writebl(0x20)
      self.lcd_strobe()
      sleep(0.0005)
      self.lcd_strobe()
      sleep(0.0005)
      self.lcd_strobe()
      sleep(0.0005)

      self.lcd_write(0x28)
      self.lcd_write(0x08)
      self.lcd_write(0x01)
      self.lcd_write(0x06)
      self.lcd_write(0x0C)
      self.lcd_write(0x0F)

     #wrapper to self.lcd_device.write fir backlight control
     def lcd_device_writebl(self,value):
      if self.backlight:
       self.lcd_device.write(value | 0x08);
      else:
       self.lcd_device.write(value)

     #control backlight on=1 or off=0
     def lcd_backlight(self,on):
      self.backlight=on
      self.lcd_strobe()

     #clocks EN to latch command
     def lcd_strobe(self):
     #bit 2
      self.lcd_device_writebl((self.lcd_device.read() | 0x04))
      self.lcd_device_writebl((self.lcd_device.read() & 0xFB))

     #write a command to lcd
     def lcd_write(self, cmd):
      self.lcd_device_writebl((cmd >> 4)<<4)
      self.lcd_strobe()
      self.lcd_device_writebl((cmd & 0x0F)<<4)
      self.lcd_strobe()
      self.lcd_device_writebl(0x0)

     #write a character to lcd (or character rom)
     def lcd_write_char(self, charvalue):
       self.lcd_device_writebl((0x01 | (charvalue >> 4)<<4))
       self.lcd_strobe()
       self.lcd_device_writebl((0x01 | (charvalue & 0x0F)<<4))
       self.lcd_strobe()
       self.lcd_device_writebl(0x0)
	   
	 #put char function
     def lcd_putc(self, char):
      self.lcd_write_char(ord(char))

	 #put string function
         #HERE IS THE DECLARATION THAT I DON'T THINK IS WORKING
     def lcd_puts(self, string, line):
      if line == 1:
       self.lcd_write(0x80)
      if line == 2:
       self.lcd_write(0xC0)
      if line == 3:
       self.lcd_write(0x94)
      if line == 4:
       self.lcd_write(0xD4)[/color][/color]

      for char in string:
       self.lcd_putc(char)

     #clear lcd and set to home
     def lcd_clear(self):
      self.lcd_write(0x1)
      self.lcd_write(0x2)

     #add custom characters (0 - 7)
     def lcd_load_custon_chars(self, fontdata):
      self.lcd_device.bus.write(0x40);
      for char in fontdata:
       for line in char:
        self.lcd_write_char(line)

denis_hr
Posts: 17
Joined: Fri Jun 06, 2014 1:11 pm
Location: Croatia
Contact: Website

Re: Sainsmart 16x2 I2C lcd

Tue Feb 10, 2015 9:33 pm

Some of you might be interested in the code I posted to Gist/Github yesterday: https://gist.github.com/DenisFromHR/cc8 ... e19dce359d

It's a Python library plus some examples of use: most importantly, it shows how to use custom characters.

The library has been tested on exactly the same I2C LCD as shown above in the thread by marco80 (I got it from ebay)... It also works on I2C 20x4 LCD displays (already has provisions for 20x4 screen size).

My LCD is at address 0x27, and it is listed in the driver (RPi_I2C_driver.py).

In short, it's a kind of compilaton of various existing sources, mostly the lcddriver.py I got from Raspberry Pi Pod blog, http://www.recantha.co.uk/blog/?p=4849. I added the function to create and use custom characters, which I got from another source that's making the rounds on the interwebs (BTW, that one has a bug, and won't work "as is" - I cleaned it, corrected it and tested, and now it works...)

In short, I spent some time on this, but finally got it to work. SO, if this saves you some headaches, great!

The library and example script are here:
https://gist.github.com/DenisFromHR/cc8 ... e19dce359d

Disclaimer 1: 95% of the code there has been taken from other sources
Disclaimer 2: I'm a Python beginner, and programming in general is not my forte :)

Enjoy
Denis

alex_dom
Posts: 2
Joined: Wed Nov 04, 2015 6:31 am

Re: Sainsmart 16x2 I2C lcd

Wed Nov 04, 2015 6:34 am

Wow!! That is the best script to control it. I wonder how to run Ukrainian symbols on it! Will post results later.

Thanks Denis!

alex_dom
Posts: 2
Joined: Wed Nov 04, 2015 6:31 am

Re: Sainsmart 16x2 I2C lcd

Wed Nov 04, 2015 6:38 am

Do you have more examples?

atomic3
Posts: 99
Joined: Thu Jan 17, 2013 4:31 pm

Re: Sainsmart 16x2 I2C lcd

Tue Dec 01, 2015 2:43 am

So I was using the code that Denis posted and everything was working perfectly until I shutdown my pi. Now the characters that show up are just random and I can't figure out what happened.

Image
photo uploader

User avatar
DougieLawson
Posts: 37624
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: Sainsmart 16x2 I2C lcd

Tue Dec 01, 2015 8:10 am

Check your wiring. Check whether your code is running the display in 4-bit or 8-bit mode.
Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

atomic3
Posts: 99
Joined: Thu Jan 17, 2013 4:31 pm

Re: Sainsmart 16x2 I2C lcd

Thu Dec 03, 2015 4:44 am

You Sir are 100% correct. I swapped SD card and the hardware to another Pi and everything is working.

My son grabbed it before I started having issues, so I'm wondering why it's no longer working. I don't see any visual defects...

EDIT: I take that back, I hooked everything back to the original Pi and it's working flawlessly now.

smithy468
Posts: 10
Joined: Sun Jul 26, 2015 12:04 pm

Re: Sainsmart 16x2 I2C lcd

Wed Dec 30, 2015 1:50 pm

Hi, thanks for this, the library and code posted by DenisFromHR looks promising but I can't get it to work... I'm using a 16x2 HD44780 LCD connected to a PCF8574N chip, wired to the RPi 2 via I2C (stand alone chip, not a back pack) wired following this tutorial: http://www.rpiblog.com/2012/07/interfac ... ry-pi.html. My problem is when I run examples.py, the program runs without errors, but nothing displays on the LCD. I have changed the address in the library. Is there anything else I need to change in the library or example program for my specific set up? Any help would really be appreciated!

kb93
Posts: 6
Joined: Thu Jul 28, 2016 10:31 am

Re: Sainsmart 16x2 I2C lcd

Fri Nov 11, 2016 6:49 pm

Dear,

I am struggling with similar problem. I have got HD44780 which I tested that is working properly: connected directly to RPi's GPIO displays characters. When connected via PCF8574 does not work. I have PCB with PCF8574T, it looks the same as this one: http://4.bp.blogspot.com/-ndXZnYz18PA/U ... 7364-6.jpg

I have tried to connect pins from HD44780 to this PCB one by one (1--1, 2--2, 3--3, 4--4, etc)
I have tried to change pin 4 and 6, nothing helps. Always there is the same problem: only one line is displayed but there are rectangles only.

Does anyone know how to display characters using i2c? Maybe PCF8574T is crappy?
I would like to display characters using python program with smbus.

User avatar
dentex
Posts: 180
Joined: Sun May 20, 2012 7:58 am
Location: Italy
Contact: Website

Re: Sainsmart 16x2 I2C lcd

Fri Nov 11, 2016 8:04 pm

kb93 wrote:Dear,
[...]
I have PCB with PCF8574T
[...]
I would like to display characters using python program with smbus.
Hi,
we have the same I2C backback.

I slightly modified a script found somewhere (sorry for the poor credits, I don't remember where...) and it's working really well.
Download it @ https://www.dropbox.com/s/lxdprouv6i8d1 ... C.zip?dl=0

Launch either:
lcd_print.py (the LCD print script);
use the -h / --help switch for a usage message;
-i / --init to do the initialization (use the -i / --init switch only the first time you launch this script (or the next one), in order to do the initialization only once. If you happen to launch it twice, just relaunch it one more time to fix the bad characters).
-d / --debug;
-x and -y to print something on every row.
OR
lcdui.py (the "driver"); you can also launch it directly, to quickly test the LCD. It has the same -i, -d and -h switch as the other one.

Hope this helps.

Bye!
One of my projects with the Raspberry Pi:
--------------------------------------------------------
(Raspberry) Pi Aquarium Controller: https://github.com/dentex/piac

Return to “Interfacing (DSI, CSI, I2C, etc.)”