Skip to content

CrowPanel ESP32 E-Paper 5.79-inch Arduino Tutorial

Overall


This tutorial will demonstrate how to use ESP32 E-Paper Display as a price tags and update price images through WiFi and Bluetooth. And how to obtain weather information and display it on ESP32 E-paper display. In addition, there are simple examples to illustrate how to use the various interfaces on the board.

Get Started with Arduino IDE


Please click the card below to learn how to install Arduino IDE, and install ESP32 board in the Arduino IDE.

GetStartedWithArduinoIDE.png

Demo 1 Update Pictures Wireless


This demo will introduce how to wireless update a single price tag through WiFi and Bluetooth.

Update via WiFi

wifi-flow

Convert the image format

First, let's take a look at the price tag we design in this example, which is divided into three parts(all are images). The top bar is a fixed and unchanging background. On the left is the description, and on the right is the price. The parts we need to update are the description and price.

price-tag

For the fixed top bar, we can convert it to C array and put them in the code.

For the variable description and price, we need to convert them to bin file and upload them to the board through WiFi.

  1. downloadthe price tag pictures.

    pictures

  2. download the image modulo tool Image2Lcd and open it.

    imagelcd

  3. Click open and select top-bar.bmp, convert it to array format.

    • Open file
    • Output date type: C language array by default
    • The biggest width and height: Consistent with the width and height of the image. Note that it must be a multiple of 8, otherwise it cannot be displayed properly
    • Save and output

    top-bar-array

    You can put this array in a suitable header file, and I have placed it in Ap_29demo. h here.

    bg-top-array

  4. Convert the description pictures and price tag pictures to bin files. These bin files will be used to update prices over WiFi.

    • Open the file
    • The output type select .bin file
    • The width and height should consistent with the width and height of the image. Note that it must be a multiple of 8, otherwise it cannot be displayed properly
    • Save the file

    price-bin

    description-bin

Code Explanation

Please click download to download the code file 5.79_WIFI_refresh.zip for this demo.

Add necessary libraries

#include <Arduino.h>     // Includes Arduino core library files
#include "EPD.h"         // Includes library files for electronic paper screens
#include "Ap_29demo.h"   // Includes custom function libraries
#include "FS.h"          // File system library for file operations
#include "SPIFFS.h"      // SPIFFS file system library for file reading and writing
#include <WiFi.h>        // WiFi library for creating and managing WiFi connections
#include <Ticker.h>      // Ticker library for timing operations
#include <WebServer.h>   // WebServer library for creating HTTP servers

Define the file variable fsUploadFile Used for accessing files, txt_size and pre_size correspond to the size of the BIN file(Exported in the above steps) for the text label and price label to be transmitted. The image resolution requirement is smaller than the screen resolution and both width and height are multiples of 8.

//Object for storing uploaded files
File fsUploadFile; //Used to manipulate files in the SPIFFS file system
#define txt_size 6768 // Define the size of the description picture file
#define pre_size 5888 // Define the size of the price tag picture file

Note: The size here can be defined based on the size of the images to be transmitted later, otherwise it will cause image transfer failure

Receive the bin file sent and determine if it matches the pre-set file size. If it matches, store it in the file system and update the display icon

// Handling requests to upload files
void okPage()
{
  server.send(200, "text/html", HTML_OK); // Successfully sent page
  HTTPUpload &upload = server.upload();    // Retrieve the uploaded file object

  // Note: The initialization size of upload.buf is only 1436 bytes and needs to be adjusted to support uploading large files
  // Modify the HTTP-UPLOAD_SUFLEN definition in the WebServer. h file to increase the initial size to 14360 bytes
  if (upload.status == UPLOAD_FILE_END) // File upload completed
  {
    Serial.println("draw file");
    Serial.println(upload.filename);  // Print and upload file name
    Serial.println(upload.totalSize); // Total size of printed files

    // Determine the size of the uploaded file and determine the file type
    if (upload.totalSize == 6768) // If the file size is 6768 bytes, it is a txt file
      filename = "txt.bin";
    else
      filename = "pre.bin"; // Otherwise, it is a preview file

    // Save the received file
    if (!filename.startsWith("/")) filename = "/" + filename;
    fsUploadFile = SPIFFS.open(filename, FILE_WRITE); // Open file for write mode
    fsUploadFile.write(upload.buf, upload.totalSize); // Write file data
    fsUploadFile.close(); // close file
    Serial.println("保存成功");
    Serial.printf("保存:");
    Serial.println(filename);

    // Store data into the corresponding array based on file size
    if (upload.totalSize == txt_size)
    {
      for (int i = 0; i < 6768; i++) {
        txt_formerly[i] = upload.buf[i];
      }
      Serial.println("txt_formerly OK");
      flag_txt = 1; // Set a flag to indicate that the txt file has been uploaded
    } 
    else
    {
      for (int i = 0; i < pre_size; i++) {
        price_formerly[i] = upload.buf[i];
      }
      Serial.println("price_formerly OK");
      flag_pre = 1; // Set a flag to indicate that the preview file has been uploaded
    }

    EPD_GPIOInit();            // Initialize GPIO pin configuration for EPD e-ink screen
    EPD_FastMode1Init();       // Initialize EPD screen in Quick Mode 1

    EPD_ShowPicture(0, 0, 792, 40, background_top, WHITE); // Display a background image on the screen with a white background color

    // Display corresponding images based on the type of uploaded file
    if (upload.totalSize != 6768)
    {
        EPD_ShowPicture(500, 80, 256, 184, price_formerly, WHITE); // Display preview image
    }
    else
    {
        EPD_ShowPicture(30, 80, 376, 144, txt_formerly, WHITE); // Display text image
    }

    EPD_Display(ImageBW);      // Display images stored in the ImageBW array
    EPD_FastUpdate();          // Perform quick updates to refresh the screen
    EPD_DeepSleep();          // Set the screen to deep sleep mode to save power
  }
}

