合宙ESP32C3点亮1.54寸墨水屏-Arduino中文社区 - Powered by Discuz! Archiver

topdog 发表于 2022-8-12 00:53

合宙ESP32C3点亮1.54寸墨水屏

本帖最后由 topdog 于 2022-8-18 07:23 编辑


这款墨水屏型号是GDEP015OC1。
e ink outdoor display,Anti UV display,(Out of Stock)1.54 inch e-paper display anti-ultraviolet (e-paper-display.com)

GxEPD2库显示GDEP015OC1不再可用,这款亚马逊已经下架。
GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7)); // GDEP015OC1 no longer available

1,安装的库文件:


2,接线:

Eink    ESP32C3
GND   GND
VCC   3.3V
SCL   GPIO2
SDA   GPIO3
RES   GPIO10
DC      GPIO6
CS      GPIO7
BUSY    GPIO8

3,程序如下:

(1)显示库图片和文字。
// include library, include base class, make path known
#include <GxEPD.h>

// select the display class to use, only one
#include <GxGDEP015OC1/GxGDEP015OC1.h>    // 1.54" b/w

#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>

// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>

#include GxEPD_BitmapExamples

const int Eink_SCL =2;
const int Eink_SDA =3;
const int Eink_RES =10;
const int Eink_DC =6;
const int Eink_CS =7;
const int Eink_BUSY =8;

SPIClass EinkSPI(SPI);
GxIO_Class io(EinkSPI, /*CS=5*/ Eink_CS, /*DC=*/Eink_DC, /*RST=*/ Eink_RES); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ Eink_RES, /*BUSY=*/Eink_BUSY); // arbitrary selection of (16), 4


//#define DEMO_DELAY 3*60 // seconds
//#define DEMO_DELAY 1*60 // seconds
#define DEMO_DELAY 2

void setup(void)
{
Serial.begin(115200);
EinkSPI.begin(Eink_SCL ,-1, Eink_SDA, Eink_CS);
Serial.println();
Serial.println("setup");
display.init(115200); // enable diagnostic output on Serial
Serial.println("setup done");
}

void loop()
{
display.drawExampleBitmap(BitmapExample1, sizeof(BitmapExample1));
delay(DEMO_DELAY * 100);
display.drawPaged(showFontCallback);
display.powerDown();
delay(DEMO_DELAY * 100);
}

void showFontCallback()
{
const char* name = "FreeMonoBold9pt7b";
const GFXfont* f = &FreeMonoBold9pt7b;
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setFont(f);
display.setCursor(0, 0);
display.println();
display.println(name);
display.println(" !\"#$%&'()*+,-./");
display.println("0123456789:;<=>?");
display.println("@ABCDEFGHIJKLMNO");
display.println("PQRSTUVWXYZ[\\]^_");
display.println("`abcdefghijklmno");
display.println("pqrstuvwxyz{|}~ ");
}

(2)显示下载的网络图片

// include library, include base class, make path known
#include <GxEPD.h>

// select the display class to use, only one
#include <GxGDEP015OC1/GxGDEP015OC1.h>    // 1.54" b/w

#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>

const int Eink_SCL =2;
const int Eink_SDA =3;
const int Eink_RES =10;
const int Eink_DC =6;
const int Eink_CS =7;
const int Eink_BUSY =8;

SPIClass EinkSPI(SPI);
GxIO_Class io(EinkSPI, /*CS=5*/ Eink_CS, /*DC=*/Eink_DC, /*RST=*/ Eink_RES); // arbitrary selection of 17, 16
GxEPD_Class display(io, /*RST=*/ Eink_RES, /*BUSY=*/Eink_BUSY); // arbitrary selection of (16), 4

#include <WiFiClient.h>
#include <WiFiClientSecure.h>

const char* ssid   = "你的WiFi";
const char* password = "你的password";
const int httpPort= 80;
const int httpsPort = 443;
const char* fp_api_github_com = "df b2 29 c6 a6 38 1a 59 9d c9 ad 92 2d 26 f5 3c 83 8f a5 87"; // as of 25.11.2020
const char* fp_github_com   = "5f 3f 7a c2 56 9f 50 a4 66 76 47 c6 a1 8c a0 07 aa ed bb 8e"; // as of 25.11.2020
const char* fp_rawcontent   = "8F 0E 79 24 71 C5 A7 D2 A7 46 76 30 C1 3C B7 2A 13 B0 01 B2"; // as of 29.7.2022


