Module LCD HD44780

Share your advanced PureBasic knowledge/code with the community.
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Module LCD HD44780

Post by Flype »

Hi people,

Recently, I wanted to play a little with some Arduino modules - from Adafruit.com for example.

So i bought a RGB Character Liquid Crystal Display (HD44780), shipped with a USB & Serial backpack, here :

http://www.adafruit.com/products/782

Image

Once you are equipped, you need to install this driver for Windows :

https://learn.adafruit.com/usb-plus-ser ... /downloads

Here is a work in progress but usable include to use the LCD very easily with PureBasic, using a simple USB cable :

Code: Select all

;=======================================================
;== Description: HD44780 compatible RGB Character LCD
;== Filename: HD44780.pbi
;== Author: flype, 2015
;=======================================================

DeclareModule LCD
  
  ; CONSTANTS
  
  Enumeration 0
    #LCD_AUTOSCROLL_ON    = $51
    #LCD_AUTOSCROLL_OFF   = $52
    #LCD_BRIGHTNESS       = $98
    #LCD_BRIGHTNESS2      = $99
    #LCD_COLOR            = $D0
    #LCD_COMMAND          = $FE
    #LCD_CONTRAST         = $50
    #LCD_CONTRAST2        = $91
    #LCD_CURSOR_HOME      = $48
    #LCD_CURSOR_BACK      = $4C
    #LCD_CURSOR_FORWARD   = $4D
    #LCD_CURSOR_POSITION  = $47
    #LCD_CURSOR_ON        = $53
    #LCD_CURSOR_OFF       = $54
    #LCD_CUSTOM_CHAR      = $4E
    #LCD_CUSTOM_CHAR_LOAD = $C0
    #LCD_CUSTOM_CHAR_SAVE = $C1
    #LCD_DISPLAY_CLEAR    = $58
    #LCD_DISPLAY_ON       = $42
    #LCD_DISPLAY_OFF      = $46
    #LCD_SIZE             = $D1
    #LCD_SPLASH_SCREEN    = $40
    #LCD_UNDERLINE_ON     = $4A
    #LCD_UNDERLINE_OFF    = $4B
  EndEnumeration
  
  ; FUNCTIONS
  
  Declare AutoScroll(OnOff)
  Declare Blink(OnOff)
  Declare Brightness(Value.b)
  Declare Clear()
  Declare Close()
  Declare Color(Value.l)
  Declare Contrast(Value.b)
  Declare Display(OnOff)
  Declare Home()
  Declare Open(Name.s)
  Declare Position(Column.b, Row.b)
  Declare Write(Text.s)
  Declare WriteAt(Column.b, Row.b, Text.s)
  
EndDeclareModule

;=======================================================