Image Refresh Process

  1. Initialization

    // Initialize EPD (Electronic Paper Display) screen
      EPD_GPIOInit();  // Initialize the GPIO pins of EPD
      Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE);  // Create a new canvas with dimensions of EPD_W x EPD_H and a white background color
      Paint_Clear(WHITE);  // Clear the canvas, with a white background color
    
      EPD_FastMode1Init();  // Quick Mode 1 for Initialize EPD
      EPD_Display_Clear();  // Clear EPD display content
      EPD_Update();  // update display
      UI_price();  // Display price information
    
  2. Initialize to fast mode display screen

      EPD_GPIOInit();  // Initialize the GPIO pin configuration of the EPD e-ink screen again
      EPD_FastMode1Init();  // Re initialize the EPD screen in Quick Mode 1
    
  3. Select the data to refresh

      EPD_ShowPicture(0, 0, 792, 40, background_top, WHITE); 
    
  4. Update the image to the screen

      EPD_Display(ImageBW);  // Display images stored in the ImageBW array
      EPD_FastUpdate();  // Perform quick updates to refresh the screen
      EPD_DeepSleep();  // Set the screen to deep sleep mode to save power
    

Upload the Code

  1. Open the 5.79_WIFI_refresh.ino

    open-wifi-refresh

  2. Click "Tools"->"Board"->"esp32"->"ESP32S3 Dev Module", and the "Partition Scheme" select "Huge APP (3MB No OTA/1MB SPIFFS)", "PSRAM" select "OPI PSRAM".

    setting

  3. Connect CorwPanel to the computer, click on "Tool" and select the corresponding "port".

  4. Click "Upload" to upload the code to the board. There will be an image show on the screen.

    upload

Update the price tag with WiFi

  1. Connect a laptop to the hotspot of the ESP32 E-PAPER display.

  2. Enter the IP address 192.168.4.1 in the browser.

    connect-wifi

  3. Select the bin file of the picture you need to show, then click submit.

    Note: The size of the images you transfer must be consistent with the size defined in the code, otherwise it will cause image transfer failure

    bin-size

  4. After successful transmission, the price and text will be replaced, and the data will be saved in flash.

    image-refresh

Update via Bluetooth

bt-flow

Convert the image format

The same as the method in the "Update via WiFi".

Code Explanation

Please click download to download the code file 5.79_ble_refresh.zip for this demo.

Add necessary libraries

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include "Ap_29demo.h"
#include <Arduino.h>
#include "EPD.h"
#include "FS.h"           // File System Library
#include "SPIFFS.h"       // SPIFFS File system library, used for file reading and writing

Define the file variable fsUploadFile Used for accessing files, txt_size and pre_size correspond to the size of the BIN file(Exported in the above steps) for the text label and price label to be transmitted. The image resolution requirement is smaller than the screen resolution and both width and height are multiples of 8

//Object for storing uploaded files
File fsUploadFile; //Used to manipulate files in the SPIFFS file system
#define txt_size 6768 // Define the size of the description picture file
#define pre_size 5888 // Define the size of the price tag picture file

Note: The size here can be defined based on the size of the images to be transmitted later, otherwise it will cause image transfer failure

ble_pic function

Process the bin file sent and determine if it matches the pre-set file size. If it does, store it in the file system and update the display icon.

void ble_pic()
{
  // Check if data has been received
  if (dataReceived) {
    // Ensure that the data buffer is not empty
    if (!dataBuffer.empty()) {
      size_t bufferSize = dataBuffer.size();
      Serial.println(bufferSize);
      if (dataBuffer.size() == txt_size)//txt size
        filename = "txt.bin";
      else
        filename = "pre.bin";
      if (!filename.startsWith("/")) filename = "/" + filename;
      fsUploadFile = SPIFFS.open(filename, FILE_WRITE);
      fsUploadFile.write(dataBuffer.data(), dataBuffer.size());
      fsUploadFile.close();
      Serial.println("保存成功"); //Successfully saved
      Serial.printf("保存:"); //Save: 
      Serial.println(filename);
      if (bufferSize == txt_size )
      {
        for (int i = 0; i < txt_size; i++) {
          txt_formerly[i] = dataBuffer[i];
        }
        //      memcpy(txt_formerly, upload.buf, sizeof(upload.totalSize));
        Serial.println("txt_formerly OK");

      } else
      {
        for (int i = 0; i < pre_size; i++) {
          price_formerly[i] = dataBuffer[i];
        }
        //      memcpy(price_formerly, upload.buf, sizeof(upload.totalSize));
        Serial.println(" price_formerlyOK");

      }

      EPD_GPIOInit();            // Initialize the GPIO pin configuration of the EPD e-ink screen again
      EPD_FastMode1Init();       // Re initialize the EPD screen in Quick Mode 1

      EPD_ShowPicture(0, 0, 792, 40, background_top, WHITE); // Display the gImage_stcenario_home image on the screen with a white background color

      if (bufferSize != txt_size)
      {

        EPD_ShowPicture(500, 80, 256, 184, price_formerly, WHITE); // Display the gImage_stcenario_home image on the screen with a white background color
        //         EPD_ShowPicture(400, 60, 256, 184, price_formerly, WHITE); // Display the gImage_stcenario_home image on the screen with a white background color

      } else
      {
        //          EPD_ShowPicture(400, 60, 256, 184, price_formerly, WHITE); // Display the gImage_stcenario_home image on the screen with a white background color

        EPD_ShowPicture(30, 80, 376, 144, txt_formerly, WHITE); // Display the gImage_stcenario_home image on the screen with a white background color

      }

      EPD_Display(ImageBW);      // Display images stored in the ImageBW array
      EPD_FastUpdate();          // Perform quick updates to refresh the screen
      EPD_DeepSleep();          // Set the screen to deep sleep mode to save power


      // Clear the buffer after writing
      dataBuffer.clear();
      totalReceivedBytes = 0;


      // Clear data buffer
      dataBuffer.clear(); // Clear the buffer after writing
      totalReceivedBytes = 0;


    }

    // Reset the data reception flag after processing the data
    dataReceived = false;
  }
}