const char* certificate_rawcontent =
"-----BEGIN CERTIFICATE-----\n"
"MIIEvjCCA6agAwIBAgIQBtjZBNVYQ0b2ii+nVCJ+xDANBgkqhkiG9w0BAQsFADBh"
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3"
"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD"
"QTAeFw0yMTA0MTQwMDAwMDBaFw0zMTA0MTMyMzU5NTlaME8xCzAJBgNVBAYTAlVT"
"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxKTAnBgNVBAMTIERpZ2lDZXJ0IFRMUyBS"
"U0EgU0hBMjU2IDIwMjAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC"
"AQEAwUuzZUdwvN1PWNvsnO3DZuUfMRNUrUpmRh8sCuxkB+Uu3Ny5CiDt3+PE0J6a"
"qXodgojlEVbbHp9YwlHnLDQNLtKS4VbL8Xlfs7uHyiUDe5pSQWYQYE9XE0nw6Ddn"
"g9/n00tnTCJRpt8OmRDtV1F0JuJ9x8piLhMbfyOIJVNvwTRYAIuE//i+p1hJInuW"
"raKImxW8oHzf6VGo1bDtN+I2tIJLYrVJmuzHZ9bjPvXj1hJeRPG/cUJ9WIQDgLGB"
"Afr5yjK7tI4nhyfFK3TUqNaX3sNk+crOU6JWvHgXjkkDKa77SU+kFbnO8lwZV21r"
"eacroicgE7XQPUDTITAHk+qZ9QIDAQABo4IBgjCCAX4wEgYDVR0TAQH/BAgwBgEB"
"/wIBADAdBgNVHQ4EFgQUt2ui6qiqhIx56rTaD5iyxZV2ufQwHwYDVR0jBBgwFoAU"
"A95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQG"
"CCsGAQUFBwMBBggrBgEFBQcDAjB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGG"
"GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2Nh"
"Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNydDBCBgNV"
"HR8EOzA5MDegNaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRH"
"bG9iYWxSb290Q0EuY3JsMD0GA1UdIAQ2MDQwCwYJYIZIAYb9bAIBMAcGBWeBDAEB"
"MAgGBmeBDAECATAIBgZngQwBAgIwCAYGZ4EMAQIDMA0GCSqGSIb3DQEBCwUAA4IB"
"AQCAMs5eC91uWg0Kr+HWhMvAjvqFcO3aXbMM9yt1QP6FCvrzMXi3cEsaiVi6gL3z"
"ax3pfs8LulicWdSQ0/1s/dCYbbdxglvPbQtaCdB73sRD2Cqk3p5BJl+7j5nL3a7h"
"qG+fh/50tx8bIKuxT8b1Z11dmzzp/2n3YWzW2fP9NsarA4h20ksudYbj/NhVfSbC"
"EXffPgK2fPOre3qGNm+499iTcc+G33Mw+nur7SpZyEKEOxEXGlLzyQ4UfaJbcme6"
"ce1XR2bFuAJKZTRei9AqPCCcUZlM51Ke92sRKw2Sfh3oius2FkOH6ipjv3U/697E"
"A7sKPPcw7+uvTPyLNhBzPvOk\n"
"-----END CERTIFICATE-----\n";


const char* host_rawcontent   = "raw.githubusercontent.com";
const char* path_rawcontent   = "/ZinggJM/GxEPD2/master/extras/bitmaps/";
const char* path_prenticedavid   = "/prenticedavid/MCUFRIEND_kbv/master/extras/bitmaps/";
const char* path_waveshare_c= "/waveshare/e-Paper/master/RaspberryPi_JetsonNano/c/pic/";
const char* path_waveshare_py = "/waveshare/e-Paper/master/RaspberryPi_JetsonNano/python/pic/";

void showBitmapFrom_HTTP(const char* host, const char* path, const char* filename, int16_t x, int16_t y, bool with_color = true);
void showBitmapFrom_HTTPS(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color = true,
                        const char* certificate = certificate_rawcontent);

void setup()
{
Serial.begin(115200);
EinkSPI.begin(Eink_SCL ,-1, Eink_SDA, Eink_CS);
Serial.println();
Serial.println("GxEPD_WiFi_Example");
display.init(115200);


if (!WiFi.getAutoConnect() || ( WiFi.getMode() != WIFI_STA) || ((WiFi.SSID() != ssid) && String(ssid) != "........"))
{
    Serial.println();
    Serial.print("WiFi.getAutoConnect()=");
    Serial.println(WiFi.getAutoConnect());
    Serial.print("WiFi.SSID()=");
    Serial.println(WiFi.SSID());
    WiFi.mode(WIFI_STA); // switch off AP
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
}
int ConnectTimeout = 30; // 15 seconds
while (WiFi.status() != WL_CONNECTED)
{
    delay(500);
    Serial.print(".");
    Serial.print(WiFi.status());
    if (--ConnectTimeout <= 0)
    {
      Serial.println();
      Serial.println("WiFi connect timeout");
      return;
    }
}
Serial.println();
Serial.println("WiFi connected");

// Print the IP address
Serial.println(WiFi.localIP());

drawBitmaps_200x200();
drawBitmaps_other();

Serial.println("GxEPD_WiFi_Example done");
}

void loop(void)
{
}

void drawBitmaps_200x200()
{
int16_t x = (display.width() - 200) / 2;
int16_t y = (display.height() - 200) / 2;
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "logo200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "first200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "second200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "third200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "fourth200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "fifth200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "sixth200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "seventh200x200.bmp", fp_rawcontent, x, y);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_rawcontent, "eighth200x200.bmp", fp_rawcontent, x, y);
delay(2000);
}

