最新消息:重新回归WordPress,我要比较认真的开始更新我的博客了。

4.2寸墨水屏ESP8266开发实践

杂七杂八 hanlei 8838浏览

之前说过买了个墨水屏ESP8266开发套件,后来发现是网上开源的方案。而且我买的是没有经过作者授权的成品,没有任何服务支持,我是在网上搜了好久才发现原作者发布的方案,虽然有个QQ群但加不进去。所以只能我自己研究了。

墨水屏是Goodisplay 4.2寸黑白红三色墨水屏(GDEH042Z96),产品链接https://www.good-display.cn/product/214.html

疑似原作者的开源项目地址:https://oshwhub.com/duck/4-2-cun-mo-shui-ping-ri-li

原作者的闭源程序

墨水屏的官网有个esp8266的让驱动示例,我下载下来,边试边学。中途还看了墨水屏的产品规格书。总之断断续续琢磨了一个来月,终于把驱动这块弄了个一知半解,可以正常显示想要的图片了。下面给出一下研究成果

//IO定义如下,开发板选的NodeMCU1.0
int BUSY_Pin = D2; 
int RES_Pin = D4;
int DC_Pin = D3;
int CS_Pin = D8;
int SCK_Pin = D5;
int SDI_Pin = D7;

//墨水屏的初始化程序
void EPD_HW_Init(void)
{
    EPD_W21_RST_0;  // Module reset      
    delay(1); //At least 10ms delay 
    EPD_W21_RST_1; 
    delay(1); //At least 10ms delay   
    
    Epaper_READBUSY();    //waiting for the electronic paper IC to release the idle signal
    Epaper_Write_Command(0x12);     //SWRESET
    Epaper_READBUSY();  //waiting for the electronic paper IC to release the idle signal
  
    Epaper_Write_Command(0x74);
    Epaper_Write_Data(0x54);
    Epaper_Write_Command(0x7E);
    Epaper_Write_Data(0x3B);
    Epaper_Write_Command(0x2B);  // Reduce glitch under ACVCOM  
    Epaper_Write_Data(0x04);           
    Epaper_Write_Data(0x63);

    Epaper_Write_Command(0x0C);  // Soft start setting
    Epaper_Write_Data(0x8B);           
    Epaper_Write_Data(0x9C);
    Epaper_Write_Data(0x96);
    Epaper_Write_Data(0x0F);

    Epaper_Write_Command(0x01);  // Set MUX as 300
    Epaper_Write_Data(0x2B);           
    Epaper_Write_Data(0x01);
    Epaper_Write_Data(0x00);     

    //下面是指定墨水屏刷新顺序和刷新矩形位置
    //原程序是从下到上,我改成了从上到下
    Epaper_Write_Command(0x11);  // Data entry mode
    Epaper_Write_Data(0x03);         
    Epaper_Write_Command(0x44); 
    Epaper_Write_Data(0x00); // RAM x address start at 0
    Epaper_Write_Data(0x31); // RAM x address end at 31h(49+1)*8->400
    Epaper_Write_Command(0x45); 
    Epaper_Write_Data(0x00); // RAM y address end at 00h     
    Epaper_Write_Data(0x00);
    Epaper_Write_Data(0x2B);   // RAM y address start at 12Bh     
    Epaper_Write_Data(0x01);
    Epaper_Write_Command(0x3C); // board
    Epaper_Write_Data(0x01); // HIZ

    Epaper_Write_Command(0x18);
    Epaper_Write_Data(0X80);
    Epaper_Write_Command(0x22);
    Epaper_Write_Data(0XB1);  //Load Temperature and waveform setting.
    Epaper_Write_Command(0x20);
    Epaper_READBUSY();    //waiting for the electronic paper IC to release the idle signal
    

    //下面这应该是定义刷新起点坐标
    Epaper_Write_Command(0x4E); 
    Epaper_Write_Data(0x00);
    Epaper_Write_Command(0x4F); 
    Epaper_Write_Data(0x00);
    Epaper_Write_Data(0x00);
}

//用SPI库代替原来的SPI程序,不知道有什么区别
SPI.begin();
SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
void SPI_Write(unsigned char value)                                    
{          
  SPI.transfer(value);                 
}


//通过http流更新屏幕
void getfromhttp_black(){
    WiFiClient client;

    HTTPClient http;

    Serial.print("[HTTP] begin...\n");
    if (http.begin(client, "http://url/black")) {  // HTTP

      Serial.print("[HTTP] GET...\n");
      // start connection and send HTTP header
      int httpCode = http.GET();

      // httpCode will be negative on error
      if (httpCode > 0) {
        
        // HTTP header has been send and Server response header has been handled
        Serial.printf("[HTTP] GET... code: %d\n", httpCode);

        // file found at server
      if (httpCode == 200 || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          int len = http.getSize();
          
          Serial.println(len);
          // create buffer for read
          uint8_t buff[128] = { 0 };
          // get tcp stream
          WiFiClient * stream = &client;
          // read all data from server
          EPD_HW_Init(); //Electronic paper initialization
          Epaper_Write_Command(0x24);   //write RAM for black(0)/white (1)

          while (http.connected() && (len > 0 || len == -1)) {
            // read up to 128 byte
            int c = stream->readBytes(buff, std::min((size_t)len, sizeof(buff)));
            //Serial.printf("readBytes: %d\n", c);
            if (!c) {
              Serial.println("read timeout");
            }
            // write it to Serial
            //Serial.write(buff, c);
             unsigned int i; 
             int dh, dl;  // 16进制的高4位和低4位  
             unsigned char dest; 
             for(i=0;i<128;i=i+2)
             {        
              dest=(getNum(buff[i]) << 4) + getNum(buff[i+1]);
              Epaper_Write_Data(dest);
             }
            if (len > 0) {
              len -= c;
            }
          }
          
      } else {
        Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
      }

      http.end();
    } else {
      Serial.printf("[HTTP} Unable to connect\n");
    }
  }
}

虽然可以随心所欲的更新屏幕了,但依然有很多问题,最大的问题就是不会c++,想要在8266上创建用于更新屏幕的数据太难了,连各种变量类型也搞不清楚。途中试了micopython,比c++好点但是确出现内存不够用的情况。内存放不下一张图片的数据。后来换回C++发现依然无法成功编辑一张图片大小的数组。

这期间发现一个使用同样墨水屏但是用树莓派驱动的开源电子台历,给了我很多帮助,最后干脆直接拿过来用了。

基于Goodisplay 4.2寸黑白红三色墨水屏(GDEH042Z96)和树莓派zero w,制作的墨水屏日历。项目地址:https://github.com/88431844/Ecalender

他这外壳打印的有点粗糙呀

最终我把组建数据这块放到了服务器上,用ESP8266访问网站,获取数据流更新屏幕,效果还不错。粘了个2000毫安的锂电池,充一次电能用一周。

日历这块直接用了上面的开源代码
同样3D打印,这是我买时带的

一时冲动买了这么个玩意儿,还好没有直接吃灰。我把我的驱动和服务器程序传到了gitee上面,有兴趣的可以看看。

https://gitee.com/ghoot/ink-screen-calendar

转载请注明:HANLEI'BLOG » 4.2寸墨水屏ESP8266开发实践