This project is an example of how to apply the concepts we covered in the previous parts of this tutorial. You can check them at the following links:
IntroductionImagine that your school, college, or university is hosting an event—like a science fair or expo. This time, the organizers want to do something different: instead of the usual cardboard or plastic name tags, they want participants to use electronic badges that can display information clearly and can be updated at any moment.
Since you’re known for being a curious maker with some tech skills, they come to you with the challenge and share a list of requirements for the project:
The moment you read the first requirement, your first thought is: "That’s impossible!" Every electronic component needs some form of power—especially displays, whether they’re LCD, OLED, or any other type!
Still, you keep reading: Good visibility in different lighting conditions and decent resolution?
Maybe an OLED display would work, with its bright colors. Or maybe an EPD could do the job, since it can show vibrant colors even in bright light…
Wait, what was that thing about EPDs being bistable?
Could an EPD work without batteries?
Yes! Once you load an image onto the screen, the EPD doesn’t need any power to keep it visible.
Can it be reused?
Absolutely! You can change the image and use the badge again with any new info you want.
So, the conclusion is clear: this project is perfectly possible using EPD screens.
Commercial Epaper BadgesThese kinds of devices already exist commercially under different names, like smart badge,work badge, or ePaper badge. If you look them up online, you’ll find plenty of options available.
Compared to traditional cardboard or plastic name tags, ePaper badges have several key advantages: you can easily update the information, reuse the same device as many times as you want, and even display extra details—like the wearer’s photo, a QR code, or any other relevant info.
Many of these devices include an NFC receiver. NFC stands for Near Field Communication, a short-range technology that allows devices to exchange information when they’re just a few centimeters apart.
Besides sending data, NFC can also be used to power ultra low-power devices by taking advantage of the electromagnetic field generated by the reader—meaning the receiver can work without any batteries at all.
Continuing with our imaginary scenario, let’s say you take this info and ask the event organizers if they’d rather buy an existing solution or develop their own. The answer is clear: they want to create their own project—not just to use it as a badge, but also to showcase it during the event. However, due to budget limitations, the NFC interface won’t be included.
So, with these specs and constraints, let’s get started and design your own ePaper badge together!
Component SelectionWith the specs in front of us, the next step is to choose the components we’ll need to build the device.
Let’s put together a preliminary list:
But hold on a second—A buzzer might be useful, but there’s no battery to power it.
NFC was rejected because of the cost, and WiFi also needs a battery and a CPU to control it, so that’s out too.
Let’s cross all of those off the list.
So, what are we left with? An EPD inside a case.
How could the badge work without any communication—no WiFi or NFC—to load the screen’s content?
A compromise solution would be to use a driver board like the EE04, connect the EPD, load the content you want to display, then disconnect it and mount it inside the case.
It’s not the most elegant setup, but it could work. If the badge is used frequently, you might damage the delicate FPC ribbon cable by connecting and disconnecting so much. But if you only need to use the badge once in a while, this could be a viable solution.
The screen you choose will define the whole badge, so it’s important to pick the right one.
Earlier in this tutorial, we covered the main technical specs of EPDs, so let’s keep those in mind as we make our selection.
First, let’s talk about size. A medium-sized display is probably best. A 7-inch screen would be a bit too bulky to wear around your neck, but something between 2 and 4 inches is just about perfect.
The next big question is color: should we go with a monochrome or a color display?
Color screens are definitely more eye-catching—they make your info stand out. But they’re also slower: color EPDs need complex waveforms, which means the refresh takes longer because several steps are needed to position each pigment correctly.
Monochrome screens, on the other hand, are much faster and even support partial refreshes, so you can quickly update just a part or a small section of the screen.
In the next image, you can compare the speed characteristics of two displays of the same size—2.9", which is pretty convenient.
One is capable of showing 4 grayscale levels, and the other can display 4 colors. The full refresh on the monochrome display takes about 3 seconds, while the color version takes 25 seconds. That’s almost 10 times longer!
As you can see, there’s a huge difference in speed. But think about it for a moment: do we really need a fast screen? Are we going to display data that changes frequently?
If your badge is going to show a fixed image—the same one for days, without any changes—a slow initial refresh isn’t a big deal, since it only happens once and then you don’t notice it anymore. So, in this case, refresh time isn’t a limiting factor.
Considering all the benefits of using color, we’ll go with the display on the right: a 2.9-inch, four-color (white, black, red, and yellow) EPD with a resolution of 128 x 296 pixels.
Key FeaturesThis display has a JD79667 driver chip, capable of handling screens with up to 200x384 pixels of resolution.
The chip comes with an internal buffer of 2 bits per pixel (2bpp) and includes a built-in temperature sensor. It also features non-volatile MTP (Multi-Time Programmable) memory. Unlike OTP memory, which can only be programmed once, MTP memory can be erased and rewritten multiple times. This memory stores the default LUTs and other important information.
To control the screen and load content onto it, we’ll use the EE04 board (as mentioned before) with its 24-pin connector.
Displaying TextThe badge we’ll build in this project will show information using text and simple graphics, like lines and rectangles. Even though Seeed_GFX lets you load images, we’ll save that feature for later projects.
This way, you can start with the basics and move on to more advanced stuff as you get familiar with how the library works.
So, let’s go back to the basic program we saw earlier that displays some text on the screen:
#include "TFT_eSPI.h"
EPaper epaper;
void setup()
{
epaper.begin();
epaper.fillScreen(TFT_WHITE);
epaper.drawString ("Hello",10,10);
epaper.update(); // update the display
}
void loop()
{
// put your main code here, to run repeatedly:
}If you run this code, you might get an error message or just not see any changes on the EPD. That’s because something’s missing: you need to tell the library which combination of display and driver board you’re using.
To do that, you have to create an extra file called driver.h. In the IDE, you can press Ctrl+Shift+N to open a new tab.
Inside this driver.h file, you’ll need to add a couple of definitions. Don’t worry about memorizing these or digging through the docs—Seeed Studio has made an online tool to make this step super easy.
You can find it here: https://seeed-studio.github.io/Seeed_GFX/
On this page, just select your display panel and driver board. For this project, it should look like this:
When you make this selection, the text box below will automatically update with the definitions you need.
Just copy that content into your driver.h file.
Now, if you compile and upload the program, it should work without errors. After a few seconds of blinking and color changes, you’ll see something like this:
Wow! Okay, I know—it’s not exactly mind-blowing, but it’s definitely exciting.
This is the very first thing you’re showing on an EPD screen.
Be patient, this is just the beginning.
Colors and CoordinatesThe display we’re using in this project supports four colors, which in the library are defined as TFT_WHITE, TFT_BLACK, TFT_RED, and TFT_YELLOW.
To place any element on the screen, an x, y coordinate system is used. The origin of this system can be changed (we’ll see that later), but by default, the 0, 0 point is located at the top-left corner, on the side opposite the FPC ribbon cable.
The x coordinate increases to the right, and the y coordinate increases downward.
Seeed_GFX can display text using different fonts, each with its own style, size, and features.
The available fonts might vary depending on your display, so here’s a quick tip to check which fonts you can use in each case.
The library includes several configuration files in the User_Setups folder. These serve different purposes—like setting the display size, driver chip, and connection pins, among other things.
Each config file has a numeric code assigned to it. For the 2.9" color display and the EE04 board, the code is 512 (you can see this in your driver.h file).
If you look in the User_Setups folder, you’ll find a file named Setup512_Seeed_XIAO_EPaper_2inch9_BWRY.h which includes these definitions:
What these definitions mean is that you have 6 fonts available: 1, 2, 4, 6, 7, and 8. Each one has a different text size—some include all letters and characters, while others might only have numbers and a few symbols (the comments explain which is which).
It also means that FreeFonts are enabled—a collection of open-source fonts inherited from a library originally created by Adafruit. We’ll talk more about those soon.
To select one of these 6 fonts, use the setTextFont method and specify the corresponding number. For example:
epaper.setTextFont(2);
epaper.drawString("Hello", 10, 10);Let’s use this knowledge to display the user’s info on the badge.
Just as an example, you might want to include an ID number, the person’s name, their title, and maybe some event info—but feel free to add whatever information you think is appropriate.
Here’s how the code would look:
#include "TFT_eSPI.h"
EPaper epaper;
void setup()
{
epaper.begin();
epaper.fillScreen(TFT_RED);
epaper.setTextSize(1);
epaper.setTextColor(TFT_WHITE);
// ID number
epaper.drawString("ID:12345556789-44", 12, 6);
// Name
epaper.setTextFont(4);
epaper.drawString("Ernesto", 17, 40);
epaper.drawString("Tolocka", 15, 75);
// Title
epaper.setTextFont(2);
epaper.drawString("Teacher", 34, 130);
// Event info
epaper.drawString("Expo 2026", 28, 220);
// Update screen
epaper.update(); // update the display
}
void loop()
{
// put your main code here, to run repeatedly:
}The result is shown in the image below.
As demonstrated, fonts 2 and 4 look great for this purpose. Try experimenting with the others to check out their appearance.
Changing fonts is a big step forward, but there’s still room to improve the badge’s look by making use of the FreeFonts.
As we saw in the Setup512_Seeed_XIAO_EPaper_2inch9_BWRY.h file, the use of so-called FreeFonts is enabled.
There are lots of them, and each one is defined in a header file (.h) inside the library’s Fonts/GFXFF folder.
The name of each font tells you its style and size. For example, the font FreeSans9pt7b can be broken down like this:
- Free: It’s an open-source font, with no license restrictions.
- Sans: It’s a modern, sans-serif font (like Arial). It could also be Mono (a simple, monospaced font) or Serif (more decorative, like Times New Roman).
- Bold: This means the font is bold. You might also see Oblique or Italic, or nothing at all if it’s regular.
- 9pt: This is the font size in points.
- 7b: Indicates that the font is defined using 7-bit values.
Now that we know what FreeFonts are, let’s check out how we can use them to improve our badge.
To select one of these fonts, you’ll use the setFreeFont method and a pointer to the font definition. Here’s how your code would look with FreeFonts applied:
#include "TFT_eSPI.h"
EPaper epaper;
void setup()
{
epaper.begin();
epaper.fillScreen(TFT_RED);
epaper.setTextSize(1);
epaper.setTextColor(TFT_WHITE);
// ID number
epaper.drawString("ID:12345556789-44", 12, 6);
// Name
epaper.setFreeFont(&FreeSansBold12pt7b);
epaper.drawString("Ernesto", 17, 40);
epaper.drawString("Tolocka", 15, 75);
// Title
epaper.setTextFont(2);
epaper.drawString("Teacher", 34, 130);
// Event info
epaper.setFreeFont(&FreeMonoBold12pt7b);
epaper.drawString("EXPO", 34, 210);
epaper.drawString("2026", 34, 245);
// Update screen
epaper.update(); // update the display
}
void loop()
{
// put your main code here, to run repeatedly:
}As you can see, the FreeFonts FreeSansBold12pt7b is used for the name, and FreeMonoBold12pt7b for the event info.
Of course, you can pick any font you like, as long as it’s the right size for your display.
Other FontsIf you explore the library’s Fonts folder, you’ll find two other folders: Custom and TrueType. The second type isn’t supported yet, but in the Custom folder there are a few definitions you can use to experiment—though they’re a bit large for this display.
Custom fonts are user-created fonts. You can even make your own, but we’ll leave that for another time.
Adding GraphicsTo finish up the badge design, let’s add some simple graphics like lines and rectangles. The library includes a rich set of graphics functions that make it easy to draw circles, rectangles, ellipses, and more. We’ll cover those in detail in another project.
Lines can be drawn in different ways: Use drawFastHLine and drawFastVLine for optimized horizontal and vertical lines, or use drawLine for a general case—this lets you draw a line between any two points.
Rectangles can be empty with drawRect, filled with color using fillRect, or drawn with rounded corners using drawRoundRect.
By adding a few separator lines and filled rectangles to change the background color, our badge now takes its final shape:
#include "TFT_eSPI.h"
EPaper epaper;
void setup()
{
epaper.begin();
epaper.fillScreen(TFT_RED);
epaper.setTextSize(1);
// ID number inside the yellow rectangle
epaper.fillRect(0, 0, epaper.width(), 20, TFT_YELLOW);
epaper.setTextColor(TFT_BLACK);
epaper.drawString("ID:12345556789-44", 12, 6);
// Name
epaper.setTextColor(TFT_WHITE);
epaper.setFreeFont(&FreeSansBold12pt7b);
epaper.drawString("Ernesto", 17, 40);
epaper.drawString("Tolocka", 15, 75);
// Separation line
epaper.drawFastHLine(0, 110, epaper.width(), TFT_WHITE);
// Title
epaper.setTextFont(2);
epaper.drawString("Teacher", 36, 130);
// Event info
epaper.fillRect(0, 180, epaper.width(), epaper.height() - 180, TFT_WHITE);
epaper.setTextColor(TFT_BLACK);
epaper.setFreeFont(&FreeMonoBold12pt7b);
epaper.drawString("EXPO", 34, 210);
epaper.drawString("2026", 34, 245);
// Update screen
epaper.update(); // update the display
}
void loop()
{
// put your main code here, to run repeatedly:
}There’s something cool to notice here: instead of specifying the width of the rectangles and separator line in pixels, I used the width method, which returns the width of the display.
I also used the height method to get the total pixel height, making it easier to set the height for the white rectangle.
To wrap things up and finish the process with a functional prototype, I added a 3D-printed case for the display.
This is how the finished badge looks!
In this project, we learned how to develop a simple application using a color display and the EE04 board, starting from a set of specific design requirements.
By applying several concepts covered in the first part of this tutorial, we came up with a viable solution for the proposed problem and designed a complete system—covering both hardware and software—ending with a working prototype.
Along the way, we explored how the Seeed_GFX library works, including some of its unique features related to ePaper technology. We also took a look “under the hood” to see how the library renders text on the screen using different fonts.
The badge we built here is just one possible application. With what you’ve learned, you can redesign it any way you like, or use it for something totally different—from a personalized credential or an event accessory, to a mini display for showing messages or info you want to communicate.
In the next project, we’ll take things a bit further and see how to load and display bitmap images on the screen.








Comments