void drawBitmaps_other()
{
int16_t w2 = display.width() / 2;
int16_t h2 = display.height() / 2;
showBitmapFrom_HTTP("www.squix.org", "/blog/wunderground/", "chanceflurries.bmp", w2 - 50, h2 - 50, false);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "betty_1.bmp", fp_rawcontent, w2 - 100, h2 - 160);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "betty_4.bmp", fp_rawcontent, w2 - 102, h2 - 126);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "marilyn_240x240x8.bmp", fp_rawcontent, w2 - 120, h2 - 120);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "miniwoof.bmp", fp_rawcontent, w2 - 60, h2 - 80);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "test.bmp", fp_rawcontent, w2 - 100, h2 - 100);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "tiger.bmp", fp_rawcontent, w2 - 160, h2 - 120);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "tiger_178x160x4.bmp", fp_rawcontent, w2 - 89, h2 - 80);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "tiger_240x317x4.bmp", fp_rawcontent, w2 - 120, h2 - 160);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "tiger_320x200x24.bmp", fp_rawcontent, w2 - 160, h2 - 100);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "tiger16T.bmp", fp_rawcontent, w2 - 160, h2 - 100);
delay(2000);
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "woof.bmp", fp_rawcontent, w2 - 100, h2 - 100);
delay(2000);
}

void drawBitmaps_test()
{
int16_t w2 = display.width() / 2;
int16_t h2 = display.height() / 2;
showBitmapFrom_HTTPS(host_rawcontent, path_prenticedavid, "betty_4.bmp", fp_rawcontent, w2 - 102, h2 - 126);
delay(2000);
}

static const uint16_t input_buffer_pixels = 800; // may affect performance

static const uint16_t max_row_width = 1448; // for up to 6" display 1448x1072
static const uint16_t max_palette_pixels = 256; // for depth <= 8

uint8_t input_buffer; // up to depth 24
uint8_t output_row_mono_buffer; // buffer for at least one row of b/w bits
uint8_t output_row_color_buffer; // buffer for at least one row of color bits
uint8_t mono_palette_buffer; // palette buffer for depth <= 8 b/w
uint8_t color_palette_buffer; // palette buffer for depth <= 8 c/w

