Skip to content

CrowPanel ESP32 E-Paper 3.7-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. The description and the price is variable. 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
    • Scan mode: Vertical scan (the 2nd one)
    • 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 WIFI_refresh.zip for this demo.

Add necessary libraries

#include <Arduino.h>            // Include the Arduino core library
#include "EPD.h"                // Include the e-paper display library
#include "EPD_GUI.h"            // Include the e-paper display GUI library
#include "Ap_29demo.h"          // Custom library file
#include "FS.h"                 // File system library
#include "SPIFFS.h"             // SPIFFS file system library, for file read/write

#include <WiFi.h>               // Include the WiFi library
#include <WebServer.h>          // Include the Web Server library
#include <Adafruit_GFX.h>       // Include the Adafruit graphics library
#include <Fonts/FreeMonoBold9pt7b.h> // Include the FreeMonoBold font

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;                  // File object for saving the uploaded file
#define txt_size 3536          // Define the size of the txt file
#define pre_size 2208          // Define the size of the pre 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

UI_price() Function

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

// Function to update the price interface
void UI_price() {

  // txt:3536 pre:2208
  EPD_FastInit();  // Fast initialize the screen
  EPD_ShowPicture(0, 0, EPD_H, 40, background_top, WHITE);  // Show the background image
  EPD_Display(ImageBW);  // Update the screen display
  EPD_Update();  // Refresh the screen
  EPD_DeepSleep();  // Enter deep sleep mode

  // Check if the file exists and read its content
  if (SPIFFS.exists("/txt.bin")) {  // Check if /txt.bin file exists
    File file = SPIFFS.open("/txt.bin", FILE_READ);  // Open the file for reading
    if (!file) {
      Serial.println("Failed to open file for reading");  // If the file cannot be opened, print an error message
      return;
    }
    // Read data from the file into the array
    size_t bytesRead = file.read(txt_formerly, txt_size);

    Serial.println("File content:");  // Print the file content
    while (file.available()) {
      Serial.write(file.read());  // Read the file content byte by byte
    }
    file.close();  // Close the file

    EPD_FastInit();  // Fast initialize the screen
    EPD_ShowPicture(30, 60, 272, 104, txt_formerly, WHITE);  // Show the file content image
    EPD_Display(ImageBW);  // Update the screen display
    EPD_Update();  // Refresh the screen
    EPD_DeepSleep();  // Enter deep sleep mode
  }

  if (SPIFFS.exists("/pre.bin")) {  // Check if /pre.bin file exists
    File file = SPIFFS.open("/pre.bin", FILE_READ);  // Open the file for reading
    if (!file) {
      Serial.println("Failed to open file for reading");  // If the file cannot be opened, print an error message
      return;
    }
    // Read data from the file into the array
    size_t bytesRead = file.read(price_formerly, pre_size);

    Serial.println("File content:");  // Print the file content
    while (file.available()) {
      Serial.write(file.read());  // Read the file content byte by byte
    }
    file.close();  // Close the file

    EPD_FastInit();  // Fast initialize the screen
    EPD_ShowPicture(30, 180, 368, 48, price_formerly, WHITE);  // Show the price image
    EPD_Display(ImageBW);  // Update the screen display
    EPD_Update();  // Refresh the screen
    EPD_DeepSleep();  // Enter deep sleep mode
  }
}

okPage() Function

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.