Module LCD
  
  ;=====================================================
  ;== GLOBALS
  ;=====================================================
  
  Global port = 0
  
  ;=====================================================
  ;== PRIVATES
  ;=====================================================
  
  Procedure SendByte(Value.b)
    WriteSerialPortData(port, @Value, 1)
  EndProcedure
  
  Procedure SendCommand(Value.b)
    SendByte(#LCD_COMMAND)
    SendByte(Value)
  EndProcedure
  
  Procedure SendString(Text.s)
    WriteSerialPortString(port, Text, #PB_Ascii)
  EndProcedure
  
  ;=====================================================
  ;== PUBLICS
  ;=====================================================
  
  Procedure AutoScroll(OnOff)
    If OnOff
      SendCommand(#LCD_AUTOSCROLL_ON)
    Else
      SendCommand(#LCD_AUTOSCROLL_OFF)
    EndIf
  EndProcedure
  
  Procedure Blink(OnOff)
    If OnOff
      SendCommand(#LCD_CURSOR_ON)
    Else
      SendCommand(#LCD_CURSOR_OFF)
    EndIf
  EndProcedure
  
  Procedure Brightness(Value.b)
    SendCommand(#LCD_BRIGHTNESS)
    SendByte(Value)
  EndProcedure
  
  Procedure Clear()
    SendCommand(#LCD_DISPLAY_CLEAR)
  EndProcedure
  
  Procedure Close()
    CloseSerialPort(port)
  EndProcedure
  
  Procedure Color(Value.l)
    SendCommand(#LCD_COLOR)
    SendByte(Red(Value))
    SendByte(Green(Value))
    SendByte(Blue(Value))
  EndProcedure
  
  Procedure Contrast(Value.b)
    SendCommand(#LCD_CONTRAST)
    SendByte(Value)
  EndProcedure
  
  Procedure Display(OnOff)
    If OnOff
      SendCommand(#LCD_DISPLAY_ON)
      SendByte(0)
    Else
      SendCommand(#LCD_DISPLAY_OFF)
    EndIf
  EndProcedure
  
  Procedure Home()
    SendCommand(#LCD_CURSOR_HOME)
  EndProcedure
  
  Procedure Open(Name.s)
    port = OpenSerialPort(#PB_Any,Name,9600,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,1024,1024)
    ProcedureReturn port
  EndProcedure
  
  Procedure Position(Column.b, Row.b)
    SendCommand(#LCD_CURSOR_POSITION)
    SendByte(Column)
    SendByte(Row)
  EndProcedure
  
  Procedure Write(Text.s)
    SendString(Text)
  EndProcedure
  
  Procedure WriteAt(Column.b, Row.b, Text.s)
    LCD::Position(Column, Row)
    SendString(Text)
  EndProcedure
  
EndModule

;=======================================================
A very simple clock example :

Image

Code: Select all

IncludeFile "HD44780.pbi"

If LCD::Open("COM3")
  LCD::Display(#True)
  LCD::Color(#Red)
  LCD::Home()
  LCD::Clear()
  If OpenWindow(0, 10, 10, 100, 50, "LCD")
    Repeat
      LCD::WriteAt(4, 1, FormatDate("%dd/%mm/%yyyy", Date()))
      LCD::WriteAt(5, 2, FormatDate("%hh:%ii:%ss", Date()))
    Until WaitWindowEvent(1000) = #PB_Event_CloseWindow
    CloseWindow(0)
  EndIf
  LCD::Display(#False)
  LCD::Close()
EndIf
Another simple example, a basic module player :

Image

Code: Select all

IncludeFile "HD44780.pbi"

Global exit.l = #False

InitSound()

;=======================================================

Procedure update(music)
  
  Protected row, pos, startdate = Date()
  Protected fileName.s  = "AmigaModules\ProjectX_intro.mod"
  Protected filePart.s  = GetFilePart(fileName)
  Protected filePartLen = Len(fileName)
  Protected scrollIndex = 1
  
  If LoadMusic(0, fileName)
    PlayMusic(0)
    fileName = ReplaceString(fileName, ":", "_")
    fileName = ReplaceString(fileName, "/", "_")
    fileName = ReplaceString(fileName, "\", "_")
    LCD::WriteAt(1, 2, "000/000")
    While exit = #False
      LCD::WriteAt(1, 1, LSet(Mid(fileName, scrollIndex, filePartLen - scrollIndex), 16, " "))
      LCD::WriteAt(9, 2, FormatDate("%hh:%ii:%ss", Date()-startdate))
      If pos <> GetMusicPosition(music)
        LCD::WriteAt(1, 2, RSet(Str(pos), 3, "0"))
        pos = GetMusicPosition(music)
      EndIf
      If row <> GetMusicRow(music)
        LCD::WriteAt(5, 2, RSet(Str(row), 3, "0"))
        row = GetMusicRow(music)
      EndIf
      Delay(200)
      scrollIndex + 1
      If scrollIndex > filePartLen
        scrollIndex = 1
      EndIf
    Wend
  EndIf
  
EndProcedure

;=======================================================

If LCD::Open("COM3")
  LCD::Display(#True)
  LCD::Color(#Blue)
  LCD::Home()
  LCD::Clear()
  If OpenWindow(0, 10, 10, 100, 50, "LCD")
    Thread0 = CreateThread(@update(), 0)
    Repeat
    Until WaitWindowEvent() = #PB_Event_CloseWindow
    CloseWindow(0)
    exit = #True
  EndIf
  WaitThread(Thread0)
  LCD::Display(#False)
  LCD::Close()
EndIf
Last edited by Flype on Sun Aug 30, 2015 8:59 pm, edited 1 time in total.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
metalos
User
User
Posts: 27
Joined: Thu Apr 19, 2012 8:32 am

Re: Module LCD HD44780

Post by metalos »

Very cool...
Fred
Administrator
Administrator
Posts: 16686
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Module LCD HD44780

Post by Fred »

Nice !
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Re: Module LCD HD44780

Post by Flype »

Next step, something like this links, based on characters customization (not my vids) :

https://youtu.be/pqv48FtHm0E
https://youtu.be/HugwQ4b9iBU
https://youtu.be/4wjj0Xcu2F8
https://youtu.be/RtiVHo-jvmQ

:twisted:
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
ludoke
Enthusiast
Enthusiast
Posts: 153
Joined: Fri Jul 08, 2016 5:35 pm
Location: Essen (Belgium)

Re: Module LCD HD44780

Post by ludoke »

If LCD::Open("COM3")

I see several times :: in your code, which means that.
I can not find it in the purebasic help.
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Module LCD HD44780

Post by davido »

@ludoke,
It is the separator or delimeter used to access modules. Look under the heading: Arrays, Lists & Structures in the manual:
Manual wrote:To access a module item from outside the Module, the module name has to be specified followed by the '::' separator.
There is also a more general way of accessing Modules described therein.
DE AA EB
ludoke
Enthusiast
Enthusiast
Posts: 153
Joined: Fri Jul 08, 2016 5:35 pm
Location: Essen (Belgium)

Re: Module LCD HD44780

Post by ludoke »

Many thanks,
much respect, the manual has 1660pages , to all that is impossible for me to remember and understand.
Post Reply