lcdproc / lcdproc

Client/server suite for controlling a wide variety of LCD devices
http://lcdproc.org/
GNU General Public License v2.0
104 stars 86 forks source link

LCD2USB not working with LCDproc but works with LCD Smartie #192

Closed whc2001 closed 1 year ago

whc2001 commented 2 years ago

I have a 2402 LCD module with LCD2USB installed. I tested it on Windows with LCD Smartie and it works well. However when I connected it to my proxmox box and compiled the latest LCDproc from GitHub repo, it does not work at all. After configuration, the backlight would light up, but there is absolutely nothing showing on screen. I wonder if anyone had a similar problem, am I getting a defective unit that is only meant to be used with LCD Smartie, or it's some compatibility issue with LCDproc?

(Yes I tried lcd4linux and it displayed something, but seems like there is some problem with the timing and the screen would garble the first few characters. Also lcd4linux is a little too simple on functionality so LCDproc looks more promising.)

Here is the config I used:

[Server]
DriverPath = /usr/lib/lcdproc/
Driver=hd44780
Hello="Hello World 111111"
Hello="Hello World 222222"

[hd44780]
ConnectionType=lcd2usb
VendorID=0x0403         # Tried with or without
ProductID=0xc630        # Tried with or without
Contrast=500            # Tried with different values, no display
Brightness=1000         # Tried with different values, brightness control works
Backlight=external
Size=24x2
ExtendedMode=yes        # Tried with yes or no
#DelayMult=4            # Tried with or without, 2 through 4
#DelayBus=yes           # Tried with yes or no

And here is what the LCDd outputs when running in foreground with maximum debug level:

LCDd version 0.5dev starting
Protocol version 0.4, API version 0.5
Using Configuration File: /etc/LCDd.conf
Set report level to 5, output to stderr
LCDd 0.5dev, LCDproc Protocol 0.4

(copyright notice)

Server running in foreground
Listening for queries on 127.0.0.1:13666
screenlist_init()
driver_load(name="hd44780", filename="/usr/lib/lcdproc/hd44780.so")
HD44780: using ConnectionType: lcd2usb
HD44780: selecting Model: extended
HD44780: backlight: external
hd44780: Using hd44780_default charmap
hd_init_lcd2usb: device with firmware version 2.00 found
screenlist_process()
screenlist_switch(s=[_server_screen])
screenlist_switch: switched to screen [_server_screen]
screenlist_process()
screenlist_process()
screenlist_process()
screenlist_process()
screenlist_process()
screenlist_process()
screenlist_process()
screenlist_process()
screenlist_process()
screenlist_switch(s=[_server_screen])
screenlist_process()
screenlist_switch(s=[_server_screen])
screenlist_process()
screenlist_switch(s=[_server_screen])
screenlist_process()
screenlist_switch(s=[_server_screen])
screenlist_process()
screenlist_switch(s=[_server_screen])
screenlist_process()
... (the same two lines above keeps on)
whc2001 commented 2 years ago

Seems like the "Display on" command sent by LCDd isn't registered by LCD2USB. I added a log output to the LCD2USB driver and here is the command before text data:

hd44780: Using hd44780_default charmap
hd_init_lcd2usb: device with firmware version 2.00 found
Send: 3b -> 2c 9 28 28
Send: 3b -> 28 8 1 6
Send: 39 -> 2 c 1 6
screenlist_switch: switched to screen [_server_screen]
Send: 28 -> 82 c 1 6          // HERE: 0x0C is the "Display ON Cursor OFF" command
Send: 4b -> 20 4c 43 44    // Text data
Send: 4b -> 70 72 6f 63    // Text data
...

When LCDd is running, I use the LCD2USB Python Library to forcefully inject a "Display ON Cursor OFF" command:

from lcd2usb import LCD
lcd = LCD()
lcd._send(0x38, 0x0C, 0x00); lcd._flush()    # 0x38 assumes "number of bytes in transfer" is zero, but it's only for test the Display ON command..

After executing this the LCD shows the text, although the text offset seems off. So the problem grows to two problems: whether the incorrect offset is because the incorrect "number of bytes in transfer" value, and why the Display ON command sent by LCDd is not executed.

IMG_20211226_181432

ethandicks commented 2 years ago

I have an old (pre-zener-diode) LCD2USB module but I haven't used it in over 10 years. I used to use it with a 40x4 dual-controller LCD panel. In 2008, it seemed to work pretty well.

Looks like the driver was updated to work with libusb-1.0 about eight months ago, so I will see about pulling out my LCD2USB module and checking it against the latest version of LCDproc. In the meantime, if anyone else has the hardware, please feel free to share what version of LCDproc you are using and if it's working for you right now.

woggle65 commented 1 year ago