void drawBitmapFrom_HTTP_ToBuffer(const char* host, const char* path, const char* filename, int16_t x, int16_t y, bool with_color)
{
WiFiClient client;
bool connection_ok = false;
bool valid = false; // valid format to be handled
bool flip = true; // bitmap is stored bottom-to-top
uint32_t startTime = millis();
if ((x >= display.width()) || (y >= display.height())) return;
display.fillScreen(GxEPD_WHITE);
Serial.print("connecting to "); Serial.println(host);
if (!client.connect(host, httpPort))
{
    Serial.println("connection failed");
    return;
}
Serial.print("requesting URL: ");
Serial.println(String("http://") + host + path + filename);
client.print(String("GET ") + path + filename + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "User-Agent: GxEPD_WiFi_Example\r\n" +
               "Connection: close\r\n\r\n");
Serial.println("request sent");
while (client.connected())
{
    String line = client.readStringUntil('\n');
    if (!connection_ok)
    {
      connection_ok = line.startsWith("HTTP/1.1 200 OK");
      if (connection_ok) Serial.println(line);
      //if (!connection_ok) Serial.println(line);
    }
    if (!connection_ok) Serial.println(line);
    //Serial.println(line);
    if (line == "\r")
    {
      Serial.println("headers received");
      break;
    }
}
if (!connection_ok) return;
// Parse BMP header
if (read16(client) == 0x4D42) // BMP signature
{
    int32_t fileSize = read32(client);
    int32_t creatorBytes = read32(client);
    int32_t imageOffset = read32(client); // Start of image data
    int32_t headerSize = read32(client);
    int32_t width= read32(client);
    int32_t height = read32(client);
    uint16_t planes = read16(client);
    uint16_t depth = read16(client); // bits per pixel
    int32_t format = read32(client);
    int32_t bytes_read = 7 * 4 + 3 * 2; // read so far
    (void) creatorBytes;
    if ((planes == 1) && ((format == 0) || (format == 3))) // uncompressed is handled, 565 also
    {
      Serial.print("File size: "); Serial.println(fileSize);
      Serial.print("Image Offset: "); Serial.println(imageOffset);
      Serial.print("Header size: "); Serial.println(headerSize);
      Serial.print("Bit Depth: "); Serial.println(depth);
      Serial.print("Image size: ");
      Serial.print(width);
      Serial.print('x');
      Serial.println(height);
      // BMP rows are padded (if needed) to 4-byte boundary
      uint32_t rowSize = (width * depth / 8 + 3) & ~3;
      if (depth < 8) rowSize = ((width * depth + 8 - depth) / 8 + 3) & ~3;
      if (height < 0)
      {
      height = -height;
      flip = false;
      }
      uint16_t w = width;
      uint16_t h = height;
      if ((x + w - 1) >= display.width())w = display.width()- x;
      if ((y + h - 1) >= display.height()) h = display.height() - y;
      valid = true;
      uint8_t bitmask = 0xFF;
      uint8_t bitshift = 8 - depth;
      uint16_t red, green, blue;
      bool whitish = false;
      bool colored = false;
      if (depth == 1) with_color = false;
      if (depth <= 8)
      {
      if (depth < 8) bitmask >>= depth;
      //bytes_read += skip(client, 54 - bytes_read); //palette is always @ 54
      bytes_read += skip(client, imageOffset - (4 << depth) - bytes_read); // 54 for regular, diff for colorsimportant
      for (uint16_t pn = 0; pn < (1 << depth); pn++)
      {
          blue= client.read();
          green = client.read();
          red   = client.read();
          client.read();
          bytes_read += 4;
          whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
          colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
          if (0 == pn % 8) mono_palette_buffer = 0;
          mono_palette_buffer |= whitish << pn % 8;
          if (0 == pn % 8) color_palette_buffer = 0;
          color_palette_buffer |= colored << pn % 8;
          //Serial.print("0x00"); Serial.print(red, HEX); Serial.print(green, HEX); Serial.print(blue, HEX);
          //Serial.print(" : "); Serial.print(whitish); Serial.print(", "); Serial.println(colored);
      }
      }
      display.fillScreen(GxEPD_WHITE);
      uint32_t rowPosition = flip ? imageOffset + (height - h) * rowSize : imageOffset;
      //Serial.print("skip "); Serial.println(rowPosition - bytes_read);
      bytes_read += skip(client, rowPosition - bytes_read);
      for (uint16_t row = 0; row < h; row++, rowPosition += rowSize) // for each line
      {
      if (!connection_ok || !(client.connected() || client.available())) break;
      delay(1); // yield() to avoid WDT
      uint32_t in_remain = rowSize;
      uint32_t in_idx = 0;
      uint32_t in_bytes = 0;
      uint8_t in_byte = 0; // for depth <= 8
      uint8_t in_bits = 0; // for depth <= 8
      uint16_t color = GxEPD_WHITE;
      for (uint16_t col = 0; col < w; col++) // for each pixel
      {
          yield();
          if (!connection_ok || !(client.connected() || client.available())) break;
          // Time to read more pixel data?
          if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
          {
            uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
            uint32_t got = read8n(client, input_buffer, get);
            while ((got < get) && connection_ok)
            {
            //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
            uint32_t gotmore = read8n(client, input_buffer + got, get - got);
            got += gotmore;
            connection_ok = gotmore > 0;
            }
            in_bytes = got;
            in_remain -= got;
            bytes_read += got;
          }
          if (!connection_ok)
          {
            Serial.print("Error: got no more after "); Serial.print(bytes_read); Serial.println(" bytes read!");
            break;
          }
          switch (depth)
          {
            case 24:
            blue = input_buffer;
            green = input_buffer;
            red = input_buffer;
            whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
            colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
            break;
            case 16:
            {
                uint8_t lsb = input_buffer;
                uint8_t msb = input_buffer;
                if (format == 0) // 555
                {
                  blue= (lsb & 0x1F) << 3;
                  green = ((msb & 0x03) << 6) | ((lsb & 0xE0) >> 2);
                  red   = (msb & 0x7C) << 1;
                }
                else // 565
                {
                  blue= (lsb & 0x1F) << 3;
                  green = ((msb & 0x07) << 5) | ((lsb & 0xE0) >> 3);
                  red   = (msb & 0xF8);
                }
                whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
                colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
            }
            break;
            case 1:
            case 4:
            case 8:
            {
                if (0 == in_bits)
                {
                  in_byte = input_buffer;
                  in_bits = 8;
                }
                uint16_t pn = (in_byte >> bitshift) & bitmask;
                whitish = mono_palette_buffer & (0x1 << pn % 8);
                colored = color_palette_buffer & (0x1 << pn % 8);
                in_byte <<= depth;
                in_bits -= depth;
            }
            break;
          }
          if (whitish)
          {
            color = GxEPD_WHITE;
          }
          else if (colored && with_color)
          {
            color = GxEPD_RED;
          }
          else
          {
            color = GxEPD_BLACK;
          }
          uint16_t yrow = y + (flip ? h - row - 1 : row);
          display.drawPixel(x + col, yrow, color);
      } // end pixel
      } // end line
    }
    Serial.print("bytes read "); Serial.println(bytes_read);
}
Serial.print("loaded in "); Serial.print(millis() - startTime); Serial.println(" ms");
if (!valid)
{
    Serial.println("bitmap format not handled.");
}
}

void showBitmapFrom_HTTP(const char* host, const char* path, const char* filename, int16_t x, int16_t y, bool with_color)
{
Serial.println(); Serial.print("downloading file \""); Serial.print(filename);Serial.println("\"");
drawBitmapFrom_HTTP_ToBuffer(host, path, filename, x, y, with_color);
display.update();
}

