数码之家

 找回密码
 立即注册
搜索
查看: 11254|回复: 25

又一汉朔4.2电子墨水屏价签的亚种 WFH0420CZ11

[复制链接]
发表于 2021-9-28 12:37:58 | 显示全部楼层 |阅读模式
本帖最后由 liaodongling 于 2021-9-28 14:07 编辑

某鱼淘到的,外观、型号均跟WFH0420CZ35屏幕的那款墨水屏价签一模一样。WFH0420CZ35一样,也是双驱动IC的墨水屏。但是直接写入WFH0420CZ35的程序没反应。

下面是拆机图,有这款墨水屏的欢迎大家一起来研究

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
发表于 2021-10-13 22:54:55 | 显示全部楼层
试一下我这个固件,直接烧录到小板上,再复位,应该会刷出上下颠倒的价签。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 2021-12-10 08:52:16 | 显示全部楼层
WFH0420CZ35的测试程序有吗?
回复 支持 反对

使用道具 举报

发表于 2023-5-5 15:02:59 | 显示全部楼层
WFH0420CZ11 可以按照 GDEW0154T11 搞驱动,是两片 UC8154 级联驱动的。

打赏

参与人数 1家元 +30 收起 理由
springvirus + 30 熱心助人

查看全部打赏

回复 支持 反对

使用道具 举报

发表于 2023-5-10 22:36:14 | 显示全部楼层
gandalf 发表于 2023-5-5 15:02
WFH0420CZ11 可以按照 GDEW0154T11 搞驱动,是两片 UC8154 级联驱动的。

有例程吗?
回复 支持 反对

使用道具 举报

发表于 2023-9-24 14:47:15 | 显示全部楼层
回复 支持 反对

使用道具 举报

发表于 2024-1-18 14:42:32 | 显示全部楼层
楼主 你发的这个屏驱动起来了么?  能分享一下你的驱动程序么。。。
回复 支持 反对

使用道具 举报

发表于 2024-1-18 14:43:12 | 显示全部楼层
gandalf 发表于 2023-9-24 14:47
可以参考: https://github.com/dotnfc/EPD_mpy_efont/blob/main/examples/panel/epd_cz11.py

效果可以看 ...

你好 你这个视频驱动的程序能分享个么  那个参考的地址打不开了
回复 支持 反对

使用道具 举报

发表于 2024-3-28 15:35:52 | 显示全部楼层
gandalf 发表于 2023-5-5 15:02
WFH0420CZ11 可以按照 GDEW0154T11 搞驱动,是两片 UC8154 级联驱动的。

WFH0420CZ11移植了GDEW0154T11,没有反应
回复 支持 反对

使用道具 举报

发表于 2024-3-31 11:38:57 | 显示全部楼层
仓木 发表于 2024-3-28 15:35
WFH0420CZ11移植了GDEW0154T11,没有反应

咋移植的?分享一下程序呗。46550650@qq.com
回复 支持 反对

使用道具 举报

