Categories
บทความ

ESP32 Font ภาษาไทยสำหรับจอ LCD

    ในบทความนี้จะแสดงตัวอย่างการสร้าง Font จากโปรแกรม BM Font แปลง Font ที่ได้ไปเป็น Array ภาษาซี และใช้งาน Library font ภาษาไทย สำหรับแสดงผลบนจอ LCD โดยใช้ ESP32 บน Eclipse + esp-idf

ขาสัญญาณของ ESP32 ที่ใช้เชื่อมต่อกับ LCD ILI9341 มีดังนี้

ขา ESP32 ขาของจอ LCD
GPIO12 MISO
GPIO13 MOSI
GPIO14 SCK
GPIO15 CS
GPIO23 DC
GPIO22 RESET
GPIO21 LED Backlight

    วิธีการสร้าง Bitmap font จากโปรแกรม BM Font มีขั้นตอนดังนี้
เริ่มต้นด้วยการเปิดโปรแกรม BM Font ขึ้นมา แล้วเลือกที่เมนู Option -> Font settings แล้วเลือก Font ที่ต้องการแปลงในช่อง Font หรือเลือก Font ที่ไม่ได้ติดตั้งในเครื่องโดยกดที่ปุ่ม Add font file
ทำเครื่องหมายในช่อง OEM แล้วเลือก Font เป็น Thai กำหนดขนาดของ Font ตรง Size โดยขนาดที่เรากำหนดจะเป็นขนาดความสูงของ Font มีหน่วยเป็น Pixel หลังจากที่ตั้งค่าต่างๆเสร็จแล้วก็กดที่ปุ่ม OK

    ขั้นตอนต่อไปคือการเลือกตัวอักษรที่ต้องการแปลงไปเป็น Bitmap font โดยคลิกซ้ายที่ตัวอักษรที่ต้องการใช้งานให้ครบทุกตัว หรือหากต้องการแปลง Font ทุกตัวอักษรให้คลิกขวาแล้วเลือกที่ Select marked subset(s)

  หลังจากนั้นให้คลิกที่เมนู Option -> Export option เพื่อกำหนดรูปแบบของ Font ที่ต้องการแปลง โดยต้องกำหนดขนาดของ Texture ให้ครอบคลุมกับตัวอักษรที่เลือก ตรง File format ในช่อง Textures ให้เลือกเป็น png- Portable Network Graphic หลังจากที่ตั้งค่าต่างๆเสร็จแล้วให้คลิดปุ่ม OK

    หากต้องการดูตัวอย่างรูปของ Font ที่ต้องการแปลง ให้เลือกที่เมนู Option -> Visualize จะมีหน้าต่าง Preview รูปของ Bitmap font ออกมา

    เมื่อตั้งค่าต่างๆเสร็จแล้ว ให้คลิกที่เมนู Option -> Save bitmap font as เพื่อบันทึก Font ที่ต้องการแปลงเป็นรูปภาพ เมื่อคลิดแล้วโปรแกรมจะให้เราตั้งชื่อไฟล์ ในตัวอย่างนี้จะตั้งชื่อไฟล์ว่า loma40 ตาม Font และความสูงที่เลือกไว้ Output ของโปรแกรมนี้จะมีอยู่ 2 ไฟล์คือ loma40.fnt และ loma40.png โดยไฟล์ .fnt จะเป็นตัวเก็บรายละเอียดของตัวอักษรแต่ละตัว ส่วนไฟล์ .png จะเป็น bitmap ที่ได้จาก Font ที่เราแปลง ตัวอย่างดังรูป

    การเลือกใช้ Font มีข้อสำคัญอย่างหนึ่งคือ ต้องเลือก Font ที่สามารถพิมพ์สระได้โดยไม่มีวงกลมแสดงหน้าสระ ตัวอย่างของ Font Loma ที่สามารถพิมพ์สระได้โดยไม่มีวงกลมแสดงหน้าสระ https://www.micro.in.th/esp32-font-converter/national.7z

    หลังจากได้ไฟล์ .fnt และ .png มาแล้ว ให้เข้าไปที่หน้า https://www.micro.in.th/esp32-font-converter เพื่อทำการแปลงไฟล์ Bitmap font ไปเป็น Array ในภาษาซี สำหรับนำไปใช้กับ esp-idf เมื่อเข้าไปที่หน้าเว็บแปลงไฟล์แล้ว ให้เลือกไฟล์ .fnt และ .png แล้วกดปุ่ม Convert ตัว Server ก็จะทำหน้าที่แปลงไฟล์ Bitmap font ไปเป็น Array แล้วให้เราบันทึกไฟล์ดังกล่าวลงบนคอมพิวเตอร์ หลังจากนั้นก็นำไฟล์ดังกล่าวเข้าไปในโปรเจคของ esp-idf ที่สร้างจาก Eclipse เพื่อเรียกใช้ Font จากไฟล์ดังกล่าว
    สำหรับการเรียกใช้งาน Font นั้นทำได้โดยดูจากตัวอย่างดังนี