void drawBitmapFrom_HTTPS_ToBuffer(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color, const char* certificate)
{
// Use WiFiClientSecure class to create TLS connection
#if USE_BearSSL
BearSSL::WiFiClientSecure client;
#else
WiFiClientSecure client;
#endif
bool connection_ok = false;
bool valid = false; // valid format to be handled
bool flip = true; // bitmap is stored bottom-to-top
uint32_t startTime = millis();
if ((x >= display.width()) || (y >= display.height())) return;
display.fillScreen(GxEPD_WHITE);
Serial.print("connecting to "); Serial.println(host);
#if defined (ESP8266)
client.setBufferSizes(4096, 4096); // doesn't help
if (fingerprint) client.setFingerprint(fingerprint);
#elif defined (ESP32)
if (certificate) client.setCACert(certificate);
#endif
if (!client.connect(host, httpsPort))
{
    Serial.println("connection failed");
    return;
}
Serial.print("requesting URL: ");
Serial.println(String("https://") + host + path + filename);
client.print(String("GET ") + path + filename + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "User-Agent: GxEPD_WiFi_Example\r\n" +
               "Connection: close\r\n\r\n");
Serial.println("request sent");
while (client.connected())
{
    String line = client.readStringUntil('\n');
    if (!connection_ok)
    {
      connection_ok = line.startsWith("HTTP/1.1 200 OK");
      if (connection_ok) Serial.println(line);
      //if (!connection_ok) Serial.println(line);
    }
    if (!connection_ok) Serial.println(line);
    //Serial.println(line);
    if (line == "\r")
    {
      Serial.println("headers received");
      break;
    }
}
if (!connection_ok) return;
// Parse BMP header
if (read16(client) == 0x4D42) // BMP signature
{
    int32_t fileSize = read32(client);
    int32_t creatorBytes = read32(client);
    int32_t imageOffset = read32(client); // Start of image data
    int32_t headerSize = read32(client);
    int32_t width= read32(client);
    int32_t height = read32(client);
    uint16_t planes = read16(client);
    uint16_t depth = read16(client); // bits per pixel
    int32_t format = read32(client);
    int32_t bytes_read = 7 * 4 + 3 * 2; // read so far
    (void) creatorBytes;
    if ((planes == 1) && ((format == 0) || (format == 3))) // uncompressed is handled, 565 also
    {
      Serial.print("File size: "); Serial.println(fileSize);
      Serial.print("Image Offset: "); Serial.println(imageOffset);
      Serial.print("Header size: "); Serial.println(headerSize);
      Serial.print("Bit Depth: "); Serial.println(depth);
      Serial.print("Image size: ");
      Serial.print(width);
      Serial.print('x');
      Serial.println(height);
      // BMP rows are padded (if needed) to 4-byte boundary
      uint32_t rowSize = (width * depth / 8 + 3) & ~3;
      if (depth < 8) rowSize = ((width * depth + 8 - depth) / 8 + 3) & ~3;
      if (height < 0)
      {
      height = -height;
      flip = false;
      }
      uint16_t w = width;
      uint16_t h = height;
      if ((x + w - 1) >= display.width())w = display.width()- x;
      if ((y + h - 1) >= display.height()) h = display.height() - y;
      valid = true;
      uint8_t bitmask = 0xFF;
      uint8_t bitshift = 8 - depth;
      uint16_t red, green, blue;
      bool whitish = false;
      bool colored = false;
      if (depth == 1) with_color = false;
      if (depth <= 8)
      {
      if (depth < 8) bitmask >>= depth;
      //bytes_read += skip(client, 54 - bytes_read); //palette is always @ 54
      bytes_read += skip(client, imageOffset - (4 << depth) - bytes_read); // 54 for regular, diff for colorsimportant
      for (uint16_t pn = 0; pn < (1 << depth); pn++)
      {
          blue= client.read();
          green = client.read();
          red   = client.read();
          client.read();
          bytes_read += 4;
          whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
          colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
          if (0 == pn % 8) mono_palette_buffer = 0;
          mono_palette_buffer |= whitish << pn % 8;
          if (0 == pn % 8) color_palette_buffer = 0;
          color_palette_buffer |= colored << pn % 8;
          //Serial.print("0x00"); Serial.print(red, HEX); Serial.print(green, HEX); Serial.print(blue, HEX);
          //Serial.print(" : "); Serial.print(whitish); Serial.print(", "); Serial.println(colored);
      }
      }
      display.fillScreen(GxEPD_WHITE);
      uint32_t rowPosition = flip ? imageOffset + (height - h) * rowSize : imageOffset;
      //Serial.print("skip "); Serial.println(rowPosition - bytes_read);
      bytes_read += skip(client, rowPosition - bytes_read);
      for (uint16_t row = 0; row < h; row++, rowPosition += rowSize) // for each line
      {
      if (!connection_ok || !(client.connected() || client.available())) break;
      delay(1); // yield() to avoid WDT
      uint32_t in_remain = rowSize;
      uint32_t in_idx = 0;
      uint32_t in_bytes = 0;
      uint8_t in_byte = 0; // for depth <= 8
      uint8_t in_bits = 0; // for depth <= 8
      uint16_t color = GxEPD_WHITE;
      for (uint16_t col = 0; col < w; col++) // for each pixel
      {
          yield();
          if (!connection_ok || !(client.connected() || client.available())) break;
          // Time to read more pixel data?
          if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
          {
            uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
            uint32_t got = read8n(client, input_buffer, get);
            while ((got < get) && connection_ok)
            {
            //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
            uint32_t gotmore = read8n(client, input_buffer + got, get - got);
            got += gotmore;
            connection_ok = gotmore > 0;
            }
            in_bytes = got;
            in_remain -= got;
            bytes_read += got;
          }
          if (!connection_ok)
          {
            Serial.print("Error: got no more after "); Serial.print(bytes_read); Serial.println(" bytes read!");
            break;
          }
          switch (depth)
          {
            case 24:
            blue = input_buffer;
            green = input_buffer;
            red = input_buffer;
            whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
            colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
            break;
            case 16:
            {
                uint8_t lsb = input_buffer;
                uint8_t msb = input_buffer;
                if (format == 0) // 555
                {
                  blue= (lsb & 0x1F) << 3;
                  green = ((msb & 0x03) << 6) | ((lsb & 0xE0) >> 2);
                  red   = (msb & 0x7C) << 1;
                }
                else // 565
                {
                  blue= (lsb & 0x1F) << 3;
                  green = ((msb & 0x07) << 5) | ((lsb & 0xE0) >> 3);
                  red   = (msb & 0xF8);
                }
                whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
                colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
            }
            break;
            case 1:
            case 4:
            case 8:
            {
                if (0 == in_bits)
                {
                  in_byte = input_buffer;
                  in_bits = 8;
                }
                uint16_t pn = (in_byte >> bitshift) & bitmask;
                whitish = mono_palette_buffer & (0x1 << pn % 8);
                colored = color_palette_buffer & (0x1 << pn % 8);
                in_byte <<= depth;
                in_bits -= depth;
            }
            break;
          }
          if (whitish)
          {
            color = GxEPD_WHITE;
          }
          else if (colored && with_color)
          {
            color = GxEPD_RED;
          }
          else
          {
            color = GxEPD_BLACK;
          }
          uint16_t yrow = y + (flip ? h - row - 1 : row);
          display.drawPixel(x + col, yrow, color);
      } // end pixel
      } // end line
    }
    Serial.print("bytes read "); Serial.println(bytes_read);
}
Serial.print("loaded in "); Serial.print(millis() - startTime); Serial.println(" ms");
if (!valid)
{
    Serial.println("bitmap format not handled.");
}
client.stop();
}

