Introduction: ESP32/X-Project Cheerlight Badge Using MQTT

About: I am a Ham Radio operator, computer geek, robotic hobbyist. I've been "playing" with microcontrolers for the last several years, basic stamps, arduinos, and arduino like controllers, Raspberry PI, PICs & PICax…

This project uses a dual base shield, and ESP32 (D-Duino) (Display Duino that has a .96 OLED on board). The base shield has headers for the D-Duino, and 2 X-Project shields. It's a unique way to combine both of the projects. I found the dual base shield, with a 4 pixel Neopixel LED x-project board (X-2812b), and a X-Battery charger.

You maybe able to find the individual components cheaper, but I thought if they all come in from one place, they should all get here at the same time, and the project could be completed quickly.

First a little background. I made a display badge with just a ESP8266 D-Duino (

Code for that project can be found here if you might be interested in something a little simpler

One of my friends saw it, and said, it would be cool to add some leds... I thought about it, and said, yeah and I'm not really taking advantage of the WIFI on board either - so why not do a cheerlights/name wifi badge.

I had already finished my 2017 Halloween Cheerlights Ghost (with much simpler hardware and software from my previous punkin cheerlights display the year before)

I came across the dual base shield with a ESP32, and thought, that may even be better!

That's the background into this project, lets get started.....

Step 1: The Hardware.

This kit - even thou it's a little more expensive really has all the hardware you need to complete this project.

except for a battery for that I found this one (The plug is almost the size, too me it appears to be upside down, but as you can see in the picture can be made to fit)

So a couple of warnings here - There is a lot of soldering, all of the headers need soldered in place. The good news is it is not that hard. The D-duino can be put in it's socket to keep the pins straight while soldering them.

And the X-project boards each have a small 2 pin connector on the edge of the full pin header. I found that it did help to keep the pins lined up and straight, but I will say even thou I took my time and was careful (and for the most part keep things straight) I did end up with the X-2812b board having slightly bent pins.

This wasn't a big deal, they are long and can be carefully bent back.

Take your time while soldering.

My other warning - IT appears that the dual base shield was designed with the ESP8266 D-Duino board in mind. (I will say thou someone was thinking and keep the ESP32 D-Duino pin compatible with it) But Compatible doesn't mean the same, the ESP32 using very different pin numbering and that throw me off at the start.

Step 2: Figure Out the Pins...

So, what makes the X-Project really interesting to me is the ability for the "shields" to use different pins. It's done with a little dip switch on the bottom of the boards. The picture above is for the X-2812B X-project board.

The downside to this is the X-Project was originally using the ESP8266 (a smaller but Not D1 mini small - nodeMCU compatible board)

If you look at the picture you'll notice that it has what the dip switches are connected to. I ended up choosing to turn on dip switch 4 - which is connected to Pin D6. Now this is what I did.

I used a couple of dupont cables, and multimeter to check what the pins where connected to....(See the pictures above) Had I been paying attention to the pin out of the ESP8266 board, I would have seen that D6 is GPIO 12 -

And that GPIO 12 is in the same spot as D6 on the ESP32 board - So the pins do line up and all you need to do is use the GPIO #....well all that trouble, and I just needed to look at a couple of pictures side by side.

Just if anyone is interested, here is the little list I made before I looked at the pictures.... :-(

pin 15 -- D8
pin 13 -- d7 pin 12 -- d6 pin 14 -- d5 pin 2 -- d4 pin 0 -- d3 pin4 -- d2 pin 5 -- d1 svp -- adc

Step 3: The Sketches....

Github project page:

1st set the dip switch on the X-2812B board - dip switch 4 to on. You can choose any of the switches, but will need to make changes to the sketches.

The ESP32 has some flicker issues when using the Neopixel board - the creators of the libraries are aware of the issues, and in some cases have issues fixes, unfortunately even with the fixes I was still having flicker issues.

I think this is because of a timing issue with updating the OLED and getting a color from the cheerlight MQTT broker.

You'll need to install the Arduino IDE if you haven't already done so.

(Current Version is 1.8.5, I am using 1.8.4. Download and follow the install instructions for your OS)

You will also need to install the ESP32 core into the IDE (This is a work in progress, so be sure to follow the install instructions for your OS)

So, some libraries you will need: (See installing libraries if you need a guide on how to do it

Required Libraries:



Sketch Dependant:




The sketch that appears to work the best (but still no 100%) is the NeoPixelBus.

Other than using different libraries, the 3 sketches all work and pretty much do the same thing.

First we need to change the ssid and password for the WIFI you will be connecting to. This is near line 29 in all three sketches and looks something like this.

const char* ssid = "Motel6";
const char* password = "";

Starting at line 67 (or somewhere close to it) you'll start to see lines that look like this:

<p>void drawFrame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {<br>display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(0+x, 10+y,"LeRoy Miller");
display->drawString(25+x, 40+y,"KD8BXP");
}</p><p>void drawFrame2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
  display->drawStringMaxWidth(0+x,0+y, 120, "Automation Technology      Club!");
}</p><p>void drawFrame3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
  display->drawString(0 + x, 20 + y, "");
  display->drawString(0 + x, 30 + y, "");

These are setting up the OLED Frames that will be displayed. You can pretty much change these to anything you'd like, keeping in mind the screen formatting. Near line 61 - you'll see what looks like this:

<p>void msOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {<br>  display->setTextAlignment(TEXT_ALIGN_RIGHT);
  display->drawString(128, 0, String(millis()));

The Overlay is persistent across all the FRAMES, currently it is not being used. I had plans to add a clock, but haven't done it yet.

If you'd like to add more Frames feel free, you'll need to update line 91 and 94

FrameCallback frames[] = { drawFrame1, drawFrame2, drawFrame3 };
// how many frames are there?
int frameCount = 3;

The example in the library has 5 frames, so I know it can handle at least that many :-)

To get the cheerlight color we have subscribed to a "cheerlights" topic on broker.

My ESP32/ESP8266 WIFI Display Using MQTT Protocol explains MQTT a bit more.

The basics of it - it's a publish/subscribe protocol used by a lot of IoT devices. One device publishes on a topic, the other device listens to that topic.

The MQTT Broker needs a unique device name, I came up with a way that uses part of the MAC address of the device. Near line 139.

uint64_t chipid = ESP.getEfuseMac(); // MAC address of ESP32
uint16_t chip = (uint16_t)(chipid>>32);
    char clientid[25];

* I just noticed that I copied and pasted the code from my 2017 Cheerlights Ghost and never changed the CheerlightGhost part of the unique name. (You may or may not want to do this).

Because I attempt to make a unique name this shouldn't need to be changed (unless you notice a lot of connects and disconnects from the MQTT broker)

That is pretty much everything....

Step 4: The Video....

Step 5: Using a D-Duino ESP8266

So Because the dual base can use either the ESP8266 or ESP32 D-Duino - I went ahead a put together a sketch for the ESP8266.

The sketch uses the Adafruit Neopixel library. And appears to not have the same flicker problem the ESP32 has.

It's included in the github repository in the ESP8266 directory.

If you haven't installed the ESP8266 Arduino Core you'll need to do that.

Probably the easiest way is with the boards manager instructions can be found here:

There are some minor changes in the sketch for the different hardware. The biggest is how I come up with the unique device name, which is at line 140.

<p>// Attempt to connect<br>    uint32_t chipid=ESP.getChipId();
    char clientid[25];

The idea is the same, it just uses a slightly different call to do it.

* And again I just noticed that I copied and pasted the code from my 2017 Cheerlights Ghost and never changed the CheerlightGhost part of the unique name. (You may or may not want to do this).

Because I attempt to make a unique name this shouldn't need to be changed (unless you notice a lot of connects and disconnects from the MQTT broker)

You'll still need to make the other changes to this sketch as well. The line numbers should be pretty close.

SO why didn't I use the other libraries for the ESP8266 - well honestly I tried all three, but only the Adafruit library worked - I thought this was strange, but since I have a working ESP32 (and the ESP8266 was a after thought) I didn't go to far into it.

Automation Contest 2017

Participated in the
Automation Contest 2017