E-Ink Waveshare Meets AI: How to Integrate an E-Paper Display with ASI Biont for Smart Information Dashboards

The Problem: Static Information in a Dynamic World

E-Ink displays, like the popular Waveshare series, are everywhere: price tags in retail, departure boards in train stations, meeting room signs, home automation dashboards. They are ultra-low power, sunlight-readable, and can show static content for months on a coin cell. But here is the catch: updating them usually requires a dedicated microcontroller (ESP32, Raspberry Pi) and manual code to fetch data from an API, transform it into an image, and send it to the display. Every time you want to change the layout, add a new data source, or switch from a weather widget to a calendar — you need to rewrite firmware. This is tedious, error-prone, and not scalable.

The Solution: Let an AI Agent Handle the Integration

ASI Biont is an AI agent that can connect to virtually any device through a conversational chat interface. Instead of writing a full firmware update routine, you simply describe your E-Ink setup and what you want to display. The AI writes the integration code on the fly using one of several supported protocols: MQTT, SSH, HTTP API, or Hardware Bridge (for direct COM port access). This article walks through a real-world scenario: connecting a Waveshare E-Ink display (driven by an ESP32) to ASI Biont via MQTT, so the AI can push dynamic content — weather forecasts, calendar events, smart home status — without touching a single line of microcontroller code after the initial setup.

Why MQTT for E-Ink?

Method When to use Pros Cons
MQTT ESP32/Arduino with WiFi/Ethernet shield Low latency, persistent connection, pub/sub model Requires broker (Mosquitto)
SSH Raspberry Pi / Linux SBC directly driving E-Ink via SPI Full control over GPIO, no extra hardware Requires SSH credentials, higher latency
Hardware Bridge Wired E-Ink connected to PC via USB (serial) Direct access to COM port, no WiFi needed PC must be running bridge.py
HTTP API E-Ink module with built-in web server (e.g., Waveshare Pico-ePaper) Simple GET/POST, no persistent connection Polling overhead, one-way communication

For this guide, we use MQTT because it is the most flexible for battery-powered ESP32-based E-Ink displays — the ESP32 can sleep between updates and only wake when a new message arrives.

The Hardware Setup

You will need:
- Waveshare E-Ink display (any size: 2.13", 4.2", 7.5") – I used the 4.2" model (400×300 pixels)
- ESP32 development board (e.g., ESP32-WROOM-32)
- Jumper wires (female-to-female) for SPI connection
- 5V power supply (or USB cable)
- MQTT broker (Mosquitto running on a local server or Raspberry Pi)

Wiring Diagram (ESP32 ↔ Waveshare 4.2")

E-Ink Pin ESP32 Pin
BUSY GPIO 4
RST GPIO 16
DC GPIO 17
CS GPIO 5
CLK GPIO 18
DIN GPIO 23
GND GND
VCC 3.3V

Note: Pin assignments may vary by Waveshare model — always check the datasheet. The 7.5" model uses the same SPI pins but different GPIO for BUSY/RST/DC.

Step 1: Flash the ESP32 with a Minimal MQTT Firmware

We use ESP-IDF or Arduino framework. Below is an Arduino sketch that connects to WiFi, subscribes to an MQTT topic, and when it receives a base64-encoded PNG image, it decodes it and displays it on the E-Ink.

#include <WiFi.h>
#include <PubSubClient.h>
#include <base64.h>
#include <GxEPD2_BW.h>
#include <GxEPD2_3C.h>

// WiFi credentials
const char* ssid = "YourSSID";
const char* password = "YourPassword";

// MQTT broker
const char* mqtt_server = "192.168.1.100";
const char* topic = "home/display/eink";

WiFiClient espClient;
PubSubClient client(espClient);

// Display instance (4.2" b/w)
GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(/*CS=*/5, /*DC=*/17, /*RST=*/16, /*BUSY=*/4));

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  display.init();
}

void loop() {
  if (!client.connected()) reconnect();
  client.loop();
}

void callback(char* topic, byte* payload, unsigned int length) {
  // Decode base64 payload
  String encoded = String((char*)payload).substring(0, length);
  int decodedLen = base64_decode_len(encoded.c_str());
  uint8_t* decoded = (uint8_t*)malloc(decodedLen);
  base64_decode(decoded, encoded.c_str(), encoded.length());

  // Convert to 1-bit bitmap and display
  display.setFullWindow();
  display.drawBitmap(0, 0, decoded, 400, 300, GxEPD_WHITE);
  display.display();
  free(decoded);
}

Note: This is a simplified example. In production, you would handle partial updates, use PNG decoding library (e.g., pngle), or send raw 1-bit data to save memory.