void showBitmapFrom_HTTPS(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color, const char* certificate)
{
Serial.println(); Serial.print("downloading file \""); Serial.print(filename);Serial.println("\"");
drawBitmapFrom_HTTPS_ToBuffer(host, path, filename, fingerprint, x, y, with_color, certificate);
display.update();
}

uint16_t read16(WiFiClient& client)
{
// BMP data is stored little-endian, same as Arduino.
uint16_t result;
((uint8_t *)&result) = client.read(); // LSB
((uint8_t *)&result) = client.read(); // MSB
return result;
}

int32_t read32(WiFiClient& client)
{
// BMP data is stored little-endian, same as Arduino.
int32_t result;
((uint8_t *)&result) = client.read(); // LSB
((uint8_t *)&result) = client.read();
((uint8_t *)&result) = client.read();
((uint8_t *)&result) = client.read(); // MSB
return result;
}

#if USE_BearSSL

uint32_t skip(BearSSL::WiFiClientSecure& client, int32_t bytes)
{
int32_t remain = bytes;
uint32_t start = millis();
while (client.connected() && (remain > 0))
{
    if (client.available())
    {
      int16_t v = client.read();
      remain--;
    }
    else delay(1);
    if (millis() - start > 2000) break; // don't hang forever
}
return bytes - remain;
}

uint32_t read(BearSSL::WiFiClientSecure& client, uint8_t* buffer, int32_t bytes)
{
int32_t remain = bytes;
uint32_t start = millis();
while (client.connected() && (remain > 0))
{
    if (client.available())
    {
      int16_t v = client.read();
      *buffer++ = uint8_t(v);
      remain--;
    }
    else delay(1);
    if (millis() - start > 2000) break; // don't hang forever
}
return bytes - remain;
}

#endif

uint32_t skip(WiFiClient& client, int32_t bytes)
{
int32_t remain = bytes;
uint32_t start = millis();
while ((client.connected() || client.available()) && (remain > 0))
{
    if (client.available())
    {
      int16_t v = client.read();
      (void) v;
      remain--;
    }
    else delay(1);
    if (millis() - start > 2000) break; // don't hang forever
}
return bytes - remain;
}

uint32_t read8n(WiFiClient& client, uint8_t* buffer, int32_t bytes)
{
int32_t remain = bytes;
uint32_t start = millis();
while ((client.connected() || client.available()) && (remain > 0))
{
    if (client.available())
    {
      int16_t v = client.read();
      *buffer++ = uint8_t(v);
      remain--;
    }
    else delay(1);
    if (millis() - start > 2000) break; // don't hang forever
}
return bytes - remain;
}

liangfengxiao 发表于 2022-8-13 17:03

你是我的神:lol

topdog 发表于 2022-8-13 17:38

liangfengxiao 发表于 2022-8-13 17:03
你是我的神

一起学习,一起进步。

liangfengxiao 发表于 2022-8-17 11:31

请问,楼主可以使用GXEPD2点亮吗 我折腾了一下点亮不了

topdog 发表于 2022-8-17 21:44

本帖最后由 topdog 于 2022-8-17 22:27 编辑

liangfengxiao 发表于 2022-8-17 11:31
请问,楼主可以使用GXEPD2点亮吗 我折腾了一下点亮不了
这款墨水屏型号是GDEP015OC1。
e ink outdoor display,Anti UV display,(Out of Stock)1.54 inch e-paper display anti-ultraviolet (e-paper-display.com)

GxEPD2库显示GDEP015OC1不再可用,这款亚马逊已经下架。
GxEPD2_BW<GxEPD2_154, MAX_HEIGHT(GxEPD2_154)> display(GxEPD2_154(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7)); // GDEP015OC1 no longer available


驱动:
/*
* Copyright (c) 2019, Mahyar Koshkouei
* Released under ISC License.
*
* Library to operate the GDEP015OC1 display.
*/

