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
- Flash your ESP32 with the MQTT subscriber sketch above.
- Set up an MQTT broker (Mosquitto on a Raspberry Pi or cloud).
- Go to asibiont.com and start a chat.
- 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."
- 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.
Comments