Step 2: Let ASI Biont Generate the Integration Code

Now, instead of writing a Python script yourself, you open a chat with ASI Biont and describe the task:

„Connect to my MQTT broker at 192.168.1.100:1883, subscribe to topic home/display/eink, fetch weather data from OpenWeatherMap API every hour, generate an image with temperature, humidity and a simple icon, encode it as base64 PNG, and publish to the topic.“

The AI agent will write a Python script using paho-mqtt, requests, and Pillow, then run it in the sandbox environment (execute_python). Here is the generated code (annotated):

import paho.mqtt.client as mqtt
import requests
from PIL import Image, ImageDraw, ImageFont
import base64
import io
from datetime import datetime

# Configuration
MQTT_BROKER = "192.168.1.100"
MQTT_PORT = 1883
TOPIC = "home/display/eink"
WEATHER_API_KEY = "your_openweathermap_key"
CITY = "London"

def fetch_weather():
    url = f"http://api.openweathermap.org/data/2.5/weather?q={CITY}&appid={WEATHER_API_KEY}&units=metric"
    resp = requests.get(url)
    data = resp.json()
    temp = data['main']['temp']
    humidity = data['main']['humidity']
    desc = data['weather'][0]['description']
    return temp, humidity, desc

def create_image(temp, humidity, desc):
    # Create 400x300 black/white image for 4.2" E-Ink
    img = Image.new('1', (400, 300), 255)  # 1-bit, white background
    draw = ImageDraw.Draw(img)
    # Use a simple monospace font (available in sandbox)
    font_large = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 36)
    font_small = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 24)

    # Draw header
    draw.text((10, 10), f"Weather - {datetime.now().strftime('%H:%M')}", font=font_small, fill=0)
    # Draw temperature
    draw.text((10, 60), f"{temp:.1f}°C", font=font_large, fill=0)
    draw.text((10, 110), f"Humidity: {humidity}%", font=font_small, fill=0)
    draw.text((10, 150), f"{desc.capitalize()}", font=font_small, fill=0)

    # Convert to PNG bytes in memory
    buf = io.BytesIO()
    img.save(buf, format='PNG')
    return base64.b64encode(buf.getvalue()).decode()

# MQTT publish
client = mqtt.Client()
client.connect(MQTT_BROKER, MQTT_PORT, 60)
temp, humidity, desc = fetch_weather()
image_b64 = create_image(temp, humidity, desc)
client.publish(TOPIC, image_b64)
client.disconnect()
print("Image published successfully.")

The script runs in the sandbox (which has internet access), fetches real data, generates a 1-bit PNG, and publishes it via MQTT. The ESP32 receives it and updates the display.

Step 3: Automate with a Schedule

You can ask the AI to run this script every hour using a cron-like schedule. ASI Biont supports scheduled tasks via the schedule tool. Simply say:

„Run the weather display script every 60 minutes.“

The AI will create a repeating task that executes the same Python code automatically.

Real-World Scenarios Beyond Weather

The same pattern works for:
- Meeting room availability: Pull data from Google Calendar API, show room status (free/busy) with next meeting time.
- Smart home dashboard: Display temperature, humidity, CO2 levels from MQTT sensors, door/window status.
- Bus/train departure board: Fetch real-time transit data, show next departures.
- Stock/investment tracker: Show portfolio value, percentage change, key indices.
- Task list: Integrate with Todoist or Trello API, show today's top 3 tasks.

In each case, you only change the data source and image layout — the AI rewrites the script in seconds. No reflashing the ESP32, no firmware updates.

Why This Matters

Traditional E-Ink integration requires:
1. Writing and debugging microcontroller code (C++/MicroPython)
2. Setting up a server to push data
3. Manually updating the display logic

With ASI Biont:
- The AI writes all server-side code
- You only describe the desired outcome in natural language
- Changes happen instantly — new data source, new layout, new schedule

This is not a device review; it's a paradigm shift. The display becomes a passive output device, and the intelligence lives in the cloud AI agent that orchestrates data retrieval, image generation, and publishing.

Getting Started

  1. Flash your ESP32 with the MQTT subscriber sketch above.
  2. Set up an MQTT broker (Mosquitto on a Raspberry Pi or cloud).
  3. Go to asibiont.com and start a chat.
  4. Describe your setup: "I have a Waveshare 4.2" E-Ink connected to an ESP32. MQTT broker at 192.168.1.100. Subscribe to topic home/display/eink. I want to show the current weather from London, updated every hour."
  5. The AI will generate and run the integration code immediately.

No waiting for developer support. No dashboard to configure. Just you, the AI, and your E-Ink display — working together in minutes.

Try it today: asibiont.com.

← All posts

Comments