#ifndef MK_GDEP015OC1_H
#define      MK_GDEP015OC1_H

/* User required definitions. */
#ifndef MK_GDEP_READ_BUSY_PIN
#error "MK_GDEP_READ_BUSY_PIN was not defined."
#endif

#ifndef MK_GDEP_RESET_DISPLAY
#error "MK_GDEP_SET_RESET_PIN was not defined."
#endif

#ifndef MK_GDEP_SET_DC_PIN
#error "MK_GDEP_SET_DC_PIN was not defined."
#endif

#ifndef MK_GDEP_SET_CS_PIN
#error "MK_GDEP_SET_CS_PIN was not defined."
#endif

#ifndef MK_GDEP_SET_SCLK_PIN
#error "MK_GDEP_SET_SCLK_PIN was not defined."
#endif

#ifndef MK_GDEP_SET_SDI_PIN
#error "MK_GDEP_SET_SDI_PIN was not defined."
#endif

#ifndef MK_GDEP_SEND_SPI_BYTE
#error "MK_GDEP_SEND_SPI_BYTE was not defined."
#endif

/* Display resolution */
#define GDEP015OC1_DISPLAY_WIDTH                200
#define GDEP015OC1_DISPLAY_HEIGHT                200

/* GDEP015OC1 commands */
#define DRIVER_OUTPUT_CONTROL                        0x01
#define BOOSTER_SOFT_START_CONTROL                0x0C
#define GATE_SCAN_START_POSITION                0x0F
#define DEEP_SLEEP_MODE                              0x10
#define DATA_ENTRY_MODE_SETTING                        0x11
#define SW_RESET                              0x12
#define TEMPERATURE_SENSOR_CONTROL                0x1A
#define MASTER_ACTIVATION                        0x20
#define DISPLAY_UPDATE_CONTROL_1                0x21
#define DISPLAY_UPDATE_CONTROL_2                0x22
#define WRITE_RAM                              0x24
#define WRITE_VCOM_REGISTER                        0x2C
#define WRITE_LUT_REGISTER                        0x32
#define SET_DUMMY_LINE_PERIOD                        0x3A
#define SET_GATE_TIME                              0x3B
#define BORDER_WAVEFORM_CONTROL                        0x3C
#define SET_RAM_X_ADDRESS_START_END_POSITION      0x44
#define SET_RAM_Y_ADDRESS_START_END_POSITION      0x45
#define SET_RAM_X_ADDRESS_COUNTER                0x4E
#define SET_RAM_Y_ADDRESS_COUNTER                0x4F
#define TERMINATE_FRAME_READ_WRITE                0xFF

enum lut_selection_e {
      LUT_NONE,      /* Uses previously used LUT? */
      LUT_FULL,
      LUT_PARTIAL
};

const uint8_t lut_full_update[] =
{
    0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22,
    0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88,
    0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51,
    0x35, 0x51, 0x51, 0x19, 0x01, 0x00
};