// Handle file upload and display on the e-paper
void okPage() {
  server.send(200, "text/html", HTML_OK); // Send the success page

  HTTPUpload& upload = server.upload(); // Get the uploaded file data

  // Note: The initial size of upload.buf is only 1436 bytes, adjust as needed
  // Click ctrl + left mouse button on upload.buf to find HTTP_UPLOAD_BUFLEN in WebServer.h
  // Adjust it to an appropriate size (e.g., 14360 bytes)
  if (upload.status == UPLOAD_FILE_END) { // Upload completed
    Serial.println("Drawing file");
    Serial.println(upload.filename); // Print the filename
    Serial.println(upload.totalSize); // Print the file size

    // Determine the file type based on the file size
    if (upload.totalSize == txt_size) // If the file size matches txt_size
      filename = "txt.bin";          // Set the filename to txt.bin
    else
      filename = "pre.bin";          // Otherwise, set the filename to pre.bin

    // Save the received file
    if (!filename.startsWith("/")) filename = "/" + filename; // Ensure the filename starts with '/'
    fsUploadFile = SPIFFS.open(filename, FILE_WRITE); // Open the file for writing
    fsUploadFile.write(upload.buf, upload.totalSize); // Write the file content
    fsUploadFile.close(); // Close the file
    Serial.println("Save successful");
    Serial.printf("Saved: ");
    Serial.println(filename);

    // Store the uploaded file data in the corresponding array
    if (upload.totalSize == txt_size) {
      for (int i = 0; i < txt_size; i++) {
        txt_formerly[i] = upload.buf[i]; // Store the uploaded data in the txt_formerly array
      }
      Serial.println("txt_formerly OK");
    } else {
      for (int i = 0; i < pre_size; i++) {
        price_formerly[i] = upload.buf[i]; // Store the uploaded data in the price_formerly array
      }
      Serial.println("price_formerly OK");
    }

    // Initialize the e-paper display and show the image
    EPD_FastInit(); // Initialize the partial display mode of the E-Paper screen
    EPD_ShowPicture(0, 0, EPD_H, 40, background_top, WHITE); // Show the background image

    // Display the appropriate content based on the uploaded file type
    if (upload.totalSize != txt_size) {
      EPD_ShowPicture(30, 180, 368, 48, price_formerly, WHITE); // Show the content of the pre file
    } else {
      EPD_ShowPicture(30, 60, 272, 104, txt_formerly, WHITE); // Show the content of the txt file
    }

    EPD_Display(ImageBW); // Update the screen content
    EPD_Update(); // Refresh the screen content
    EPD_DeepSleep(); // Enter deep sleep mode to save power
  }
}

Image Refresh Process

  1. Initialization

      EPD_GPIOInit();  // Initialize the screen GPIO
      Paint_NewImage(ImageBW, EPD_W, EPD_H, 180, WHITE);  // Create a new image canvas
      Paint_Clear(WHITE);  // Clear the canvas
    
      EPD_FastInit();  // Fast initialize the screen
      EPD_Display_Clear();  // Clear the screen display
      EPD_Update();  // Update the screen display
    
  2. Initialize to fast mode display screen

      EPD_FastInit();  // Fast initialize the screen
    
  3. Select the data to refresh

      EPD_ShowPicture(0, 0, EPD_H, 40, background_top, WHITE);  // Show the background image
    
  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 3.7_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.

  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

    connect-wifi

  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 3.7_ble_refresh.zip for this demo.

Add necessary libraries

#include <BLEDevice.h>          // Include the BLE device library
#include <BLEServer.h>          // Include the BLE server library
#include <BLEUtils.h>           // Include the BLE utility library
#include <BLE2902.h>            // Include the BLE descriptor library
#include <FS.h>                 // Include the file system library
#include <SPIFFS.h>             // Include the SPIFFS file system library
#include <Arduino.h>            // Include the Arduino library
#include "EPD.h"                // Include the E-Paper driver library
#include "EPD_GUI.h"            // Include the E-Paper GUI library
#include "Ap_29demo.h"          // Include the custom application demo library

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

File fsUploadFile;              // File object for uploading files
#define txt_size 3536           // Define the size of text data
#define pre_size 2208           // Define the size of preset data

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.

