Edited at

cairoでLCDに表示

FTDIのFT245Rにグラフィック有機ELモジュール(とりあえずLCD)をつないで、mruby-cairoでデータを作り表示してみました。いつものように環境はFreeBSD 12-Currentです。

LCDは4bitモードで利用して、データ4本のコントロール3本の接続にしています。

mrubyはmruby-cairomruby-ftdiを入れてZRouterビルドしています。

#

# LCD sample code on libftdi
#

class LCD4
RW = 0x10
RS = 0x20
E = 0x40

def lcd4init()
@ftdi = Ftdi.new(0x6001, 0xff)
@ftdi.baudrate(115200)
@cache = 0
self.out(0)
end

def out(ch)
@ftdi.write([ch])
end

def cmd(ch)
arr = Array.new
c = (ch >> 4)
arr << c
arr << (c | E)
arr << c
c = (ch & 0xf)
arr << c
arr << (c | E)
arr << c
if @chache == 1 then
@garr << arr
else
@ftdi.write(arr)
end
end

def data(ch)
arr = Array.new
c = (ch >> 4) | RS
arr << c
arr << (c | E)
arr << c
c = (ch & 0xf) | RS
arr << c
arr << (c | E)
arr << c
if @chache == 1 then
@garr << arr
else
@ftdi.write(arr)
end
end

def start()
@cache = 1
@garr = Array.new
end

def flash()
@ftdi.write(@garr)
end
end

class HD44780 < LCD4
Clear_Display = 0x10
Return_Home = 0x02
Set_Entry_Mode = 0x04
Set_Display = 0x08
Set_Cursor_and_Display_Shift = 0x10
Set_Function = 0x20
Set_CGRAM_Address = 0x40
Set_DDRAM_Address = 0x80

Decrement_Address = 0x00
Increment_Address = 0x02
Shift_Display_Off = 0x00
Shift_Display_On = 0x01

Display_Off = 0x00
Display_On = 0x04
Cursor_Off = 0x00
Cursor_On = 0x02
Blink_Off = 0x00
Blink_On = 0x01

Cursor = 0x00
Display_and_Cursor = 0x08
Left = 0x00
Right = 0x04

Data_Length_4 = 0x00
Data_Length_8 = 0x10
One_Display_Line = 0x00
Two_Display_Lines = 0x08
Font_5x7 = 0x00
Font_5x10 = 0x04

def initialize()
lcd4init
cmd(Set_Function)
usleep(1000)
cmd((Set_Function | Data_Length_4) >> 4 )
usleep(100)
cmd((Set_Function | Data_Length_4) | Two_Display_Lines)
usleep(100)
cmd(0x06)
usleep(100)
cmd(0x0f)
usleep(100)
cmd(0x1f)
usleep(100)
cmd(Return_Home)
end
end

def copylcd(c, t)
for n in 1..2 do
rgba = c.getpix(0, 8 * (n - 1), 100 * 8)
t.start
t.cmd(0x40 + (n - 1))
for i in 1..100 do
t.cmd(0x80 + (i - 1))
pat = 0
for k in 1..8 do
if rgba[1 + (i - 1) * 4 + 100 * (k - 1) * 4] == 0xff
bit = 1
else
bit = 0
end
pat = pat | bit << (k - 1)
end
t.data(pat)
end
t.flash
end
end

t = HD44780.new

c = Cairo.new(100,16)

c.set_source_rgb(1, 1, 1)
c.set_line_width(1)
c.rectangle(0.5, 0.5, 99, 15)
c.stroke();

c.move_to(20, 12)
c.set_source_rgb(1, 1, 1)
c.font_create("/tmp/6x13.pcf")
c.set_font_size(13)
c.show_text("mruby cairo")
c.stroke();

copylcd(c, t)

IMGP0080.JPG

白黒(単色)なので0xffかそれ以外で処理しています。

rectangleがx,yともに0.5になっているのはcairoではこのx,yを中心にしてwidthのラインを引くためです。0,0だと上と下のピクセルにまたがりデータを拾うと0xffになっていませんでした。

斜めの線はピクセルが0xffにならないので、このコードでは引けません。

漢字も表示できます。

写真(2019-04-04 09.34).jpg

これはk8x12ですが、12ポイントくらいが収まりがよいです。

FreeBSDのツリーにパラレルポートを使ってLCDをコントロールするサンプルコードがありました。最近ではパラレルポートが付いたマシンはほとんどありませんが。

https://svnweb.freebsd.org/base/head/share/examples/ppi/