I just build a LCD2USB device with a 20x4 display and it works perfect with the current git version of lcdproc.

whc2001 commented 1 year ago

I only got one of the counterfeit LCD2USB (with a non-AVR MCU) from China, so maybe that's the problem. It does work with other software though. I have tried everything but still didn't find any workaround for it so I am guessing that's the end.

For anyone in China, note that do NOT buy this exact board if you want to use it with LCDProc. I'll get those several other ones available on Taobao (seems like one of them has an AVR MCU) to test it out next year after going back to China.

image

tomwang221812 commented 1 year ago

I got the same module and the issue as you have when I start the LCDd.

I figure out that the problem may be the senddata mechanism which implement in hd44780-lcd2usb.c is not compatible for this module.

    /* flush buffer if it's full */
    if (p->tx_buf.use_count == LCD2USB_MAX_CMD)
        lcd2usb_HD44780_flush(p);

It seems that this module only support the BUFFER_MAX_CMD=1 and not the same as the original implementation.

So I edit the code hd44780-lcd2usb.h#L11 from 4 to 1 and recompile the program and it works.

/* current protocol supports up to 4 bytes */
#define LCD2USB_MAX_CMD     4

to

/* current protocol supports up to 4 bytes */
#define LCD2USB_MAX_CMD     1

=========================== Ubuntu 18.04 aarch64 with kernel 4.19.125

cat /usr/local/etc/LCDd.conf

[server]
DriverPath = /usr/local/lib/lcdproc/
NextScreenKey = Right
PrevScreenKey = Left
ReportToSyslog = yes
ToggleRotateKey = Enter
Driver=hd44780
ReportLevel=5
ReportToSyslog=yes
Foreground=no

[menu]
DownKey = Down
EnterKey = Enter
MenuKey = Escape
UpKey = Up

[hd44780]
ConnectionType=lcd2usb
Contrast=430
Brightness=1000
OffBrightness=800
Backlight=true
Keypad=yes
Size=20x4
KeyDirect_1=Enter
KeyDirect_2=Down
KeyDirect_3=Escape
DelayBus=false

cat /var/log/syslog

Nov 11 05:56:59 armboard LCDd: LCDd version 0.5dev starting
Nov 11 05:56:59 armboard LCDd: Protocol version 0.4, API version 0.5
Nov 11 05:56:59 armboard LCDd: Using Configuration File: /usr/local/etc/LCDd.conf
Nov 11 05:56:59 armboard LCDd: Set report level to 5, output to syslog
Nov 11 05:56:59 armboard LCDd: Server forking to background
Nov 11 05:56:59 armboard LCDd: Listening for queries on 127.0.0.1:13666
Nov 11 05:56:59 armboard LCDd: screenlist_init()
Nov 11 05:56:59 armboard LCDd: driver_load(name="hd44780", filename="/usr/local/lib/lcdproc/hd44780.so")
Nov 11 05:56:59 armboard LCDd: hd44780: deprecated boolean 'true' for 'Backlight' option found, consider updating configuration !!
Nov 11 05:56:59 armboard LCDd: HD44780: using ConnectionType: lcd2usb
Nov 11 05:56:59 armboard LCDd: HD44780: selecting Model: default
Nov 11 05:56:59 armboard LCDd: HD44780: backlight: external
Nov 11 05:56:59 armboard LCDd: HD44780: Direct key 0: "Enter"
Nov 11 05:56:59 armboard LCDd: HD44780: Direct key 1: "Down"
Nov 11 05:56:59 armboard LCDd: HD44780: Direct key 2: "Escape"
Nov 11 05:56:59 armboard LCDd: hd44780: Using hd44780_default charmap
Nov 11 05:56:59 armboard LCDd: hd_init_lcd2usb: device with firmware version 2.02 found
Nov 11 05:56:59 armboard LCDd: Key "Escape" is now reserved exclusively by client [-1]
Nov 11 05:56:59 armboard LCDd: Key "Enter" is now reserved shared by client [-1]
Nov 11 05:56:59 armboard LCDd: Key "Up" is now reserved shared by client [-1]
Nov 11 05:56:59 armboard LCDd: Key "Down" is now reserved shared by client [-1]
...
whc2001 commented 1 year ago

@tomwang221812 Whoa I never expected that, thanks a lot! I tried to change many things inside the driver, but the command buffer length is one of the things I didn't think of. I'll recompile and try myself to see if it works.

whc2001 commented 1 year ago

@tomwang221812 Finally got some time to test this and you are right. After disabling the tx_buf it worked immediately. Thanks a lot!

As for the display misalignment problem like in the second comment, I found out that it's because ExtendedMode is on. When I remove that it works.

(9OKI$8NZC$SUAH_{8SX12E