// Clear the display screen content
void clear_all()
{
  // Initialize the quick mode of the e-ink screen
  EPD_FastMode1Init();
  // Clear the e-ink screen
  EPD_Display_Clear();
  // Update display screen
  EPD_Update();
}

class MyCallbacks : public BLECharacteristicCallbacks

Receive the data sent and integrate it together. Receiving the "OK" character indicates that the transmission is complete.

// BLE Feature callback class
class MyCallbacks : public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();

      if (value.length() > 0) {
        Serial.printf(".");

        // Assuming that the client sends a specific end marker at the end of data transmission
        if (value == "OK") {
          dataReceived = true;
          return ;
        }

        size_t len = value.length();
        if (len > 0) {
          // Append the received data to the buffer
          dataBuffer.insert(dataBuffer.end(), value.begin(), value.end());
          totalReceivedBytes += len; // Update the total number of bytes received
        }


      }
    }
};

UI_price

Check if the file system has saved UI images, and if so, display them.

// User interface function: Display price information
void UI_price()
{
  EPD_GPIOInit();            // Initialize the GPIO pin configuration of the EPD e-ink screen again
  EPD_FastMode1Init();       // Re initialize the EPD screen in Quick Mode 1
  EPD_ShowPicture(0, 0, 792, 40, background_top, WHITE); // Display the gImage_stcenario_home image on the screen with a white background color


  if (SPIFFS.exists("/txt.bin")) {
    // File exists, read file content
    File file = SPIFFS.open("/txt.bin", FILE_READ);
    if (!file) {
      Serial.println("无法打开文件进行读取"); // Unable to open file for reading
      return;
    }
    // Read data from a file to an array
    size_t bytesRead = file.read(txt_formerly, txt_size);

    Serial.println("File content:");
    while (file.available()) {
      Serial.write(file.read());
    }
    file.close();


    EPD_ShowPicture(30, 80, 376, 144, txt_formerly, WHITE);


  }

  if (SPIFFS.exists("/pre.bin")) {
    // File exists, read file content
    File file = SPIFFS.open("/pre.bin", FILE_READ);
    if (!file) {
      Serial.println("无法打开文件进行读取"); // Unable to open file for reading
      return;
    }
    // Read data from a file to an array
    size_t bytesRead = file.read(price_formerly, pre_size);

    Serial.println("File content:");
    while (file.available()) {
      Serial.write(file.read());
    }
    file.close();



    EPD_ShowPicture(500, 80, 256, 184, price_formerly, WHITE);


  }
  EPD_Display(ImageBW);      // Display images stored in the ImageBW array
  EPD_FastUpdate();          // Perform quick updates to refresh the screen
  EPD_DeepSleep();          // Set the screen to deep sleep mode to save power
}

Image Refresh Process

  1. Initialization

    // Initialize EPD (Electronic Paper Display) screen
      EPD_GPIOInit();  // Initialize the GPIO pins of EPD
      Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE);  // Create a new canvas with dimensions of EPD_W x EPD_H and a white background color
      Paint_Clear(WHITE);  // Clear the canvas, with a white background color
    
      EPD_FastMode1Init();  // Quick Mode 1 for Initialize EPD
      EPD_Display_Clear();  // Clear EPD display content
      EPD_Update();  // update display
      UI_price();  // Display price information
    
  2. Initialize to fast mode display screen

      EPD_GPIOInit();  // Initialize the GPIO pin configuration of the EPD e-ink screen again
      EPD_FastMode1Init();  // Re initialize the EPD screen in Quick Mode 1
    
  3. Select the data to refresh

      EPD_ShowPicture(0, 0, 792, 40, background_top, WHITE); 
    
  4. Update the image to the screen

      EPD_Display(ImageBW);  // Display images stored in the ImageBW array
      EPD_FastUpdate();  // Perform quick updates to refresh the screen
      EPD_DeepSleep();  // Set the screen to deep sleep mode to save power
    

Upload the Code

  1. Double click the 5.79_ble_refresh.ino.

    ble-refresh-ino

  2. Click "Tools"->"Board"->"esp32"->"ESP32S3 Dev Module", and the "Partition Scheme" select "Huge APP (3MB No OTA/1MB SPIFFS)", "PSRAM" select "OPI PSRAM".

    setting-bt

  3. Connect CorwPanel to the computer, click on "Tool" and select the corresponding "port".

  4. Click "Upload" to upload the code to the board. There will be an image show on the screen.

    upload

Update the images via bluetooth

  1. Download a BLE debugging assistant to your phone, and connect it your phone to the screen device BLE.

    connect-ble

  2. Upload the bin file(Save the bin file to your phone in advance).

    Note: The size of the images you transfer must be consistent with the size defined in the code, otherwise it will cause image transfer failure

    upload-image-ble

    upload-image-ble-2

  3. After successful transmission, the price and text will be replaced, and the data will be saved in flash.

    image-refresh

Demo 2 Weather Station


Obtain weather information through OpenWeather and display the information on the CrowPanel.

Convert the image format

First, let's take a look at the weather information panel we design in this example, which is divided into 6 parts(all are images).

5.79

  • weather
  • city
  • humidity
  • wind
  • temperature
  • visibility