const uint8_t lut_partial_update[] =
{
    0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

/**
* Transmits a given buffer over SPI.
*
* @param buf buffer to transmit
* @param len length of buffer
*/
void send_spi_buffer(const uint8_t *buf, const uint_fast8_t len)
{
      // Select data transmission
      MK_GDEP_SET_DC_PIN(1);

      // Select display for SPI communication
      MK_GDEP_SET_CS_PIN(0);

      for(uint_fast8_t i = 0; i < len; i++)
                MK_GDEP_SEND_SPI_BYTE(buf);

      MK_GDEP_SET_CS_PIN(1);
}

/**
* Send command over SPI to the display.
*
* @param cmd Command to send.
*/
void send_disp_command(const uint8_t cmd)
{
      // Select command transmission
      MK_GDEP_SET_DC_PIN(0);

      // Select display for SPI communication
      MK_GDEP_SET_CS_PIN(0);

      MK_GDEP_SEND_SPI_BYTE(cmd);

      MK_GDEP_SET_CS_PIN(1);
}

/**
* Waits until the display is idle.
*/
inline void disp_wait_until_idle(void)
{
      while(MK_GDEP_READ_BUSY_PIN);
}

/**
* Initialise the connected display.
*/
inline void init_display(const enum lut_selection_e lut)
{
      MK_GDEP_RESET_DISPLAY();

      send_disp_command(DRIVER_OUTPUT_CONTROL);
      const uint8_t doc_data[] = {
                0xC7, // Low 8 bits for display height
                0x00, // High 8 bits
                0x00
                //      0b00000000
                //          UUUUU
                //               0   GD: Selects gate layout of panel
                //                0SM: Disable interleaved mode
                //               0 TB: Scanning direction of gate driver
      };
      send_spi_buffer(doc_data, sizeof (doc_data));

      send_disp_command(BOOSTER_SOFT_START_CONTROL);
      const uint8_t bssc_data[] = {0xD7, 0xD6, 0x9D};
      send_spi_buffer(bssc_data, sizeof (bssc_data));

      send_disp_command(WRITE_VCOM_REGISTER);
      const uint8_t wvr_data[] = {0xA8};
      send_spi_buffer(wvr_data, sizeof (wvr_data));

      send_disp_command(SET_DUMMY_LINE_PERIOD);
      const uint8_t sdlp_data[] = {0x1A};
      send_spi_buffer(sdlp_data, sizeof (sdlp_data));

      send_disp_command(SET_GATE_TIME);
      const uint8_t sgt_data[] = {0x08};
      send_spi_buffer(sgt_data, sizeof (sgt_data));

      send_disp_command(DATA_ENTRY_MODE_SETTING);
      const uint8_t dems_data[] = {0x03};
      send_spi_buffer(dems_data, sizeof (dems_data));

      switch(lut)
      {
      case LUT_FULL:
                send_disp_command(WRITE_LUT_REGISTER);
                send_spi_buffer(lut_full_update, sizeof (lut_full_update));
                break;
               
      case LUT_PARTIAL:
                send_disp_command(WRITE_LUT_REGISTER);
                send_spi_buffer(lut_partial_update, sizeof(lut_partial_update));
                break;
               
      default:
                break;
      };
}

void disp_set_memory_area(const uint8_t x_start, const uint8_t y_start,
                        const uint8_t x_end, const uint8_t y_end)
{
      send_disp_command(SET_RAM_X_ADDRESS_START_END_POSITION);
      /* x point must be the multiple of 8 or the last 3 bits will be ignored */
      uint8_t set_ramx_addr[] = {(x_start >> 3), (x_end >> 3)};
      send_spi_buffer(set_ramx_addr, sizeof (set_ramx_addr));

      send_disp_command(SET_RAM_Y_ADDRESS_START_END_POSITION);
      uint8_t set_ramy_addr[] = {y_start, 0x00, y_end, 0x00};
      send_spi_buffer(set_ramy_addr, sizeof (set_ramy_addr));
}

void set_memory_pointer(uint8_t x, uint8_t y)
{
      send_disp_command(SET_RAM_X_ADDRESS_COUNTER);
      /* x point must be the multiple of 8 or the last 3 bits will be ignored */
      uint8_t set_ramx_addr_count[] = {x >> 3};
      send_spi_buffer(set_ramx_addr_count, sizeof (set_ramx_addr_count));

      send_disp_command(SET_RAM_Y_ADDRESS_COUNTER);
      uint8_t set_ramy_addr_count[] = {y, 0x00};
      send_spi_buffer(set_ramy_addr_count, sizeof (set_ramy_addr_count));

      disp_wait_until_idle();
}

void disp_clear_frame_memory(const uint8_t color)
{
      disp_set_memory_area(0, 0,
                        GDEP015OC1_DISPLAY_WIDTH - 1, GDEP015OC1_DISPLAY_HEIGHT - 1);
      set_memory_pointer(0, 0);
      send_disp_command(WRITE_RAM);

      // Select data transmission
      MK_GDEP_SET_DC_PIN(1);

      // Select display for SPI communication
      MK_GDEP_SET_CS_PIN(0);

      /* send the colour data */
      uint_fast16_t i = (GDEP015OC1_DISPLAY_WIDTH / 8) * GDEP015OC1_DISPLAY_HEIGHT;
      do
      {
                MK_GDEP_SEND_SPI_BYTE(color);
      }
      while(--i);

      MK_GDEP_SET_CS_PIN(1);
}

void disp_display_frame(void)
{
      send_disp_command(DISPLAY_UPDATE_CONTROL_2);
      const uint8_t duc2_data[] = {0xC4};
      send_spi_buffer(duc2_data, sizeof (duc2_data));

      send_disp_command(MASTER_ACTIVATION);
      send_disp_command(TERMINATE_FRAME_READ_WRITE);

      disp_wait_until_idle();
}

void disp_sleep(void)
{
      send_disp_command(DEEP_SLEEP_MODE);

      const uint8_t sleep_data[] = {0x01};
      send_spi_buffer(sleep_data, sizeof (sleep_data));
}

void disp_set_block(const uint8_t x, const uint8_t y,
                  const uint8_t x_end, const uint8_t y_end,
                  const uint8_t pattern)
{

      uint16_t pixels = (((x_end + 1) - x) * ((y_end + 1) - y));

      disp_set_memory_area(x, y, x_end, y_end);
      set_memory_pointer(x, y);
      send_disp_command(WRITE_RAM);

      // Select data transmission
      MK_GDEP_SET_DC_PIN(1);

      // Select display for SPI communication
      MK_GDEP_SET_CS_PIN(0);

      /* send the pattern data */
      do
      {
                MK_GDEP_SEND_SPI_BYTE(pattern);
      }
      while(--pixels);

      MK_GDEP_SET_CS_PIN(1);
}

void disp_write_image(const uint8_t x, const uint8_t y,
                      const uint8_t x_end, const uint8_t y_end,
                      const uint8_t *img, const uint_fast16_t len)
{
      disp_set_memory_area(x, y, x_end, y_end);
      set_memory_pointer(x, y);
      send_disp_command(WRITE_RAM);

      // Select data transmission
      MK_GDEP_SET_DC_PIN(1);

      // Select display for SPI communication
      MK_GDEP_SET_CS_PIN(0);

      /* send the pattern data */
      for(uint_fast16_t i = 0; i < len; i++)
                MK_GDEP_SEND_SPI_BYTE(img);

      MK_GDEP_SET_CS_PIN(1);
}

#endif      /* MK_GDEP015OC1_H */
页: [1]
查看完整版本: 合宙ESP32C3点亮1.54寸墨水屏