ใส่ extern const char loma40px[]; ในไฟล์ที่ต้องการใช้ Font ภาษาไทย หรือจะใส่ไว้ใน header file แล้ว include ไปใช้งานก็ได้

#define BLINK_GPIO 2

extern const char loma40px[];

void app_main()
{
    gpio_pad_select_gpio(BLINK_GPIO);
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);

    ili9341_init();

    ili9341_fill_bar(COLOR_WHITE, 0, 0, 240, 320);

    thaifont_set_font((char*)&loma40px);
    while(1) {
        ili9341_fill_bar(COLOR_YELLOW, 0, 0, 240, 120);
        thaifont_set_color(COLOR_RED);
        thaifont_draw_text((char*)"Hello world", 5, 0);
        thaifont_set_color(COLOR_GREEN);
        thaifont_draw_text((char*)"สวัสดีชาวโลก", 5, 40);
        thaifont_set_color(COLOR_BLUE);
        thaifont_draw_text((char*)"0123456789", 5, 80);

        /* Blink off (output low) */
        gpio_set_level(BLINK_GPIO, 0);
        vTaskDelay(1000 / portTICK_PERIOD_MS);

        ili9341_fill_bar(COLOR_CYAN, 0, 0, 240, 120);
        thaifont_set_color(COLOR_GREEN);
        thaifont_draw_text((char*)"0123456789", 5, 0);
        thaifont_set_color(COLOR_BLUE);
        thaifont_draw_text((char*)"Hello world", 5, 40);
        thaifont_set_color(COLOR_RED);
        thaifont_draw_text((char*)"สวัสดีชาวโลก", 5, 80);

        /* Blink on (output high) */
        gpio_set_level(BLINK_GPIO, 1);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

Download source code จาก https://www.micro.in.th/files/esp32/ili9341_thai_font.7z

Categories
บทความ

เชื่อมต่อ ESP32 กับจอ LCD TFT 2.8″

ตัวอย่างการเชื่อมต่อ ESP32 กับจอ LCD 2.8″ โดยตัว TFT Controller จะใช้เบอร์ ILI9341 Interface ของจอจะเป็น SPI โดยขาของ ESP32 ที่ใช้เชื่อมต่อกับจอมีดังนี้

ขา ESP32 ขาของจอ LCD
GPIO12 MISO
GPIO13 MOSI
GPIO14 SCK
GPIO15 CS
GPIO23 DC
GPIO22 RESET
GPIO21 LED Backlight

รูปภาพที่จะนำมาทดสอบกับจอ LCD จะทำการแปลงจากไฟล์รูปภาพบนคอมโดยใช้โปรแกรม LCD Image Converter สามารถดาวน์โหลดได้จาก http://www.riuson.com/lcd-image-converter

ขั้นตอนการ Convert รูปภาพ เพื่อนำไปใช้กับ esp-idf v4.0.1 มีดังนี้
เปิดโปรแกรม LCD Image Converter ขึ้น แล้วเลือกที่เมนู File -> New Image

หลังจากนั้นให้เลือกที่เมนู Image -> Import แล้วเลือกรูปที่ต้องการ Convert

หลังจากนั้นให้เลือกที่เมนู Option -> Conversion แล้วเลือกที่ Tab Image โดยตั้งค่า Block size = 16 bit, Byte order = Big-Endian เสร็จแล้วกดปุ่ม OK ข้อสังเกตุการจัดเรียงข้อมูลในหน่วยความจำของ ESP32 เป็นแบบ Little endian ดังนั้น Byte order ของโปรแกรมนี้น่าจะสลับกันอยู่

หลังจากนั้นให้เลือกที่เมนู File -> Convert All เพื่อแปลงรูปภาพไปเป็น Array ในภาษาซี

หลังจากที่ Convert รูปภาพไปเป็น Array ภาษาซีแล้ว ให้คัดลอกไฟล์ดังกล่าวไปไว้ในโปรเจคที่สร้าง Eclipse หรือ สร้างเองจาก esp-idf ตัวอย่าง Source code โปรเจคดาวน์โหลดได้จาก https://www.micro.in.th/files/esp32/test_ili9341.7z

 

Categories
บทความ

เพิ่ม LCD Controller ใน MPLAB Harmony

การเพิ่ม LCD Controller ใน MPLAB เพื่อให้รองรับ LCD Controller ที่เราจะใช้สามารถทำได้โดยการคัดลอกไฟล์ต่างๆของ LCD Controller ที่มีอยู่แล้วมาแก้ไข วิธีการนี้จะง่ายและเร็วกว่าการเขียนเองใหม่หมด ตัวอย่างนี้จะเป็นการคัดลอก LCD Controller SSD1926 มาแก้ไขเพื่อใช้งานกับ LCD Controller SSD1963 ครับ

เริ่มจากคัดลอกโฟล์เดอร์ framework/driver/gfx/controller/ssd1926 แล้วแก้ไขชื่อเป็น framework/driver/gfx/controller/ssd1963 เสร็จแล้วให้เข้าไปเปลี่ยนชื่อไฟล์จาก ssd1926 เป็น ssd1963 หลังจากนั้นให้แก้ไข Source code ในไฟล์ framework/driver/gfx/controller/ssd1963/drv_gfx_ssd1963.h และ framework/driver/gfx/controller/ssd1963/src/drv_gfx_ssd1963.c ให้เป็นของ SSD1963 ในขั้นตอนการแก้ไข source code นี้จะขอข้ามไปนะครับ เนื่องจากการแก้ไข source code มีรายละเอียดค่อนข้างเยอะ

ต่อไปให้แก้ไข harmony config ในโฟล์เดอร์ framework/driver/gfx/controller/ssd1963/config ดังนี้

drv_gfx_ssd1963.hconfig

menu “SSD1963”

config USE_DRV_GFX_SSD1963_NEEDED
bool

config USE_DRV_GFX_SSD1963
bool “Use SSD1963 Driver?”
select DRIVER
select USE_DRV_PMP_NEEDED
default n if !USE_DRV_GFX_SSD1963_NEEDED
default y if USE_DRV_GFX_SSD1963_NEEDED
—help—
IDH_HTML_Graphics_Driver_Library
—endhelp—
endmenu

ifblock USE_DRV_GFX_SSD1963
file DRV_GFX_SSD1963_H “$HARMONY_VERSION_PATH/framework/driver/gfx/controller/ssd1963/drv_gfx_ssd1963.h” to “$PROJECT_HEADER_FILES/framework/driver/gfx/controller/gfx_ssd1963/drv_gfx_ssd1963.h”
file DRV_GFX_SSD1963_C “$HARMONY_VERSION_PATH/framework/driver/gfx/controller/ssd1963/src/drv_gfx_ssd1963.c” to “$PROJECT_SOURCE_FILES/framework/driver/gfx/controller/gfx_ssd1963/src/drv_gfx_ssd1963.c”
endif

ส่วนไฟล์ drv_gfx_ssd1963_config.h.ftl, drv_gfx_ssd1963_config_template.h, drv_gfx_ssd1963_init.c.ftl, drv_gfx_ssd1963_init_data.c.ftl ให้แก้ไขจาก SSD1926 เป็น SSD1963

สุดท้ายให้เพิ่มข้อความด้านล่างไปในไฟล์ framework/driver/gfx/controller/config/drv_gfx_controller.hconfig

source “$HARMONY_VERSION_PATH/framework/driver/gfx/controller/ssd1963/config/drv_gfx_ssd1963.hconfig”

Categories
บทความ

เพิ่ม LCD Display ใน MPLAB Harmony

วิธีการเพิ่ม LCD Display ใน MPLAB Harmony สามารถทำได้ง่ายๆโดยการคัดลอกไฟล์ของ LCD ที่มีอยู่แล้ว มาแก้ไขให้ตรงกับ LCD ที่เราต้องการครับ
ในตัวอย่างนี้จะคัดลอกไฟล์ LCD ของ truly_7_800x480 มาแก้ไขให้ใช้งานกับจอ LCD MI0700LT ครับ
ขั้นแรกให้คัดลอกโฟล์เดอร์ truly_7_800x480 แล้วเปลี่ยนชื่อเป็น mi0700lt_7_800x480 หลังจากนั้นให้เข้าไปเปลี่ยนชื่อไฟล์ดังนี้
drv_gfx_truly_7_800x480.h เปลี่ยนเป็น drv_gfx_mi0700lt_7_800x480.h
config/truly_7_800x480.hconfig เปลี่ยนเป็น config/mi0700lt_7_800x480.hconfig
เสร็จแล้วให้เข้าไปแก้ไขค่าต่างๆของ LCD ในไฟล์ drv_gfx_mi0700lt_7_800x480.h ให้ตรงกับ LCD ที่เราจะใช้ดังนี้

#define DISP_ORIENTATION 0
#define DISP_HOR_RESOLUTION 800
#define DISP_VER_RESOLUTION 480
#define DISP_DATA_WIDTH 18
#define DISP_HOR_PULSE_WIDTH 1
#define DISP_HOR_BACK_PORCH 46
#define DISP_HOR_FRONT_PORCH 210
#define DISP_VER_PULSE_WIDTH 1
#define DISP_VER_BACK_PORCH 23
#define DISP_VER_FRONT_PORCH 131
#define DISP_INV_LSHIFT 0
#define GFX_LCD_TYPE GFX_LCD_TFT
#define BACKLIGHT_ENABLE_LEVEL 1
#define BACKLIGHT_DISABLE_LEVEL 0
#define TCON_MODULE NULL

ต่อไปก็เข้าไปแก้ไขไฟล์ config/mi0700lt_7_800x480.hconfig ให้เป็นแบบด้านล่าง

menu “MI0700LT 7\” 800×480 (WVGA) Display”

config USE_GFX_MI0700LT_7_800X480_NEEDED
bool

config USE_GFX_MI0700LT_7_800X480
bool “Use MI0700LT 7\” 800×480 (WVGA) Display?”
default n if !USE_GFX_MI0700LT_7_800X480_NEEDED
default y if USE_GFX_MI0700LT_7_800X480_NEEDED
—help—
IDH_HTML_Graphics_Driver_Library
—endhelp—

endmenu

สุดท้ายให้เข้าไปเพิ่มข้อความด้านล่างในไฟล์ framework/driver/gfx/display/config/drv_gfx_display.hconfig

source “$HARMONY_VERSION_PATH/framework/driver/gfx/display/mi0700lt_7_800x480/config/mi0700lt_7_800x480.hconfig”

 

Categories
บทความ

Cubieboard A20 + จอ LCD 7″ MI0700LT

บทความนี้จะอธิบายวิธีการใช้งาน LCD 7″ กับ Cubieboard A20 ครับ
ตัว Cubieboard A20 จะมีขา connector ออกมาสำหรับเชื่อมต่อกับจอ LCD โดยขาสัญญาณที่ใช้เชื่อมต่อจะอยู่ที่ Connector U14 ขาที่ 1-38 รายละเอียดขาสัญญาณและการเชื่อมต่อขาสัญญาณกับจอ LCD MI0700LT สามารถดูได้จากรูปด้านล่างครับ

cubieboard-a20-pinout

cubieboard-a20-mi0700lt
สำหรับไฟล์ kernel ที่ติดมากับบอร์ดนั้น จะยังไม่ได้เปิดใช้งาน LCD interface กับ Cubieboard ดังนั้นเราต้องมาแก้ไขไฟล์ script.bin เอง เพื่อเปิดใช้งาน LCD interface ครับ
ขั้นตอนการเปิดใช้งาน LCD ในไฟล์ script.bin ให้คัดลอกไฟล์ script.bin มาแปลงเป็นไฟล์ script.fex ก่อน (วิธีการแปลง script.bin to script.fex หาอ่านในเว็บของ cubieboard เองนะครับ) หลังจากนั้นก็ใช้ text editor แก้ไขไฟล์ script.fex ดังต่อไปนี้

;——————————————————————————-
;disp init configuration
;
;disp_mode (0:screen0<screen0,fb0> 1:screen1<screen1,fb0> 2:two_diff_screen_diff_contents<screen0,screen1,fb0,fb1>
; 3:two_same_screen_diff_contets<screen0,screen1,fb0> 4:two_diff_screen_same_contents<screen0,screen1,fb0>)
;screenx_output_type (0:none; 1:lcd; 2:tv; 3:hdmi; 4:vga)
;screenx_output_mode (used for tv/hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50 5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60 11:pal 14:ntsc)
;screenx_output_mode (used for vga output, 0:1680*1050 1:1440*900 2:1360*768 3:1280*1024 4:1024*768 5:800*600 6:640*480 10:1920*1080 11:1280*720)
;fbx format (4:RGB655 5:RGB565 6:RGB556 7:ARGB1555 8:RGBA5551 9:RGB888 10:ARGB8888 12:ARGB4444)
;fbx pixel sequence (0:ARGB 1:BGRA 2:ABGR 3:RGBA) — 0 for linux, 2 for android
;lcd0_bright (lcd0 init bright,the range:[0,256],default:197
;lcd1_bright (lcd1 init bright,the range:[0,256],default:197
;——————————————————————————-
[disp_init]
disp_init_enable = 1
disp_mode = 0

screen0_output_type = 1
screen0_output_mode = 5

screen1_output_type = 0
screen1_output_mode = 4

fb0_width = 800
fb0_height = 480
fb0_framebuffer_num = 2
fb0_format = 10
fb0_pixel_sequence = 0
fb0_scaler_mode_enable = 1

fb1_width = 800
fb1_height = 480
fb1_framebuffer_num = 2
fb1_format = 10
fb1_pixel_sequence = 0
fb1_scaler_mode_enable = 0

lcd0_backlight = 197
lcd1_backlight = 197

lcd0_bright = 50
lcd0_contrast = 50
lcd0_saturation = 57
lcd0_hue = 50

lcd1_bright = 50
lcd1_contrast = 50
lcd1_saturation = 57
lcd1_hue = 50

;——————————————————————————-
;lcd0 configuration

;lcd_dclk_freq: in MHZ unit
;lcd_pwm_freq: in HZ unit
;lcd_if: 0:hv(sync+de); 1:8080; 2:ttl; 3:lvds
;lcd_hbp: hsync back porch
;lcd_ht: hsync total cycle
;lcd_vbp: vsync back porch
;lcd_vt: vysnc total cycle *2
;lcd_hv_if: 0:hv parallel 1:hv serial
;lcd_hv_smode: 0:RGB888 1:CCIR656
;lcd_hv_s888_if serial RGB format
;lcd_hv_syuv_if: serial YUV format
;lcd_hspw: hsync plus width
;lcd_vspw: vysnc plus width
;lcd_lvds_ch: 0:single channel; 1:dual channel
;lcd_lvds_mode: 0:NS mode; 1:JEIDA mode
;lcd_lvds_bitwidth: 0:24bit; 1:18bit
;lcd_lvds_io_cross: 0:normal; 1:pn cross
;lcd_cpu_if: 0:18bit; 1:16bit mode0; 2:16bit mode1; 3:16bit mode2; 4:16bit mode3; 5:9bit; 6:8bit 256K; 7:8bit 65K
;lcd_frm: 0:disable; 1:enable rgb666 dither; 2:enable rgb656 dither

;lcd_gpio_0: SCL
;lcd_gpio_1 SDA
;——————————————————————————-
[lcd0_para]
lcd_used = 1

lcd_x = 800
lcd_y = 480
lcd_dclk_freq = 36
lcd_pwm_not_used = 0
lcd_pwm_ch = 0
lcd_pwm_freq = 10000
lcd_pwm_pol = 1
lcd_max_bright = 240
lcd_min_bright = 64
lcd_if = 0
lcd_hbp = 45
lcd_ht = 1057
lcd_vbp = 22
lcd_vt = 1270
lcd_vspw = 1
lcd_hspw = 1
lcd_hv_if = 0
lcd_hv_smode = 0
lcd_hv_s888_if = 0
lcd_hv_syuv_if = 0
lcd_lvds_ch = 0
lcd_lvds_mode = 0
lcd_lvds_bitwidth = 0
lcd_lvds_io_cross = 0
lcd_cpu_if = 0
lcd_frm = 1
lcd_io_cfg0 = 0x00000000
lcd_gamma_correction_en = 0
lcd_gamma_tbl_0 = 0x00000000
lcd_gamma_tbl_1 = 0x00010101
lcd_gamma_tbl_255 = 0x00ffffff

lcd_bl_en_used = 0
lcd_bl_en = port:PH07<1><0><default><1>

lcd_power_used = 0
lcd_power = port:PH08<1><0><default><1>

lcd_pwm_used = 0
lcd_pwm = port:PB02<2><0><default><default>

lcdd0 = port:PD00<2><0><default><default>
lcdd1 = port:PD01<2><0><default><default>
lcdd2 = port:PD02<2><0><default><default>
lcdd3 = port:PD03<2><0><default><default>
lcdd4 = port:PD04<2><0><default><default>
lcdd5 = port:PD05<2><0><default><default>
lcdd6 = port:PD06<2><0><default><default>
lcdd7 = port:PD07<2><0><default><default>
lcdd8 = port:PD08<2><0><default><default>
lcdd9 = port:PD09<2><0><default><default>
lcdd10 = port:PD10<2><0><default><default>
lcdd11 = port:PD11<2><0><default><default>
lcdd12 = port:PD12<2><0><default><default>
lcdd13 = port:PD13<2><0><default><default>
lcdd14 = port:PD14<2><0><default><default>
lcdd15 = port:PD15<2><0><default><default>
lcdd16 = port:PD16<2><0><default><default>
lcdd17 = port:PD17<2><0><default><default>
lcdd18 = port:PD18<2><0><default><default>
lcdd19 = port:PD19<2><0><default><default>
lcdd20 = port:PD20<2><0><default><default>
lcdd21 = port:PD21<2><0><default><default>
lcdd22 = port:PD22<2><0><default><default>
lcdd23 = port:PD23<2><0><default><default>
lcdclk = port:PD24<2><0><default><default>
lcdde = port:PD25<2><0><default><default>
lcdhsync = port:PD26<2><0><default><default>
lcdvsync = port:PD27<2><0><default><default>

;——————————————————————————
;resistive touch panel parameter
;——————————————————————————
[rtp_para]
rtp_used = 1
rtp_screen_size = 7
rtp_regidity_level = 7
rtp_press_threshold_enable = 0
rtp_press_threshold = 0x1f40
rtp_sensitive_level = 0xf
rtp_exchange_x_y_flag = 0

หากต้องการเปิดใช้งาน Resistive touch panel ให้เพิ่มพารามิเตอร์ [rtp_para] ดังตัวอย่างด้านบน หลังจากแก้ไขไฟล์ script.fex แล้ว ให้แปลงเป็น script.bin หลังจากนั้นก็คัดลอกไฟล์ script.bin ไปไว้ที่ Cubieboard แทนไฟล์เดิม

cubieboard-a20-lcd7

การแก้ไขไฟล์ script.bin เพื่อเปิดใช้งาน จะรองรับแค่ linux นะครับ สำหรับ android จะทำไม่ได้ ต้อง compile kernel ใหม่ครับ