// Process BLE received data
void ble_pic()
{
  // Check if data has been received
  if (dataReceived) {
    // If the data buffer is not empty
    if (!dataBuffer.empty()) {
      size_t bufferSize = dataBuffer.size(); // Get the size of the data buffer
      Serial.println(bufferSize); // Print the size of the data buffer to the serial monitor

      // Determine the filename based on the size of the data buffer
      if (dataBuffer.size() == txt_size) // If the data size equals txt_size
        filename = "txt.bin"; // Set the filename to txt.bin
      else
        filename = "pre.bin"; // Otherwise, set the filename to pre.bin

      // Ensure the filename starts with a slash
      if (!filename.startsWith("/")) filename = "/" + filename;

      // Open the file for writing
      fsUploadFile = SPIFFS.open(filename, FILE_WRITE);
      fsUploadFile.write(dataBuffer.data(), dataBuffer.size()); // Write the data to the file
      fsUploadFile.close(); // Close the file
      Serial.println("Save successful"); // Print a success message
      Serial.printf("Saved: "); 
      Serial.println(filename); // Print the saved filename

      // Copy the data to different arrays based on the data size
      if (bufferSize == txt_size)
      {
        for (int i = 0; i < txt_size; i++) {
          txt_formerly[i] = dataBuffer[i]; // Copy the data to the txt_formerly array
        }
        Serial.println("txt_formerly OK"); // Print a success message for processing the txt_formerly array
      } else
      {
        for (int i = 0; i < pre_size; i++) {
          price_formerly[i] = dataBuffer[i]; // Copy the data to the price_formerly array
        }
        Serial.println("price_formerly OK"); // Print a success message for processing the price_formerly array
      }

      EPD_FastInit(); // Initialize the partial display mode of the E-Paper screen
      EPD_ShowPicture(0, 0, EPD_H, 40, background_top, WHITE); // Display the background image

      // Display different images on the screen based on the data size
      if (bufferSize != txt_size)
      {
        EPD_ShowPicture(30, 180, 368, 48, price_formerly, WHITE); // Display the price image
      } else
      {
        EPD_ShowPicture(30, 60, 272, 104, txt_formerly, WHITE); // Display the text image
      }

      EPD_Display(ImageBW); // Update the screen content
      EPD_Update(); // Refresh the screen content
      EPD_DeepSleep(); // Enter deep sleep mode to save power

      // Clear the buffer after writing the data
      dataBuffer.clear();
      totalReceivedBytes = 0; // Reset the total number of bytes received
    }

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

class MyCallbacks : public BLECharacteristicCallbacks

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

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

      if (value.length() > 0) { // If the length of the received data is greater than 0
        Serial.printf("."); // Print a dot in the serial monitor to indicate data reception
        if (value == "OK") { // If the received data is "OK"
          dataReceived = true; // Set the data received flag to true
          return; // Exit the function
        }
        size_t len = value.length(); // Get the data length
        if (len > 0) { // If the data length is greater than 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.

// Display the price interface
void UI_price()
{
  // Predefined: txt size is 3536, pre size is 2208
  EPD_FastInit(); // Initialize the fast mode of the E-Paper screen
  EPD_ShowPicture(0, 0, EPD_H, 40, background_top, WHITE); // Display the background image
  EPD_Display(ImageBW); // Update the screen content
  EPD_Update(); // Refresh the screen content
  EPD_DeepSleep(); // Enter deep sleep mode to save power

  // If the txt.bin file exists, read and display it
  if (SPIFFS.exists("/txt.bin")) {
    File file = SPIFFS.open("/txt.bin", FILE_READ); // Open the txt.bin file for reading
    if (!file) {
      Serial.println("Failed to open file for reading"); // If the file cannot be opened, print an error message
      return;
    }
    // Read data from the file into the array
    size_t bytesRead = file.read(txt_formerly, txt_size);
    Serial.println("File content:");
    while (file.available()) {
      Serial.write(file.read()); // Print the file content to the serial monitor
    }
    file.close(); // Close the file

    EPD_FastInit(); // Initialize the fast mode of the E-Paper screen
    EPD_ShowPicture(30, 60, 272, 104, txt_formerly, WHITE); // Display the text image on the screen
    EPD_Display(ImageBW); // Update the screen content
    EPD_Update(); // Refresh the screen content
    EPD_DeepSleep(); // Enter deep sleep mode to save power
  }

  // If the pre.bin file exists, read and display it
  if (SPIFFS.exists("/pre.bin")) {
    File file = SPIFFS.open("/pre.bin", FILE_READ); // Open the pre.bin file for reading
    if (!file) {
      Serial.println("Failed to open file for reading"); // If the file cannot be opened, print an error message
      return;
    }
    // Read data from the file into the array
    size_t bytesRead = file.read(price_formerly, pre_size);
    Serial.println("File content:");
    while (file.available()) {
      Serial.write(file.read()); // Print the file content to the serial monitor
    }
    file.close(); // Close the file

    EPD_FastInit(); // Initialize the fast mode of the E-Paper screen
    EPD_ShowPicture(30, 180, 368, 48, price_formerly, WHITE); // Display the price image on the screen
    EPD_Display(ImageBW); // Update the screen content
    EPD_Update(); // Refresh the screen content
    EPD_DeepSleep(); // Enter deep sleep mode to save power
  }
}

Image Refresh Process

  1. Initialization

      EPD_GPIOInit();  // Initialize the screen GPIO
      Paint_NewImage(ImageBW, EPD_W, EPD_H, 180, WHITE);  // Create a new image canvas
      Paint_Clear(WHITE);  // Clear the canvas
    
      EPD_FastInit();  // Fast initialize the screen
      EPD_Display_Clear();  // Clear the screen display
      EPD_Update();  // Update the screen display
    
  2. Initialize to fast mode display screen

      EPD_FastInit();  // Fast initialize the screen
    
  3. Select the data to refresh

      EPD_ShowPicture(0, 0, EPD_H, 40, background_top, WHITE);  // Show the background image
    
  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 3.7_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

  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).

3.7-inch

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

  • downloadthe icons.

    openweather-ui

    Only the weather icon is variable, while the other icons are fixed. Therefore, we can use "3.7-inch.bmp" as the background image, while the weather icon varies depending on the weather conditions.

    Next, we need to convert these images into a C array format and include it in the code

  • download the image modulo tool Image2Lcd and open it.

    imagelcd

  • 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

    weather-c

    snow

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

    ui-array-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 3.7_wifi_http_openweather.zip for this demo.

Add libraries

#include <WiFi.h>               // Include the WiFi library for wireless network functionality
#include <HTTPClient.h>         // Include the HTTPClient library for handling HTTP requests
#include <Arduino_JSON.h>       // Include the Arduino_JSON library for JSON data processing
#include "EPD.h"                // Include the EPD library for controlling the electronic ink screen (E-Paper Display)
#include "EPD_GUI.h"            // Include the EPD_GUI library for graphical user interface (GUI) operations

#include "pic.h"                // Include image resources

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 WiFi is connected
  if (WiFi.status() == WL_CONNECTED) {
    // Construct the request path including city, country code, API key, and unit parameters
    String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&APPID=" + openWeatherMapApiKey + "&units=metric";

    // Loop until data is successfully retrieved (HTTP response code is 200)
    while (httpResponseCode != 200)
    {
      // Send an HTTP GET request and get the returned JSON data
      jsonBuffer = httpGETRequest(serverPath.c_str());
      Serial.println(jsonBuffer); // Print the retrieved JSON data
      myObject = JSON.parse(jsonBuffer); // Parse the JSON data

      // Check if JSON parsing was successful
      if (JSON.typeof(myObject) == "undefined") {
        Serial.println("Parsing input failed!"); // Print an error message if parsing fails
        return; // Exit the function
      }
      delay(2000); // Wait 2 seconds before retrying
    }

    // Extract the required data from the JSON object
    weather = JSON.stringify(myObject["weather"][0]["main"]); // Weather condition
    temperature = JSON.stringify(myObject["main"]["temp"]); // Temperature
    humidity = JSON.stringify(myObject["main"]["humidity"]); // Humidity
    sea_level = JSON.stringify(myObject["main"]["sea_level"]); // Sea level pressure
    wind_speed = JSON.stringify(myObject["wind"]["speed"]); // Wind speed
    city_js = JSON.stringify(myObject["name"]); // City name

    // Print the extracted data
    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 the weather flag based on the weather condition
    if (weather.indexOf("clouds") != -1 || weather.indexOf("Clouds") != -1) {
      weather_flag = 1; // Cloudy
    } else if (weather.indexOf("clear sky") != -1 || weather.indexOf("Clear sky") != -1) {
      weather_flag = 3; // Sunny
    } else if (weather.indexOf("rain") != -1 || weather.indexOf("Rain") != -1) {
      weather_flag = 5; // Rainy
    } else if (weather.indexOf("thunderstorm") != -1 || weather.indexOf("Thunderstorm") != -1) {
      weather_flag = 2; // Thunderstorm
    } else if (weather.indexOf("snow") != -1 || weather.indexOf("Snow") != -1) {
      weather_flag = 4; // Snowy
    } else if (weather.indexOf("mist") != -1 || weather.indexOf("Mist") != -1) {
      weather_flag = 0; // Foggy
    }
  }
  else {
    Serial.println("WiFi Disconnected"); // Print an error message if WiFi is disconnected
  }
}

// HTTP GET request function
String httpGETRequest(const char* serverName) {
  WiFiClient client;
  HTTPClient http;

  // Initialize the HTTP client and specify the server address for the request
  http.begin(client, serverName);

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

  String payload = "{}"; // Default to an empty JSON object

  // Check the HTTP response code
  if (httpResponseCode > 0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode); // Print the response code
    payload = http.getString(); // Get the response data
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode); // Print the error code
  }

  // Release resources
  http.end();

  return payload; // Return the response data
}

