Esp8266 墨水屏 图片静态显示-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 512|回复: 0

Esp8266 墨水屏 图片静态显示

[复制链接]
发表于 2022-9-9 08:29 | 显示全部楼层 |阅读模式
话不多说,继续分享,先上用法:1. reset 系统或上电,连接热点 wifiepd  ,打开浏览器,输入网址192.168.4.1,做这步之前把黑白图片先保存好,分辨率120*249 比分辨率小一点(2.13寸),竖版图片,24位 bmp图片  :




打开浏览器后如下图 ,点击选择文件,点击确定。



屏幕会自动刷新,然后图片就上去了。断电就一直显示你需要的图片。上电会重新开始。


再说缺点,这个对图片有要求,只能黑白,彩色的会显示不好(也不是不能用哈,)。也没有判断横竖屏,而且图片需要手动修改, 没有抖动算法,对线条图支持的好一点。灰度基本不能看了。

ps,屏幕是hink E0213A04,E029A1也可以了, 威锋的屏好像只能全局刷新,不好用,没改适配代码,原理应该一样的。

上代码吧,代码也是借鉴别人的,自己不是专业编程,对某些部分看的也不是太懂。希望有高手继续改良分享。注意红色部分,如果换屏需要修改,还有个隐藏功能,看大家能从代码看出来么,哈哈哈
  • //接线定义
  • // mapping from Waveshare 2.9inch e-Paper to Wemos D1 mini
  • // BUSY -> D2(4), RST -> D4(2), DC -> D3(0), CS -> D8(15), CLK -> D5(14), DIN -> D7(13), GND -> GND, 3.3V -> 3.3V
  • // mapping example for AVR, UNO, NANO etc.
  • // BUSY -> 7, RST -> 9, DC -> 8, C S-> 10, CLK -> 13, DIN -> 11
  • // include library, include base class, make path known
  • //epd resolotion 122*250(2.13) ,296x128(2.9)
  • #define  EPDX 122
  • #define  EPDY 250
  • #include <ESP8266WebServer.h>
  • #include <ESP8266WiFi.h>
  • #include <WiFiClient.h>
  • #include <ESP8266HTTPClient.h>
  • #include <FS.h>
  • #include <GxEPD.h>
  • // select the display class to use, only one
  • //#include <GxGDEH029A1/GxGDEH029A1.h>      // 2.9" b/w
  • #include <GxGDE0213B1/GxGDE0213B1.h>      // 2.13" b/w
  • #include <GxIO/GxIO_SPI/GxIO_SPI.h>
  • #include <GxIO/GxIO.h>
  • // FreeFonts from Adafruit_GFX
  • #include <Fonts/FreeMonoBold9pt7b.h>
  • #include <Fonts/FreeMonoBold18pt7b.h>
  • const char mainPageString[] PROGMEM = "<!DOCTYPE html>\r\n\
  • <html>\r\n\
  • <head>\r\n\
  •   <meta http-equiv='Content-type' content='text/html; charset=utf-8'>\r\n\
  •   <title>ESP Monitor</title>\r\n\
  • </head>\r\n\
  • <body>\r\n\
  •   <img src='/logo.bmp' width='128' height='296' />\r\n\
  •   <form method='POST' action='/' enctype='multipart/form-data'>\r\n\
  •   <input type='file' name='update' id='update'><input type='submit' value='提交'></form>\r\n\
  •   文件格式必须为bmp,24位,竖版,屏幕为2.9寸E029A1,分辨率296*128\r\n\ 屏幕为2.13寸E0213,分辨率250*122\r\n\
  • </body>\r\n\
  • </html>";
  • GxIO_Class io(SPI, /*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2); // arbitrary selection of D3(=0), D4(=2), selected for default of GxEPD_Class
  • GxEPD_Class display(io /*RST=D4*/ /*BUSY=D2*/); // default selection of D4(=2), D2(=4)
  • #if defined(_GxGDE0213B1_H_) || defined(_GxGDEH029A1_H_) || defined(_GxGDEW042T2_H_)
  • const uint32_t partial_update_period_s = 2;
  • const uint32_t full_update_period_s = 1 * 60 * 60;
  • #endif
  • unsigned char pic[4736]={0};
  • // 设置mode 按钮
  • const int MODE_PIN = 5; //  可以是0,但是屏幕刷新前要改回output状态
  • ESP8266WebServer server(80);
  • File fsUploadFile;
  • #define BUFFPIXEL 20
  • bool b_setup=false;  // 判断是否为设置模式
  • bool b_wifistatus=false;
  • //========================================
  • // These read 16- and 32-bit types from the SD card file.
  • // BMP data is stored little-endian, Arduino is little-endian too.
  • // May need to reverse subscript order if porting elsewhere.
  • uint16_t read16(File f) {
  •   uint16_t result;
  •   ((uint8_t *)&result)[0] = f.read(); // LSB
  •   ((uint8_t *)&result)[1] = f.read(); // MSB
  •   return result;
  • }
  • uint32_t read32(File f) {
  •   uint32_t result;
  •   ((uint8_t *)&result)[0] = f.read(); // LSB
  •   ((uint8_t *)&result)[1] = f.read();
  •   ((uint8_t *)&result)[2] = f.read();
  •   ((uint8_t *)&result)[3] = f.read(); // MSB
  •   return result;
  • }
  • void bmpDraw(char *filename, uint8_t x, uint8_t y) {
  •   File     bmpFile;
  •   int      bmpWidth, bmpHeight;   // W+H in pixels
  •   uint8_t  bmpDepth;              // Bit depth (currently must be 24)
  •   uint32_t bmpImageoffset;        // Start of image data in file
  •   uint32_t rowSize;               // Not always = bmpWidth; may have padding
  •   uint8_t  sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
  •   uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
  •   boolean  goodBmp = false;       // Set to true on valid header parse
  •   boolean  flip    = true;        // BMP is stored bottom-to-top
  •   int      w, h, row, col;
  •   uint8_t  r, g, b;
  •   uint32_t pos = 0, startTime = millis();
  •   int j=0;
  •    // epd resolotion
  •   if((x >= EPDX) || (y >= EPDY)) return;
  •   Serial.println();
  •   Serial.print("Loading image '");
  •   Serial.print(filename);
  •   Serial.println('\'');
  •   bmpFile = SPIFFS.open(filename,"r");
  •   // Open requested file on SD card
  •   if (!bmpFile) {
  •     Serial.print("File not found");
  •     return;
  •   }
  •   // Parse BMP header
  •   if(read16(bmpFile) == 0x4D42) { // BMP signature
  •     Serial.print("File size: "); Serial.println(read32(bmpFile));
  •     (void)read32(bmpFile); // Read & ignore creator bytes
  •     bmpImageoffset = read32(bmpFile); // Start of image data
  •     Serial.print("Image Offset: "); Serial.println(bmpImageoffset, DEC);
  •     // Read DIB header
  •     Serial.print("Header size: "); Serial.println(read32(bmpFile));
  •     bmpWidth  = read32(bmpFile);
  •     bmpHeight = read32(bmpFile);
  •     if(read16(bmpFile) == 1) { // # planes -- must be '1'
  •       bmpDepth = read16(bmpFile); // bits per pixel
  •       Serial.print("Bit Depth: "); Serial.println(bmpDepth);
  •       if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
  •         goodBmp = true; // Supported BMP format -- proceed!
  •         Serial.print("Image size: ");
  •         Serial.print(bmpWidth);
  •         Serial.print('x');
  •         Serial.println(bmpHeight);
  •         // BMP rows are padded (if needed) to 4-byte boundary
  •         rowSize = (bmpWidth * 3 + 3) & ~3;
  •         // If bmpHeight is negative, image is in top-down order.
  •         // This is not canon but has been observed in the wild.
  •         if(bmpHeight < 0) {
  •           bmpHeight = -bmpHeight;
  •           flip      = false;
  •         }
  •         // Crop area to be loaded
  •         w = bmpWidth;
  •         h = bmpHeight;
  •         //Serial.print("bmpHeight:")  ; Serial.print(h);
  •         //if((x+w-1) >= 296)  w = 296  - x;
  •         //if((y+h-1) >= 128) h = 128 - y;
  •         //Serial.print("bmpHeight:")  ; Serial.print(h);
  •         for (row=0; row<h; row++) { // For each scanline...
  •            String strs="";
  •           // Seek to start of scan line.  It might seem labor-
  •           // intensive to be doing this on every line, but this
  •           // method covers a lot of gritty details like cropping
  •           // and scanline padding.  Also, the seek only takes
  •           // place if the file position actually needs to change
  •           // (avoids a lot of cluster math in SD library).
  •           if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
  •             pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
  •           else     // Bitmap is stored top-to-bottom
  •             pos = bmpImageoffset + row * rowSize;
  •           if(bmpFile.position() != pos) { // Need seek?
  •             bmpFile.seek(pos,SeekSet);
  •             buffidx = sizeof(sdbuffer); // Force buffer reload
  •           }
  •           for (col=0; col<w; col++) { // For each pixel...
  •             // Time to read more pixel data?
  •             if (buffidx >= sizeof(sdbuffer)) { // Indeed
  •               bmpFile.read(sdbuffer, sizeof(sdbuffer));
  •               buffidx = 0; // Set index to beginning
  •             }
  •             // Convert pixel from BMP to TFT format, push to display
  •             b = sdbuffer[buffidx++];
  •             g = sdbuffer[buffidx++];
  •             r = sdbuffer[buffidx++];
  •               if (b==g and b==r and r==g and b>=200)
  •               {
  •                 strs+="0";
  •               }
  •               else
  •                 strs+="1";
  •           } // end pixel
  •            //Serial.println(strs);
  •             //const char *strt = strs.c_str();
  •             unsigned char rt = 0;
  •             for (int i=0; i< strs.length(); i++)  // for every character in the string  strlen(s) returns the length of a char array
  •             {
  •               rt = rt << 1;
  •               rt = rt | (strs & 1);
  •               if( i % 8 ==7)
  •               {
  •                   pic[j]=rt;
  •                   rt=0;
  •                   j++;
  •               }
  •             }
  •         } // end scanline
  •         full_clear();
  •         Serial.println("ready update!")  ; //Serial.print(w)  ; Serial.print(" x ")  ; Serial.println(h)  ;
  •         display.drawBitmap(0, 0, (const uint8_t *)pic, w, h, GxEPD_BLACK);
  •         //display.updateWindow(row, col,w,h, true);
  •         display.update();
  •         Serial.print("Loaded in ");
  •         Serial.print(millis() - startTime);
  •         Serial.println(" ms");
  •       } // end goodBmp
  •     }
  •   }
  •   bmpFile.close();
  •   if(!goodBmp) Serial.println("BMP format not recognized.");
  • }
  • //======================
  • //======================
  • //format bytes
  • String formatBytes(size_t bytes){
  •   if (bytes < 1024){
  •     return String(bytes)+"B";
  •   } else if(bytes < (1024 * 1024)){
  •     return String(bytes/1024.0)+"KB";
  •   } else if(bytes < (1024 * 1024 * 1024)){
  •     return String(bytes/1024.0/1024.0)+"MB";
  •   } else {
  •     return String(bytes/1024.0/1024.0/1024.0)+"GB";
  •   }
  • }
  • //文件格式转换
  • String getContentType(String filename){
  •   if(server.hasArg("download")) return "application/octet-stream";
  •   else if(filename.endsWith(".htm")) return "text/html";
  •   else if(filename.endsWith(".html")) return "text/html";
  •   else if(filename.endsWith(".css")) return "text/css";
  •   else if(filename.endsWith(".js")) return "application/javascript";
  •   else if(filename.endsWith(".png")) return "image/png";
  •   else if(filename.endsWith(".gif")) return "image/gif";
  •   else if(filename.endsWith(".jpg")) return "image/jpeg";
  •   else if(filename.endsWith(".ico")) return "image/x-icon";
  •   else if(filename.endsWith(".xml")) return "text/xml";
  •   else if(filename.endsWith(".pdf")) return "application/x-pdf";
  •   else if(filename.endsWith(".zip")) return "application/x-zip";
  •   else if(filename.endsWith(".gz")) return "application/x-gzip";
  •   return "text/plain";
  • }
  • //读取spiffs中的文件
  • bool handleFileRead(String path){
  •   Serial.println("handleFileRead: " + path);
  •   if(path.endsWith("/")) path += "index.htm";
  •   String contentType = getContentType(path);
  •   String pathWithGz = path + ".gz";
  •   if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)){
  •     if(SPIFFS.exists(pathWithGz))
  •       path += ".gz";
  •     File file = SPIFFS.open(path, "r");
  •     size_t sent = server.streamFile(file, contentType);
  •     file.close();
  •     return true;
  •   }
  •   return false;
  • }
  • //上传文件到spiffs中
  • void handleFileUpload(){
  •   if(server.uri() != "/") return;
  •   HTTPUpload& upload = server.upload();
  •   if(upload.status == UPLOAD_FILE_START){
  •     String filename = upload.filename;
  •     if(!filename.startsWith("/")) filename = "/"+filename;
  •     Serial.print("handleFileUpload Name: "); Serial.println(filename);
  •     SPIFFS.rename("/logo.bmp","/last.bmp");
  •     fsUploadFile = SPIFFS.open("/logo.bmp", "w");
  •     filename = String();
  •   } else if(upload.status == UPLOAD_FILE_WRITE){
  •     //Serial.print("handleFileUpload Data: "); Serial.println(upload.currentSize);
  •     if(fsUploadFile)
  •       fsUploadFile.write(upload.buf, upload.currentSize);
  •   } else if(upload.status == UPLOAD_FILE_END){
  •     if(fsUploadFile)
  •       fsUploadFile.close();
  •     Serial.print("handleFileUpload Size: "); Serial.println(upload.totalSize);
  •     //上传完立即显示图片
  •     //full_clear();
  •     bmpDraw("/logo.bmp", 0, 0);
  •     //休眠最长时间直到按下reset
  •     Serial.print("deepsleep until reset");
  •     ESP.deepSleep(0);
  •   }
  • }
  • void handleRoot()
  • {
  •   server.send(200, "text/html", mainPageString);
  •   server.client().stop();
  • }
  • void uplaodFinish() {
  •   server.send(200, "text/html", mainPageString);
  • }
  • void setup(void){
  •   Serial.begin(115200);
  •   Serial.print("\n");
  • // Serial.setDebugOutput(true);
  •   display.init(); // disable diagnostic output on Serial
  •   display.setTextColor(GxEPD_BLACK);
  •   //display.setRotation(1);
  •   SPIFFS.begin();
  •   {
  •     Dir dir = SPIFFS.openDir("/");
  •     while (dir.next()) {
  •       String fileName = dir.fileName();
  •       size_t fileSize = dir.fileSize();
  •       Serial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
  •     }
  •     Serial.printf("\n");
  •   }
  •   full_clear();
  •   //WIFI INIT
  •   WiFi.disconnect();
  •   //WiFi.mode(WIFI_STA);
  •   String ssid="wifiepd";
  •   WiFi.softAP(ssid.c_str());
  •   Serial.print("Open http://192.168.4.1");
  •   Serial.println(" to see the file browser");
  •   showbrand();
  •   //SERVER INIT
  •   server.on("/", HTTP_GET, handleRoot);
  •   //把上传的数据保存到spiffs
  •   server.on("/", HTTP_POST,[](){uplaodFinish();}, handleFileUpload);
  •   //访问的url没有在找spiffs中找到回复404
  •     //访问的url没有在找spiffs中找到回复404
  •   server.onNotFound([](){
  •     if(!handleFileRead(server.uri()))
  •       server.send(404, "text/plain", "FileNotFound");
  •   });
  •   server.begin();
  •   Serial.println("HTTP server started");
  •   pinMode(MODE_PIN,INPUT_PULLUP);
  •   bool mod_val = digitalRead(MODE_PIN);
  •   delay(3000);
  •   if (mod_val == LOW )
  •   {
  •     bmpDraw("/last.bmp", 0, 0);
  •     //休眠最长时间直到按下reset
  •     Serial.print("deepsleep until reset");
  •     ESP.deepSleep(0);
  •   }
  • }
  • void loop(void){
  •   server.handleClient();
  • }
  • void showbrand()
  • {
  •   //display.drawBitmap(60, 0, ewm, 254, 122, GxEPD_BLACK);
  •   display.setTextColor(GxEPD_BLACK);
  •   display.setFont(&FreeMonoBold18pt7b);
  •   display.setCursor(10, 0);
  •   display.println();
  •   //display.println("0123456789:;<=>?");
  •   display.println(" WIFI");
  •   display.println(" PIC");
  •   display.println();
  •   display.setFont(&FreeMonoBold9pt7b);
  •   display.println("WIFI:");
  •   display.println("wifiepd");
  •   display.println();
  •   display.println("open 192.168.4.1 update pic!");
  •   //display.updateWindow(0, 0, 250, 122, true);
  •   display.update();
  • }
  • void stopWiFiAndSleep() {
  •   //WiFi.disconnect();
  •   //WiFi.mode(WIFI_OFF);
  •   //Serial.println("WIFI sleep");
  •   wifi_set_sleep_type(LIGHT_SLEEP_T);
  •   //WiFi.forcelseepBegin();
  •   delay(1);
  • }
  • void full_clear()
  • {
  •      display.fillScreen(GxEPD_WHITE);
  •      display.update();
  •     delay(200);
  • }


[color=#336699 !important]复制代码


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

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-1 05:40 , Processed in 0.087797 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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