i2c LCD control

#1
Hi folks,

I have a project that uses a standard parallel LCD, but I need to fee up some Picaxe pins for other things.
So, I have obtained a 16x2 LCD that uses i2c for control - apparently it is meant for use with Arduino's.
Unfortunately I haven't been able to find any info on how to control it using Picaxe Basic, and I know nothing re Arduino code.
Does anyone have any info on how to control these units using i2c/ Picaxe Basic?

kenmac
 

lbenson

Senior Member
#2
If this is the typical "Arduino" I2C LCD, then it writes in "nibble" mode and uses the PCF8574 chip for the interface. Using with the picaxe is not trivial, but hippy worked out the necessary code some years ago. Here's a version for a 4-line lcd:
Code:
#picaxe 20M2
#terminal 4800

' hippy's generic string poking macro:
#Macro PokeString( toLoc, string )
' modified to include zero terminator
  bPtr = toLoc
  lookupAdr = 0
  Do
    Lookup lookupAdr, ( string, 0 ), lookupData
'    If lookupData <> 0 Then
      @bPtrInc = lookupData
      lookupAdr = lookupAdr + 1
'    End If
  Loop Until lookupData = 0
#EndMacro

symbol stringAdrBase = $40 ' location of up to 16 offsets for strings
symbol stringBase    = $50 ' location of strings

' hippy's I2C LCD with PCF8574 code, post 28: 
' http://www.picaxeforum.co.uk/showthread.php?21872
' symbol b2,b3,secondNybble reserved for LCD 
' b3 bits defined below
Symbol bitRS = bit24
Symbol bitWR = bit25
Symbol bitE  = bit26
Symbol bitBKL = bit27
Symbol bitD4 = bit28
Symbol bitD5 = bit29
Symbol bitD6 = bit30
Symbol bitD7 = bit31

symbol secondNybble    = b5 ' for LCD
symbol lookupAdr       = b6 ' for PokeString Macro
symbol lookupData      = b7 ' for PokeString Macro
symbol stringAdrOffset = b8 ' location of nth string address

Initialisation:

  gosub InitializeLCD
  stringAdrOffset = stringAdrBase
  bptr = stringBase
  poke stringAdrOffset, bptr
  pokeString(bptr,"Line 1 8901234567890")
  inc stringAdrOffset
  poke stringAdrOffset, bptr
  pokeString(bptr,"Line 2")
  inc stringAdrOffset
  poke stringAdrOffset, bptr
  pokeString(bptr,"Line 3")
  inc stringAdrOffset
  poke stringAdrOffset, bptr
  pokeString(bptr,"Line 4")
  inc stringAdrOffset
  poke stringAdrOffset, bptr
  pokeString(bptr,"Another longer line")
  inc stringAdrOffset
  pause 2000

MainProgram:

  b2 = $80 : Gosub Sendb2AsCommandByte
  stringAdrOffset = stringAdrBase ' offset of first string
  peek stringAdrOffset, bptr
'  sertxd(#bptr, " ", @bptr," | ")
  gosub sendString

  b2 = $C0 : Gosub SendB2AsCommandByte ' LB 180526 was $A0
  stringAdrOffset = stringAdrBase + 1 ' offset of 2nd string
  peek stringAdrOffset, bptr
  gosub sendString

  b2 = $94 : Gosub Sendb2AsCommandByte ' LB 180526 was $C0
  stringAdrOffset = stringAdrBase + 2 ' offset of 3rd string
  peek stringAdrOffset, bptr
  gosub sendString

  b2 = $D4 : Gosub Sendb2AsCommandByte ' LB 180526 was $E0
  stringAdrOffset = stringAdrBase + 3 ' offset of 4nd string
  peek stringAdrOffset, bptr
  gosub sendString

  pause 5000
  b2 = $C0 : Gosub SendB2AsCommandByte ' LB 180526 was $A0
  stringAdrOffset = stringAdrBase + 4 ' offset of 5th string
  peek stringAdrOffset, bptr
  gosub sendString

  Do : Loop