We need to convert the images of these 6 parts into C arrays and put them in the code, and combine them to form the UI interface above. The weather icon in the upper left corner is variable, while the other icons are fixed.

  1. downloadthe icons.

    5.79-weather-icons

  2. download the image modulo tool Image2Lcd and open it.

    imagelcd

  3. Click open and select the images, convert them to array format.

    • Open file
    • Output date type: C language array by default
    • The biggest width and height: Consistent with the width and height of the image. Note that it must be a multiple of 8, otherwise it cannot be displayed properly
    • Save and output

    top-bar-array

    You can put this array in a suitable header file, and I have placed it in pic. h here.

    pic.png

Register an OpenWeather account

  1. Enter https://openweathermap.org/ and click "Sing in" to register an OpenWeather account.

    openweather

  2. Log in your account.

  3. Click your user name -> "My API Keys" to find your API key.

    openweather-api

Code Explanation

Please click download to download the code file 5.79_wifi_http_openweather.zip for this demo.

Add libraries

#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>
#include "EPD.h"
#include "pic.h"

Modify your information

const char* ssid = " ";       // Enter your ssid
const char* password = " ";     // Enter your WiFi password

// OpenWeatherMap API key
String openWeatherMapApiKey = "You-API"; //Enter your API key
// For example: String openWeatherMapApiKey = "bd939aa3d23ff33d3c8f5dd1dd435";

// Replace with city and country code you're in
String city = "London";                    // City Name
String countryCode = "2643743";            // Country Code

Country Code

You can find the country code at: http://bulk.openweathermap.org/sample/

country-code

Function Explanation

js_analysis

This function is mainly used to parse the received JSON data, process these data separately, and save them in variables.

void js_analysis()
{
  // Check if successfully connected to WiFi network
  if (WiFi.status() == WL_CONNECTED) {
    // Build URL for OpenWeatherMap API request
    String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&APPID=" + openWeatherMapApiKey + "&units=metric";

    // Loop until a valid HTTP response code of 200 is obtained
    while (httpResponseCode != 200) {
    //Send HTTP GET request and retrieve response content
      jsonBuffer = httpGETRequest(serverPath.c_str());
      Serial.println(jsonBuffer); // Print the obtained JSON data
      myObject = JSON.parse(jsonBuffer); // Parse JSON data

      // Check if JSON parsing is successful
      if (JSON.typeof(myObject) == "undefined") {
        Serial.println("Parsing input failed!"); // Prompt message when parsing fails
        return; // If parsing fails, exit the function
      }
      delay(2000); // Wait for 2 seconds and retry
    }

    // Extract weather information from parsed JSON data
    weather = JSON.stringify(myObject["weather"][0]["main"]); // Weather Information
    temperature = JSON.stringify(myObject["main"]["temp"]); // temperature
    humidity = JSON.stringify(myObject["main"]["humidity"]); // humidity
    sea_level = JSON.stringify(myObject["main"]["sea_level"]); // visibility
    wind_speed = JSON.stringify(myObject["wind"]["speed"]); // wind speed
    city_js = JSON.stringify(myObject["name"]); // City Name

    // Print extracted weather information
    Serial.print("String weather: ");
    Serial.println(weather);
    Serial.print("String Temperature: ");
    Serial.println(temperature);
    Serial.print("String humidity: ");
    Serial.println(humidity);
    Serial.print("String sea_level: ");
    Serial.println(sea_level);
    Serial.print("String wind_speed: ");
    Serial.println(wind_speed);
    Serial.print("String city_js: ");
    Serial.println(city_js);

    // Set weather icon flags based on weather description
    if (weather.indexOf("clouds") != -1 || weather.indexOf("Clouds") != -1 ) {
      weather_flag = 1; // Clouds
    } else if (weather.indexOf("clear sky") != -1 || weather.indexOf("Clear sky") != -1) {
      weather_flag = 3; // Clear sky
    } else if (weather.indexOf("rain") != -1 || weather.indexOf("Rain") != -1) {
      weather_flag = 5; // rain
    } else if (weather.indexOf("thunderstorm") != -1 || weather.indexOf("Thunderstorm") != -1) {
      weather_flag = 2; // thounderstorm
    } else if (weather.indexOf("snow") != -1 || weather.indexOf("Snow") != -1) {
      weather_flag = 4; // snow
    } else if (weather.indexOf("mist") != -1 || weather.indexOf("Mist") != -1) {
      weather_flag = 0; // mist
    }
  }
  else {
    // If WiFi is disconnected, print a prompt message
    Serial.println("WiFi Disconnected");
  }
}

// Define the function for HTTP GET requests
String httpGETRequest(const char* serverName) {
  WiFiClient client;
  HTTPClient http;

  // Initialize the HTTP client and specify the requested server URL
  http.begin(client, serverName);

  // Send HTTP GET request
  httpResponseCode = http.GET();

  // The response content returned by initialization
  String payload = "{}";

  // Check the response code and process the response content
  if (httpResponseCode > 0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode); // Print response code
    payload = http.getString(); // Obtain response content
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode); // Print error code
  }
  // Release HTTP client resources
  http.end();

  return payload; // Return response content
}

UI_weather_forecast

Display the processed data saved in the variable on the screen.