UI_weather_forecast

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

// Display the weather forecast interface
void UI_weather_forecast() {
  char buffer[40];  // Character array to store information

  EPD_GPIOInit();  // Initialize screen GPIO
  Paint_NewImage(ImageBW, EPD_W, EPD_H, 180, WHITE);  // Create a new image canvas
  Paint_Clear(WHITE);  // Clear the canvas

  EPD_FastInit();  // Fast initialize the screen
  EPD_Display_Clear();  // Clear the screen display
  EPD_Update();  // Update the screen display
  EPD_FastInit();  // Fast initialize the screen
  // Display background image and weather icon
  EPD_ShowPicture(0, 0, 416, 240, pic, WHITE);
  EPD_ShowPicture(14, 2, 184, 184, Weather_Num[weather_flag], WHITE);

  // Draw partition lines
  EPD_DrawLine(0, 180, 416, 180, BLACK); // Draw horizontal line
  EPD_DrawLine(215, 0, 215, 180, BLACK); // Draw vertical line
  EPD_DrawLine(215, 94, 416, 94, BLACK); // Draw horizontal line

  // Display city information
  memset(buffer, 0, sizeof(buffer));
  snprintf(buffer, sizeof(buffer), "%s ", city_js); // Format city information as a string
  EPD_ShowString(301, 51, buffer, 16, BLACK); // Display city name

  // Display temperature
  memset(buffer, 0, sizeof(buffer));
  snprintf(buffer, sizeof(buffer), "%s C", temperature); // Format temperature as a string
  EPD_ShowString(168, 217, buffer, 16, BLACK); // Display temperature

  // Display humidity
  memset(buffer, 0, sizeof(buffer));
  snprintf(buffer, sizeof(buffer), "%s ", humidity); // Format humidity as a string
  EPD_ShowString(301, 148, buffer, 16, 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(62, 217, buffer, 16, BLACK); // Display wind speed

  // Display sea level pressure
  memset(buffer, 0, sizeof(buffer));
  snprintf(buffer, sizeof(buffer), "%s ", sea_level); // Format sea level pressure as a string
  EPD_ShowString(324, 217, buffer, 16, BLACK); // Display sea level pressure

  // Update the e-ink display content
  EPD_Display(ImageBW); // Refresh the screen display
  EPD_Update(); // Refresh the screen
  EPD_DeepSleep(); // Enter deep sleep mode
}

Upload the Code

  1. Double click the 3.7_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".

    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.

    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 GPIO.ino.

  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 key.ino

  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 PWR.ino

  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 TF.ino

  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 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 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 Global_refresh.ino

  2. Upload the code to the CrowPanel

  3. The image will refresh on the screen.

    global

Refresh non full screen image

  1. Open partial_refresh.ino

  2. Upload the code to the CrowPanel

  3. The image will refresh on the screen.

    partial-1

Resources