发表于 2024-3-31 11:41:07 | 显示全部楼层
1065307738 发表于 2024-1-18 14:43
你好 你这个视频驱动的程序能分享个么  那个参考的地址打不开了
  1. #-*- coding:utf-8 -*-
  2. # panel driver, referenced from GDEW0154T11
  3. # FPC Label: WFH0420CZ11
  4. # Panel    : WF0420T1PCZ11
  5. # IC       : UC8154
  6. # Product  : Stellar-XL
  7. # by dotnfc, 2023/09/20
  8. #----------------------------------------------------------------

  9. # image format
  10. #   2-bit grayscale (4 grayscale), horizontal scanning (from left to right), and bottom to top (from bottom to top)
  11. #   200x300 + 200x300 two images

  12. from micropython import const
  13. from machine import SPI, Pin
  14. from time import sleep_ms
  15. from framebuf import *
  16. from logger import *
  17. from board import *
  18. import struct

  19. BUSY = const(0)  # 0=busy, 1=idle

  20. class EPD(FrameBuffer):
  21.     # Display resolution
  22.     WIDTH  = const(400)
  23.     HEIGHT = const(300)
  24.     BUF_SIZE = const(WIDTH * HEIGHT // 8)
  25.    
  26.     def __init__(self):
  27.         self.spi = SPI(1, baudrate=20000000, polarity=0, phase=0, sck=EPD_PIN_SCK, mosi=EPD_PIN_SDA)
  28.         self.spi.init()
  29.         
  30.         self.cs  = EPD_PIN_CS
  31.         self.cs2 = EPD_PIN_CS2
  32.         self.dc  = EPD_PIN_DC
  33.         self.rst = EPD_PIN_RST
  34.         self.busy = EPD_PIN_BUSY
  35.         
  36.         self.cs.init(self.cs.OUT, value=1)
  37.         self.cs2.init(self.cs2.OUT, value=1)
  38.         self.dc.init(self.dc.OUT, value=0)
  39.         self.rst.init(self.rst.OUT, value=0)
  40.         self.busy.init(self.busy.IN)

  41.         self.buf = bytearray(self.BUF_SIZE)
  42.         super().__init__(self.buf, self.WIDTH, self.HEIGHT, MONO_HLSB)
  43.         
  44.     # lut standard
  45.     LUT_VCOM0 = bytearray(b'\x02\x03\x03\x08\x08\x03\x05\x05\x03\x00\x00\x00\x00\x00\x00')
  46.     LUT_W = bytearray(b'\x42\x43\x03\x48\x88\x03\x85\x08\x03\x00\x00\x00\x00\x00\x00')
  47.     LUT_B = bytearray(b'\x82\x83\x03\x48\x88\x03\x05\x45\x03\x00\x00\x00\x00\x00\x00')
  48.     LUT_G1 = bytearray(b'\x82\x83\x03\x48\x88\x03\x05\x45\x03\x00\x00\x00\x00\x00\x00')
  49.     LUT_G2 = bytearray(b'\x82\x83\x03\x48\x88\x03\x05\x45\x03\x00\x00\x00\x00\x00\x00')

  50.     # lut from firmware
  51.     # LUT_VCOM0 = bytearray(b'\x19\x1e\x04\x28\x28\x05\x1e\x19\x04\x00\x00\x00\x00\x00\x00')
  52.     # LUT_W = bytearray(b'\x19\x5e\x04\xa8\x68\x05\x9e\x19\x04\x00\x00\x00\x00\x00\x00')
  53.     # LUT_B = bytearray(b'\x99\x9e\x04\xa8\x68\x05\x5e\x59\x04\x00\x00\x00\x00\x00\x00')
  54.     # LUT_G1 = bytearray(b'\x99\x9e\x04\xa8\x68\x05\x5e\x59\x04\x00\x00\x00\x00\x00\x00')
  55.     # LUT_G2 = bytearray(b'\x99\x9e\x04\xa8\x68\x05\x5e\x59\x04\x00\x00\x00\x00\x00\x00')
  56.    
  57.     def conv_data(self, dat):
  58.         '''Convert 8 bits to a short'''
  59.         result = 0
  60.         for bit_position in range(7, -1, -1):
  61.             bit_value = (dat >> bit_position) & 1  # 获取当前位的值(0或1)
  62.             if bit_value:
  63.                 result = result << 2
  64.             else:
  65.                 result = result << 2 | 3
  66.         return result
  67.    
  68.     def refresh(self, buf = None, full=True):
  69.         '''Update screen contents.
  70.         
  71.         Args:
  72.             - buf: the display contents to screen, can be none to use internal buffer
  73.             - full: whether to update the entire screen, or just the partial of it
  74.         '''
  75.         
  76.         pitch = self.WIDTH // 8
  77.         cx = pitch // 2

  78.         startx = 0
  79.         self.init_full()

  80.         self._command(0x10)
  81.         if buf is not None:
  82.             for _ in range(self.HEIGHT):
  83.                 for x in range(0, cx):
  84.                     self._datax(buf[startx + x], True)   # to ic1
  85.                 for x in range(cx, pitch):
  86.                     self._datax(buf[startx + x], False)  # to ic2
  87.                
  88.                 startx = startx + pitch
  89.         else:
  90.             for _ in range(self.HEIGHT):
  91.                 for x in range(0, cx):
  92.                     self._datax(self.buf[startx + x], True)   # to ic1
  93.                 for x in range(cx, pitch):
  94.                     self._datax(self.buf[startx + x], False)  # to ic2
  95.                
  96.                 startx = startx + pitch
  97.                
  98.         if full:
  99.             self.update_full()
  100.         else:
  101.             self.update_partial()
  102.             
  103.         self.wait_until_idle()

  104.     def _command(self, command, data=None):        
  105.         # command sequence
  106.         self.cs(0)
  107.         self.cs2(0)
  108.         self.dc(0)
  109.         
  110.         if isinstance(command, int):
  111.             command = bytearray([command])
  112.         self.spi.write(command)
  113.         
  114.         self.cs(1)
  115.         self.cs2(1)
  116.         
  117.         # now optional data
  118.         if data is not None:
  119.             if isinstance(data, int):
  120.                 data = bytearray([data])
  121.             self._data(data)

  122.         self.cs(1)
  123.         self.cs2(1)
  124.         
  125.     def _data(self, data):
  126.         # data sequence
  127.         self.cs(0)
  128.         self.cs2(0)
  129.         self.dc(1)
  130.         
  131.         if isinstance(data, int):
  132.             data = bytearray([data])
  133.         self.spi.write(data)
  134.         
  135.         self.cs(1)
  136.         self.cs2(1)
  137.         
  138.     def _datax(self, data, cs1=True):
  139.         '''Write a byte to the panel'''
  140.         # data sequence
  141.         if cs1:
  142.             self.cs(0)
  143.             self.cs2(1)
  144.         else:
  145.             self.cs(1)
  146.             self.cs2(0)

  147.         self.dc(1)
  148.         
  149.         # caller is responsible for making sure: data is integer
  150.         # if not isinstance(data, int):
  151.         #    raise ValueError('data must be an integer')
  152.         
  153.         # convert data to a 4 grayscale format, in BigEndian format
  154.         self.spi.write(struct.pack('>h', self.conv_data(data)))
  155.         
  156.         self.cs(1)
  157.         self.cs2(1)

  158.     def power_on(self):
  159.         self._command(0x04)
  160.         self.wait_until_idle()
  161.         
  162.     def power_off(self):
  163.         self._command(0x02)
  164.         self.wait_until_idle()
  165.         
  166.     def init(self):
  167.         self.init_full()
  168.         
  169.     def init_panel(self, reset=True):
  170.         if reset:
  171.             self.reset()

  172.         self._command(0x01, b'\x07\x00\x0d\x00'); # power setting
  173.         self.power_on()
  174.         
  175.         self._command(0x00, 0xdf); # panel setting: df-bw cf-r
  176.         self._command(0x50, 0x67); # VCOM AND DATA INTERVAL SETTING
  177.         self._command(0x30, 0x2a); # PLL setting
  178.         
  179.         self._command(0x61, b'\xc8\x01\x2c'); # resolution setting
  180.         
  181.         self._command(0x82, 0x0A); # vcom setting
  182.         
  183.     def init_full(self):
  184.         self.init_panel()
  185.         
  186.         self._command(0x20, self.LUT_VCOM0)
  187.         self._command(0x21, self.LUT_W)
  188.         self._command(0x22, self.LUT_B)
  189.         self._command(0x23, self.LUT_G1)
  190.         self._command(0x24, self.LUT_G2)
  191.             
  192.     def init_partial(self):
  193.         self.init_panel(False)
  194.         self._command(0x20, self.LUT_VCOM0)
  195.         self._command(0x21, self.LUT_W)
  196.         self._command(0x22, self.LUT_B)
  197.         self._command(0x23, self.LUT_G1)
  198.         self._command(0x24, self.LUT_G2)
  199.         
  200.     def update_full(self):
  201.         self._command(0xe0, 0x01)   # CASCADE SETTING (CCSET) 0xe0
  202.         self._command(0x12)         # DISPLAY REFRESH (DRF) (R12H)
  203.         sleep_ms(10)
  204.         self.wait_until_idle()

  205.     def update_partial(self):
  206.         self._command(0xe0, 0x01)   # CASCADE SETTING (CCSET) 0xe0
  207.         self._command(0x12)         # DISPLAY REFRESH (DRF) (R12H)
  208.         sleep_ms(100)
  209.         self.wait_until_idle()
  210.         
  211.     def wait_until_idle(self, timeout=4000):
  212.             while self.busy.value() == BUSY:
  213.                 sleep_ms(100)
  214.                 timeout = timeout - 100
  215.                 if timeout <=0 :
  216.                     raise RuntimeError("Timeout out for waiting busy signal")

  217.     def reset(self):
  218.         self.rst(1)
  219.         sleep_ms(10)

  220.         self.rst(0)
  221.         sleep_ms(10)

  222.         self.rst(1)
  223.         sleep_ms(10)

  224.     # specify the memory area for data R/W
  225.     def set_memory_area(self, x_start, y_start, x_end, y_end):
  226.         # self._command(0x11); # set ram entry mode
  227.         # self._data(0x03);    # x increase, y increase : normal mode
  228.   
  229.         # # x point must be the multiple of 8 or the last 3 bits will be ignored
  230.         # self._command(0x44)
  231.         # self._data(x_start // 8)
  232.         # self._data((x_start + x_end - 1) // 8)
  233.         
  234.         # self._command(0x45)
  235.         # self._data(y_start % 256)
  236.         # self._data(y_start // 256)
  237.         # self._data((y_start + y_end - 1) % 256)
  238.         # self._data((y_start + y_end - 1) // 256)
  239.         
  240.         # self._command(0x4e)
  241.         # self._data(x_start // 8)
  242.         # self._command(0x4f)
  243.         # self._data(y_start % 256)
  244.         # self._data(y_start // 256)

  245.         # self.wait_until_idle()
  246.         pass
  247.    
  248.     # to wakeup panel, just call reset() or init()
  249.     def sleep(self):
  250.         self.power_off()
  251.         self._command(0x82, 0x00) # VCOM_DC SETTING (VDCS) (R82H)
  252.         
  253.         self._data(0x01, b'\x02\x00\x00\x00') # POWER SETTING (PWR) (R01H) , gate switch to external
  254.         sleep_ms(100)
  255.         self.power_off()
  256.         #self.wait_until_idle()

  257. def main():
  258.     import time
  259.     epd = EPD()
  260.     epd.init()
  261.    
  262.     epd.fill(1)
  263.     epd.text('Hello world', 10, 60, 0)
  264.    
  265.     epd.line(0, 10, 380, 10, 1)
  266.    
  267.     epd.refresh()
  268.     #time.sleep(1)

  269.     #epd.text('dotnfc here', 0, 10, 0)
  270.     #epd.refresh(full=False)
  271.    
  272.     # epd.sleep()

  273. if __name__ == "__main__":
  274.     main()
复制代码
回复 支持 反对

使用道具 举报

发表于 2024-3-31 21:24:05 | 显示全部楼层
reiyawea 发表于 2021-10-13 22:54
试一下我这个固件,直接烧录到小板上,再复位,应该会刷出上下颠倒的价签。

已经付费下载,这个要怎么用,具体讲讲,谢谢。
回复 支持 反对

使用道具 举报

发表于 2024-4-2 09:15:42 | 显示全部楼层
ygsmzj 发表于 2024-3-31 11:38
咋移植的?分享一下程序呗。

没反应还要分享么,起码也得等成功了啊。
回复 支持 反对

使用道具 举报

发表于 2024-4-4 17:07:59 | 显示全部楼层
仓木 发表于 2024-4-2 09:15
没反应还要分享么,起码也得等成功了啊。

这几个数值能查出来吗?应该是多少?
int BUSY_Pin = 25;
int RES_Pin = 26;
int DC_Pin = 27;
int CS_Pin = 15;
int SCK_Pin = 13;
int SDI_Pin = 14;
回复 支持 反对

使用道具 举报

发表于 2024-4-7 17:30:30 | 显示全部楼层
gandalf 发表于 2023-5-5 15:02
WFH0420CZ11 可以按照 GDEW0154T11 搞驱动,是两片 UC8154 级联驱动的。

GDEW0154T11实测可以驱动wfh0420cz11,但是修改参数后只能显完整显示半边,看msp430的程序是通过对P3OUT发送不同的值实现驱动两块UC8154,但是GDEW0154T11里面没有P3OUT这样的操作方法,仿写类似的代码,修改edpcs2low,和epdcs2high没有效果。大神能给个指导吗?使用esp32驱动板,怎样实现驱动wfh0420cz11的另半边屏幕。(屏确定是好的,msp430例程是可以点亮全屏的)
回复 支持 反对

使用道具 举报

发表于 2024-4-30 12:35:49 | 显示全部楼层
ygsmzj 发表于 2024-4-7 17:30
GDEW0154T11实测可以驱动wfh0420cz11,但是修改参数后只能显完整显示半边,看msp430的程序是通过对P3OUT ...

24pin里面 pin1 拉高试试。我记得是pin1是第2个芯片的CS,其它共用。
回复 支持 反对

使用道具 举报

发表于 2024-4-30 15:33:42 来自手机浏览器 | 显示全部楼层
俺尝试过8266驱动液晶屏,驱动芯片忘记了,也没成功点亮。现在买了imx6ul的板子在学的,文档非常多,挺头疼的,不过还是愿意学。
回复 支持 反对

使用道具 举报

发表于 2024-11-4 18:46:22 | 显示全部楼层
大神,WFH0420CZ35,有这个屏幕的驱动吗
回复 支持 反对

使用道具 举报

发表于 2024-11-8 10:05:51 | 显示全部楼层
高人啊搞人
回复 支持 反对

使用道具 举报

发表于 2024-11-22 08:58:08 | 显示全部楼层
一脚接DC,可以驱动2个一半屏,但下面的程序不会写了,哪位会继续完善代码,把400*300的分2半来输出到屏,我给你代码。
我的代码可以显示左右2个一样的图片
留言给我。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-4 09:48 , Processed in 0.280801 second(s), 12 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表