void UI_weather_forecast()
{
  char buffer[40];  // Create a character array for storing information

  // Clear the image and initialize the e-ink screen
  Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE); // Create a new image
  Paint_Clear(WHITE); // Clear image content
  EPD_FastMode1Init(); // Initialize the e-paper screen
  EPD_Display_Clear(); // Clear screen display
  EPD_Update(); // Update Screen
  EPD_Clear_R26A6H(); // Clear the electronic ink screen cache

  // display picture
  EPD_ShowPicture(0, 0, 792, 272, pic, WHITE); // Display background image

  // Display the corresponding weather icon according to the weather icon logo
  EPD_ShowPicture(4, 3, 432, 184, Weather_Num[weather_flag], WHITE);

  // Draw partition lines
  EPD_DrawLine(0, 190, 792, 190, BLACK); // Draw a horizontal line
  EPD_DrawLine(530, 0, 530, 270, BLACK); // Draw a vertical line

  // Display update time
  memset(buffer, 0, sizeof(buffer));
  snprintf(buffer, sizeof(buffer), "%s ", city_js); // Format the update time as a string
  EPD_ShowString(620, 60, buffer, 24, BLACK); // Display update time

  // Display temperature
  memset(buffer, 0, sizeof(buffer));
  snprintf(buffer, sizeof(buffer), "%s C", temperature); // Format temperature as a string
  EPD_ShowString(340, 240, buffer, 24, BLACK); // Display temperature

  // Display humidity
  memset(buffer, 0, sizeof(buffer));
  snprintf(buffer, sizeof(buffer), "%s ", humidity); // Format humidity as a string
  EPD_ShowString(620, 150, buffer, 24, BLACK); // Display humidity

  // Display wind speed
  memset(buffer, 0, sizeof(buffer));
  snprintf(buffer, sizeof(buffer), "%s m/s", wind_speed); // Format wind speed as a string
  EPD_ShowString(135, 240, buffer, 24, BLACK); // Display wind speed

  // display visibility
  memset(buffer, 0, sizeof(buffer));
  snprintf(buffer, sizeof(buffer), "%s ", sea_level); // Format visibility as a string
  EPD_ShowString(620, 240, buffer, 24, BLACK); // display visibility

  // Update the display content of the e-paper screen
  EPD_Display(ImageBW); // display image
  EPD_PartUpdate(); // Partially updated screen
  EPD_DeepSleep(); // Enter deep sleep mode
}

Upload the Code

  1. Double click the 5.79_wifi_http_openweather.ino.

  2. Click "Tools"->"Board"->"esp32"->"ESP32S3 Dev Module", and the "Partition Scheme" select "Huge APP (3MB No OTA/1MB SPIFFS)", "PSRAM" select "OPI PSRAM".

    open-weather

  3. Connect CorwPanel to the computer, click on "Tool" and select the corresponding "port".

  4. Click "Upload" to upload the code to the board. There will be an image show on the screen.

    dl-op

  5. After downloading, the weather information for the city you have selected will be displayed on CrowPanel.

    weather-ui

Examples for the CrowPanel Interfaces

Please click download to download the code file for the examples.