Sendb2AsInitByte:

  Pause 15

  bitWR = 0         ; Keep WR signal low
  bitBKL = 1        ; keep backlight on
  bitBKL = 0        ; keep backlight off
 
Sendb2AsCommandByte:

  bitRS = 0         ; Send byte as a command

Sendb2AsDataByte:

  bitD4 = bit20      ; Send msb first
  bitD5 = bit21
  bitD6 = bit22
  bitD7 = bit23

  bitE  = 1
  secondNybble = b3        ; secondNybble holds msb with E set
  bitE  = 0         ; b1 holds msb with E clear

  HI2cOut b3, ( secondNybble, b3 )

  bitD4 = bit16      ; Send lsb second
  bitD5 = bit17
  bitD6 = bit18
  bitD7 = bit19

  bitE  = 1
  secondNybble = b3        ; secondNybble holds lsb with E set
  bitE  = 0         ; b1 holds lsb with E clear

  HI2cOut b3, ( secondNybble, b3 )

  bitRS = 1         ; Send data byte next time
  
  Return

InitializeLCD:
  HI2cSetup I2CMASTER, $4E, I2CSLOW, I2CBYTE

  b2 = $33 : Gosub Sendb2AsInitByte
  b2 = $33 : Gosub Sendb2AsInitByte
  b2 = $32 : Gosub Sendb2AsInitByte
  b2 = $28 : Gosub Sendb2AsCommandByte
  b2 = $0C : Gosub Sendb2AsCommandByte
  b2 = $06 : Gosub Sendb2AsCommandByte
  b2 = $01 : Gosub Sendb2AsCommandByte 

  Pause 2
  return

sendString:
  do : b2 = @bptrinc: if b2 <> 0 then: Gosub Sendb2AsDataByte: endif: loop until b2 = 0
  return
It writes, for instance, "Line 1 8901234567890", using the macro PokeString. If yours is a similar LCD, you would eliminate the code for writing lines 3 and 4. The code provides for set strings to be stored at addresses in RAM above $50--you can disregard that code if not needed.

As noted in a comment, hippy's original code is attached to post 28 in this thread: http://www.picaxeforum.co.uk/showthread.php?21872
 
#4
Rather than buy another LCD, is it possible to purchase the backpack or programmed chip to convert an existing LCD?
I mean the bits that drive a AXE133Y.

Ken Mac
 

Flenser

Senior Member
#5
Ken Mac,

The AXE133 LCD board uses an 18M2 chip and the AXE133 firmware is available to download on the RevEd PICAXE website. You would need to wire up the correct circuit yourself from the AXE133.pdf document.
 
#6
If you are intending to use a Picaxe, you are best advised to use the Picaxe backpack, either as a complete module or, as Flenser suggests, as an add-on (the AXE132 serial backpack board). However, be aware that the pins on that board are on the opposite side from most budget LCDs so adding the AXE132 to an existing parallel LCD will probably result in it protruding out of the side slightly. Alternatively, if you don't need many pins for your application, you could just use your existing LCD in parallel mode.
 
Last edited:
#9
Hi,

Check also the Grove LCD RGB backlight (I2C connection). Pretty easy to program with Blockly Grove displays extension (Picaxe editor). And you can change the colour of the backlight which can be very useful (warning, ...).
 
#10
#11
I gave used the FRM010 in the past but didn't realise they were still available - it is old.
Anyway, I went ahead and bought the AXE131 Firmware and will use that for this job.

Kenmac
 

Aries

New Member
#12
I usually use an 8-bit serial to parallel shift register (SN74HC595 or similar) to interface with HD44780 type LCD displays. The shift register needs only three Picaxe pins (CLK, RCLK, SER) to produce 8 (or if you daisy-chain) 8*n parallel outputs..
 
Top