Example 1 Control the GPIO

  1. Open the 5.79_GPIO.ino.

    #include <Arduino.h>
    #include "EPD.h"  // include header files for EPD display library, providing functionality for operating electronic paper display screens
    
    // Define an array for storing display images, with a size of 27200 bytes
    uint8_t ImageBW[27200];
    
    // Determine the status of GPIO pins and display status information on EPD
    void judgement_function(int* pin) {
      char buffer[30];  // Store the string to be displayed
    
      EPD_GPIOInit();  // Initialize GPIO settings for EPD display screen
    
      // Create a new image with a white background color
      Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE);
      Paint_Clear(WHITE);  // Clear the canvas with a white background color
    
      // Create a new image again (possibly to ensure clarity) with a white background color
      Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE);
      Paint_Clear(WHITE);  // Clear the canvas with a white background color
    
      // Initialize the quick mode of EPD display
      EPD_FastMode1Init();
      EPD_Display_Clear();  // Clear EPD display content
      EPD_Update();  // Update EPD display
      EPD_Clear_R26A6H();  // Clear EPD cache
    
      // Traverse all GPIO pins, read the status of each pin and display it on EPD
      for (int i = 0; i < 12; i++) {
        int state = digitalRead(pin[i]);  // Read the status of the specified pin (HIGH or LOW)
    
        if (state == HIGH) {
          // If the pin status is HIGH, format the string and display it
          int length = sprintf(buffer, "GPIO%d : on", pin[i]);
          buffer[length] = '\0';  // Ensure that the string ends with '\ 0'
          EPD_ShowString(0, 0 + i * 20, buffer, 16, BLACK);  // Display pin status on EPD
        } else {
          // If the pin status is LOW, format the string and display it
          int length = sprintf(buffer, "GPIO%d : off", pin[i]);
          buffer[length] = '\0';  // Ensure that the string ends with '\ 0'
          EPD_ShowString(0, 0 + i * 20, buffer, 16, BLACK);  // Display pin status on EPD
        }
      }
      EPD_Display(ImageBW);  // Display the image to EPD
      EPD_PartUpdate();  // Perform partial update (refresh display)
      EPD_DeepSleep();  // Set EPD to deep sleep mode to save power
    }
    
    // Define GPIO pin array
    int pin_Num[12] = {8, 3, 14, 9, 16, 15, 18, 17, 20, 19, 38, 21};
    
    void setup() {
      Serial.begin(115200);  // Initialize serial communication, baud rate 115200
    
      // Configure pin 7 to output mode and set it to HIGH (possibly for power control)
      pinMode(7, OUTPUT);
      digitalWrite(7, HIGH);
    
      // Configure GPIO pins to output mode
      pinMode(8, OUTPUT);
      pinMode(3, OUTPUT);
      pinMode(14, OUTPUT);
      pinMode(9, OUTPUT);
      pinMode(16, OUTPUT);
      pinMode(15, OUTPUT);
      pinMode(18, OUTPUT);
      pinMode(17, OUTPUT);
      pinMode(20, OUTPUT);
      pinMode(19, OUTPUT);
      pinMode(38, OUTPUT);
      pinMode(21, OUTPUT);
    
      // Set all GPIO pins to HIGH
      digitalWrite(8, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(14, HIGH);
      digitalWrite(9, HIGH);
      digitalWrite(16, HIGH);
      digitalWrite(15, HIGH);
      digitalWrite(18, HIGH);
      digitalWrite(17, HIGH);
      digitalWrite(20, HIGH);
      digitalWrite(19, HIGH);
      digitalWrite(38, HIGH);
      digitalWrite(21, HIGH);
    
      // Call a function to determine the status of GPIO pins and display the result
      judgement_function(pin_Num);
    }
    
    void loop() {
      // Main loop, currently not performing any operations, only delaying by 1 second
      delay(1000);  // Delay of 1000 milliseconds (1 second)
    }
    
  2. Connect the LED to the GPIO pins.

  3. Upload the code to the CrowPanel. The LEDs will turn on, and the status of the GPIO will show on the screen.

    leds

    gpio

Example 2 Count the times of pressing the keys

  1. Open 5.79_key.ino

    #include <Arduino.h>
    #include "EPD.h"
    
    // Pre allocated black and white image array
    uint8_t ImageBW[27200];
    
    // key definition
    #define HOME_KEY 2      // Connect the home button to digital pin 2
    #define EXIT_KEY 1      // Exit key connected to digital pin 1
    #define PRV_KEY 6       // Previous page key connected to digital pin 6
    #define NEXT_KEY 4      // Next page key connected to digital pin 4
    #define OK_KEY 5        // Confirm key connected to digital pin 5
    
    // Initialize each key counter
    int HOME_NUM = 0;
    int EXIT_NUM = 0;
    int PRV_NUM = 0;
    int NEXT_NUM = 0;
    int OK_NUM = 0;
    
    // Storage key count array
    int NUM_btn[5] = {0};
    
    // Key counting and display function
    void count_btn(int NUM[5])
    {
      char buffer[30];  // Buffer for storing strings
    
      // EPD (Electronic Paper Display) initialization
      EPD_GPIOInit();
      Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE);
      Paint_Clear(WHITE);
    
      // Clear the display screen and initialize it
      EPD_FastMode1Init();
      EPD_Display_Clear();
      EPD_Update();
      EPD_Clear_R26A6H();
    
      // Display the count of each button
      int length = sprintf(buffer, "HOME_KEY_NUM:%d", NUM[0]);
      buffer[length] = '\0';
      EPD_ShowString(0, 0 + 0 * 20, buffer, 16, BLACK);
    
      length = sprintf(buffer, "EXIT_KEY_NUM:%d", NUM[1]);
      buffer[length] = '\0';
      EPD_ShowString(0, 0 + 1 * 20, buffer, 16, BLACK);
    
      length = sprintf(buffer, "PRV_KEY_NUM:%d", NUM[2]);
      buffer[length] = '\0';
      EPD_ShowString(0, 0 + 2 * 20, buffer, 16, BLACK);
    
      length = sprintf(buffer, "NEXT__NUM:%d", NUM[3]);
      buffer[length] = '\0';
      EPD_ShowString(0, 0 + 3 * 20, buffer, 16, BLACK);
    
      length = sprintf(buffer, "OK_NUM:%d", NUM[4]);
      buffer[length] = '\0';
      EPD_ShowString(0, 0 + 4 * 20, buffer, 16, BLACK);
    
      // Update display content and enter deep sleep mode
      EPD_Display(ImageBW);
      EPD_PartUpdate();
      EPD_DeepSleep();
    }
    
    
    void setup() {
      Serial.begin(115200);  // Initialize serial communication, baud rate 115200
    
      // Set button pins
      pinMode(7, OUTPUT);    // Set pin 7 as output for power control
      digitalWrite(7, HIGH); // Set the power to high level and turn on the screen power
    
      pinMode(HOME_KEY, INPUT);  // Set the home button pin as input
      pinMode(EXIT_KEY, INPUT);  // 
      pinMode(PRV_KEY, INPUT);   // 
      pinMode(NEXT_KEY, INPUT);  // 
      pinMode(OK_KEY, INPUT);    // 
    }
    
    void loop() {
          int flag = 0; // Mark whether any buttons have been pressed
    
      // Check if the home button is pressed
      if (digitalRead(HOME_KEY) == 0)
      {
        delay(100); // Anti shake delay
        if (digitalRead(HOME_KEY) == 1)
        {
          Serial.println("HOME_KEY"); 
          HOME_NUM++; // Increase homepage key count
          flag = 1; // set mark
        }
      }
      // Check if the exit button has been pressed
      else if (digitalRead(EXIT_KEY) == 0)
      {
        delay(100); // delay
        if (digitalRead(EXIT_KEY) == 1)
        {
          Serial.println("EXIT_KEY"); 
          EXIT_NUM++; // Increase exit key count
          flag = 1; 
        }
      }
    
      else if (digitalRead(PRV_KEY) == 0)
      {
        delay(100); 
        if (digitalRead(PRV_KEY) == 1)
        {
          Serial.println("PRV_KEY"); 
          PRV_NUM++; 
          flag = 1; 
        }
      }
    
      else if (digitalRead(NEXT_KEY) == 0)
      {
        delay(100); 
        if (digitalRead(NEXT_KEY) == 1)
        {
          Serial.println("NEXT_KEY"); 
          NEXT_NUM++; 
          flag = 1; 
        }
      }
    
      else if (digitalRead(OK_KEY) == 0)
      {
        delay(100); 
        if (digitalRead(OK_KEY) == 1)
        {
          Serial.println("OK_KEY"); 
          OK_NUM++; 
          flag = 1; 
        }
      }Reset Tag
    
      // If a button is pressed, update the display content
      if (flag == 1)
      {
        NUM_btn[0] = HOME_NUM;
        NUM_btn[1] = EXIT_NUM;
        NUM_btn[2] = PRV_NUM;
        NUM_btn[3] = NEXT_NUM;
        NUM_btn[4] = OK_NUM;
    
        count_btn(NUM_btn); // Call function to update display
        flag = 0; // Reset flag
      }
    }
    
  2. Press the button.

  3. The times each button is pressed will be displayed on the screen.

    key-counts

Example 3 Control PWR LED with menu Key

  1. Open the 5.79_PWR.ino

    #include <Arduino.h>
    #include "EPD.h"
    
    // Define a black and white image array as the buffer for the e-paper display
    uint8_t ImageBW[27200];
    
    // Define the pin for the home button
    #define HOME_KEY 2
    
    // Variable to count the state of the home button
    int HOME_NUM = 0;
    
    void setup() {
      // Initialize serial communication with a baud rate of 115200
      Serial.begin(115200);
    
      // Set the screen power pin as an output and set it high to turn on the power
      pinMode(7, OUTPUT);
      digitalWrite(7, HIGH);
    
      // Set the POWER LED pin as an output
      pinMode(41, OUTPUT);
    
      // Set the home button pin as an input
      pinMode(HOME_KEY, INPUT);
    }
    
    void loop() {
      // Flag variable to indicate if any button has been pressed
      int flag = 0;
    
      // Check if the home button is pressed
      if (digitalRead(HOME_KEY) == 0)
      {
        delay(100); // Debounce delay to ensure the button press is stable
    
        // Re-check the home button state to prevent false triggering due to bouncing
        if (digitalRead(HOME_KEY) == 1)
        {
          Serial.println("HOME_KEY"); // Print the home button press information to the serial monitor
          HOME_NUM = !HOME_NUM; // Toggle the state of the home button (on/off)
    
          flag = 1; // Set the flag to indicate that the display content needs to be updated
        }
      }
    
      // If a button has been pressed, update the display content
      if (flag == 1)
      {
        char buffer[30]; // Buffer to store the display content
    
        // Initialize the e-paper display
        EPD_GPIOInit();
        Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE);
        Paint_Clear(WHITE);
    
        // Initialize the e-paper display and clear the previous display content
        EPD_FastMode1Init();
        EPD_Display_Clear();
        EPD_Update();
        EPD_Clear_R26A6H();
    
        // Set the state of the POWER LED and display content based on the home button state
        if (HOME_NUM == 1)
        {
          digitalWrite(41, HIGH); // Turn on the POWER LED
          strcpy(buffer, "PWR:on"); // Set the display content to "PWR:on"
        } else
        {
          digitalWrite(41, LOW); // Turn off the POWER LED
          strcpy(buffer, "PWR:off"); // Set the display content to "PWR:off"
        }
    
        // Display the content on the e-paper
        EPD_ShowString(0, 0 + 0 * 20, buffer, 16, BLACK);
    
        // Refresh the e-paper display content
        EPD_Display(ImageBW);
        EPD_PartUpdate();
        EPD_DeepSleep(); // Enter deep sleep mode to save power
      }
    }
    
  2. Upload the code to the CrowPanel.

  3. Press the menu key and the PWR LED will turn on/off.

    PWR1

    PWR2

Example 4 Initialize SD card

  1. Open 5.79_TF.ino

    #include <Arduino.h>  // Include the Arduino library
    #include "EPD.h"      // Include the e-paper display library
    #include "SD.h"       // Include the SD card library
    
    // Define the SPI pins for the SD card
    #define SD_MOSI 40    // SD card MOSI pin
    #define SD_MISO 13    // SD card MISO pin
    #define SD_SCK 39     // SD card SCK pin
    #define SD_CS 10      // SD card CS pin
    
    // Create an instance of SPIClass for SD card SPI communication
    SPIClass SD_SPI = SPIClass(HSPI);
    
    // Define a black and white image array as the buffer for the e-paper display
    uint8_t ImageBW[27200];
    
    void setup() {
      // Initialize serial communication with a baud rate of 115200
      Serial.begin(115200);
    
      // Set the screen power pin as an output and set it high to turn on the power
      pinMode(7, OUTPUT);
      digitalWrite(7, HIGH);
    
      // Set another power pin as an output and set it high to turn on the power
      pinMode(42, OUTPUT);
      digitalWrite(42, HIGH);
    
      // Brief delay to ensure power stability
      delay(10);
    
      // Initialize the SD card
      SD_SPI.begin(SD_SCK, SD_MISO, SD_MOSI); // Initialize SPI with specified pins
    
      // Try to mount the SD card file system and set the SPI clock speed to 80 MHz
      if (!SD.begin(SD_CS, SD_SPI, 80000000)) {
        // If SD card initialization fails, print error message to the serial monitor
        Serial.println(F("ERROR: File system mount failed!"));
      } else {
        // If SD card initialization succeeds, print SD card size information to the serial monitor
        Serial.printf("SD Size: %lluMB \n", SD.cardSize() / (1024 * 1024));
    
        // Create a buffer to store the display content
        char buffer[30]; // Assume the display content will not exceed 30 characters
        // Use sprintf to format the string and store the SD card size information in buffer
        int length = sprintf(buffer, "SD Size:%lluMB", SD.cardSize() / (1024 * 1024));
        buffer[length] = '\0'; // Ensure the string ends with a null character
    
        // Initialize the e-paper display
        EPD_GPIOInit(); // Initialize the GPIO pins for the e-paper
        Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE); // Create a new image
        Paint_Clear(WHITE); // Clear the image, fill with white
    
        // Recreate and clear the image
        Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE);
        Paint_Clear(WHITE);
    
        // Initialize the e-paper display mode
        EPD_FastMode1Init();
        EPD_Display_Clear(); // Clear the e-paper display
        EPD_Update();        // Update the e-paper display
        EPD_Clear_R26A6H(); // Further clear the display
    
        // Print the display content to the serial monitor
        Serial.println(buffer);
    
        // Display the content on the e-paper
        EPD_ShowString(0, 0, buffer, 16, BLACK); // Draw the string on the e-paper
    
        // Refresh the e-paper display content
        EPD_Display(ImageBW);
        EPD_PartUpdate();
        EPD_DeepSleep(); // Enter deep sleep mode to save power
      }
    }
    
    void loop() {
      // Main loop code
      delay(10); // Wait for 10 milliseconds
    }
    
  2. Insert the TF card to the card slot.

  3. Upload the code to the CrowPanel.

  4. The size of the TF card will show on the screen.

    tf-size

Example 5 Connect Bluetooth

  1. Open 5.79_BLE.ino

  2. Upload the code to the CrowPanel.

  3. After the blutooth is connected, the screen will show:

    ble

Example 6 Connect WiFi

  1. Open 5.79_wifi.ino

  2. Modify your ssid and password

    String ssid = "";
    String password = "";
    
  3. Upload the code to the CrowPanel.

  4. After the WiFi is connected, the screen will show:

    wifi-ip

Example 7 Refresh image

This example will demonstrate two scenarios: refreshing full screen images and non full screen images.

  • Full screen image: The resolution of the image is the same as the screen
  • Non full screen image: The image resolution is lower than the screen resolution

Refresch full screen image

  1. Open 5.79_Global_refresh.ino

    #include <Arduino.h>         // Include the core Arduino library to provide basic Arduino functionality
    #include "EPD.h"             // Include the EPD library for controlling the electronic ink screen (E-Paper Display)
    #include "pic_home.h"        // Include the header file containing image data
    
    uint8_t ImageBW[27200];      // Declare an array of 27200 bytes to store black and white image data
    
    void setup() {
      // Initialization settings, executed once when the program starts
      pinMode(7, OUTPUT);        // Set pin 7 to output mode
      digitalWrite(7, HIGH);     // Set pin 7 to high level to activate the screen power
    
      EPD_GPIOInit();            // Initialize the GPIO pin configuration for the EPD electronic ink screen
      Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE); // Create a new image buffer with dimensions EPD_W x EPD_H and a white background
      Paint_Clear(WHITE);        // Clear the image buffer and fill it with white
    
      /************************ Fast refresh screen operation in partial refresh mode ************************/
      EPD_FastMode1Init();       // Initialize the EPD screen's fast mode 1
      EPD_Display_Clear();       // Clear the screen content
      EPD_Update();              // Update the screen display
    
      EPD_GPIOInit();            // Reinitialize the GPIO pin configuration for the EPD electronic ink screen
      EPD_FastMode1Init();       // Reinitialize the EPD screen's fast mode 1
      EPD_ShowPicture(0, 0, 792, 272, gImage_home, WHITE); // Display the image gImage_home starting at coordinates (0, 0), width 792, height 272, with a white background
      EPD_Display(ImageBW);      // Display the image stored in the ImageBW array
      //  EPD_WhiteScreen_ALL_Fast(gImage_boot_setup); // Commented-out code: Display the boot setup image using fast mode
      //  EPD_PartUpdate();       // Commented-out code: Update part of the screen
      EPD_FastUpdate();          // Perform a fast update to refresh the screen
      EPD_DeepSleep();           // Set the screen to deep sleep mode to save power
      delay(5000);               // Wait for 5000 milliseconds (5 seconds)
    
      clear_all();               // Call the clear_all function to clear the screen content
    }
    
    void loop() {
      // Main loop function, currently does not perform any actions
      // Code that needs to be executed repeatedly can be added here
    }
    
    void clear_all() {
      // Function to clear the screen content
      EPD_FastMode1Init();       // Initialize the EPD screen's fast mode 1
      EPD_Display_Clear();       // Clear the screen content
      EPD_Update();              // Update the screen display
    }
    
  2. Upload the code to the CrowPanel

  3. The image will refresh on the screen.

Refresh non full screen image

  1. Open 5.79_partial_refresh.ino

    #include <Arduino.h>         // Include the core Arduino library to provide basic Arduino functionality
    #include "EPD.h"             // Include the EPD library for controlling the electronic ink screen (E-Paper Display)
    #include "pic_scenario.h"    // Include the header file containing image data
    
    uint8_t ImageBW[27200];      // Declare an array of 27200 bytes to store black and white image data
    
    void setup() {
      // Initialization settings, executed once when the program starts
    
      // Configure the screen power pin
      pinMode(7, OUTPUT);        // Set pin 7 to output mode
      digitalWrite(7, HIGH);     // Set pin 7 to high level to activate the screen power
    
      EPD_GPIOInit();            // Initialize the GPIO pin configuration for the EPD electronic ink screen
      Paint_NewImage(ImageBW, EPD_W, EPD_H, Rotation, WHITE); // Create a new image buffer with dimensions EPD_W x EPD_H and a white background
      Paint_Clear(WHITE);        // Clear the image buffer and fill it with white
    
      /************************ Fast refresh screen operation in partial refresh mode ************************/
      EPD_FastMode1Init();       // Initialize the EPD screen's fast mode 1
      EPD_Display_Clear();       // Clear the screen content
      EPD_Update();              // Update the screen display
    
      EPD_HW_RESET();            // Perform a hardware reset operation to ensure the screen starts up properly
      EPD_ShowPicture(0, 0, 312, 152, gImage_1, WHITE); // Display the image gImage_1 starting at coordinates (0, 0), width 312, height 152, with a white background
      EPD_Display(ImageBW);      // Display the image stored in the ImageBW array
      EPD_PartUpdate();          // Update part of the screen to show the new content
      EPD_DeepSleep();           // Set the screen to deep sleep mode to save power
    
      delay(5000);               // Wait for 5000 milliseconds (5 seconds)
    
      clear_all();               // Call the clear_all function to clear the screen content
    }
    
    void loop() {
      // Main loop function, currently does not perform any actions
      // Code that needs to be executed repeatedly can be added here
    }
    
    void clear_all()
    {
      // Function to clear the screen content
      EPD_FastMode1Init();       // Initialize the EPD screen's fast mode 1
      EPD_Display_Clear();       // Clear the screen content
      EPD_Update();              // Update the screen display
    }
    
  2. Upload the code to the CrowPanel

  3. The image will refresh on the screen.

Resources