I wanted to create a single video explaining the basics of creating your own custom LCD PFD. After 6 hours of recording, I realized that nobody would watch a full-fledged documentary even though you like the topic.
This episode will focus on the wiring and the inner workings of the components. The next one will explore basic graphics, followed by an episode about the touch functionalities. For now, I’m aiming to add a communications hub, GPS, and aircraft statistics, but more might follow over time. Don’t forget that you’re able to customize this fully to your liking.
Over time we will add more windows, more functionalities, and most importantly, more personality, so stay tuned and let’s dive right in.
What do we need?
Some items are necessary if you want to follow along with this series, while the others are more of a personal preference.
- ESP32 / Teensy https://amzn.to/3ii1WDx / https://amzn.to/3rRYpPh
- 4 inch TFT screen with touch capabilities (I’ve got mine from AliExpress) https://bit.ly/3yvUVo0
- Wires https://amzn.to/2VneVuv
- Dual concentric rotary encoder https://bit.ly/3jtTf8D
- Rotary encoder https://amzn.to/3lkDDGK
- Soldering station (I’m in love with my HAKKO) https://amzn.to/3xhstVF
- Or a breadboard https://amzn.to/3rNhJNC
- Dupont crimp set (to really tidy things up) https://amzn.to/3rM5np9
First of all, I wanted to address the elephant in the room. We won’t be using an Arduino. The reasoning is simple. An Arduino can’t keep up with an LCD screen of this size. The images will appear very flickering, or our Arduino will draw shapes at a snail’s pace. Therefore I’d recommend going with an ESP32. These boards are beefier, have WI-FI and Bluetooth capabilities, and can even run on the Arduino coding environment. The beauty is that these boards only set you back around 10 bucks. If you buy them per 3 (https://amzn.to/3yiIYC8), it can even drop to $8 per piece.
A Teensy is even more powerful but also comes at an increased price. If you want the most horsepower you’re able to pick one up (https://amzn.to/3jfLO4y) in the $30 range.
I’ve put the rotary encoders as optional because they provide a way to navigate the screens and send inputs. If you want to use a different input method or don’t want to use the same enclosure as me, you’re free to swap them out for buttons.
The ESP32 is a board that can work with microcontrollers to a level that outshines our basic Arduinos. But even for those of us who are just starting it out, they’ve made sure that you can use most of the Arduino functionalities and coding on this board, and they add even more where needed. Remember the video where I controlled my coffee maker over WIFI whenever I landed (https://youtu.be/U6VIocU2aFw)? Instead of an Arduino, I’ve used an ESP 32 for that project specifically because of its WIFI capabilities. An Arduino UNO has a clock speed of 16MHZ, while the ESP32 can dish out a whopping 240MHZ of clock speed. I hope I’ve convinced you why we need a board of this caliber for this project.
4″ SPI LCD with touch capabilities
If you don’t use an ESP32 the pins on your board might not match these. I’d recommend reading the pinout of your board of choice.
The screen we are going to be using is a generic 4″ TFT display. They are cheap but get the job done. Because we tried to save a buck and went with a rather low-cost screen, there will be some limitations, especially when displaying colors. A more high-end screen usually supports a color depth of 24 bits, while this one only supports up to 16 bits.
If you want to follow along with all of the coding examples I’d recommend using the same pins as I did.
Our screen uses the SPI protocol. This protocol makes it possible to send a stream of data continuously. Other protocols like I2C (which we’ve used for smaller 16 digit LCD screens before) usually send the data in packets. The ISP protocol is built around a master and slave data flow.
There are 4 pins of importance for this.
- MOSI (Master output / slave input)
- MISO (Master input / slave output)
- CLK (Clock)
- CS (Chip select)
Multiple SPI-enabled components can share the same MOSI, MISO, and CLK pins. Even though our screen has 1 row of available pins, there are 2 (and if you include the sd card, even 3) components that use the SPI interface. The touch controller and LCD driver are their own separate entities. Therefore the CLCK and MOSI lines of both the touch screen and display can be routed to the same pin on our ESP32 (CLK = 18, MOSI = 23).
The clock pin determines the rhythm at which our data gets transported (it isn’t called a clock without reason). For now, we won’t dive too deep into this. Just make sure to use pin 18 for the clock on our ESP32.
On our touch pins, there is be no marking called MOSI. Here they’ve gone with another term T_DIN (Touch data in). MOSI refers to Master Out Slave In. Our touch driver has a pin called touch data in. Can you see the link? The T_DIN pin will probably receive data from our ESP32 and do something with that data. Our screen uses the same naming scheme (SDI or Screen data in). This is the pin that will receive the data to be displayed from the controller.
On the other hand, our touch controller also has a T_DO pin. This stands for touch data out. Perhaps it might not come as a surprise, but this will send data from our touchscreen towards our microcontroller (MISO = pin 19 on our ESP). Since we don’t want to retrieve any data from our display itself, we won’t utilize its MISO (or SDO/screen data out) pin.
With ISP, it’s important to utilize the correct pins on your microcontroller for it to work.
I’ve already mentioned that we can merge our components to the same MISO/MOSI/CLK line. But how does our controller know which one to control at any given time? For this, we use the CS (Chip Select) pins. For this, we can use any GPIO pin that’s open on our board. I went with 21 for the touchscreen and 2 for our display (DC/RS). By enabling/disabling the signal towards these pins, we ensure that we don’t send the wrong data to the wrong place (don’t worry, the library will handle this all for us).
Dual concentric rotary encoders
Every hardcore flight simmer will tell you that dual concentric rotary encoders are the holy grail of components. These beauties control autopilots, radios, and many more. They are significantly more expensive than regular rotary encoders, though. With an ESP32 or Arduino, I always love to use the EC11EBB24C03 dual concentric rotary encoders. You can obtain them for around $7 apiece from AliExpress.
They look quite different from regular KY-40 encoders, for example, and it has 8 pins that aren’t marked. So how do we know what pin to solder to our encoder? Simple, we google the part number (EC11EBB24C03) and try to find a datasheet. Most of the time, you’ll find a link to the pdf from wholesalers that carry your component (this time, I found https://bit.ly/37f2lQK).
The image above tells us that 7 pins marked A, C, B, D, and E. We also know that our switch has a momentary button (if you press the shaft). In almost all instances, a button consists of 2 pins. Therefore, I’m assuming that pin D and E are linked to this functionality by looking at the image. Using the same logic, I know that encoders usually have an A and B pin, so I’m guessing they match the A and B on the sheet. This gets confirmed by the image below.
We see an A terminal on the left side and a B terminal on the right side. This diagram tells us that the C terminal needs to be connected to the ground (the //// icon at the bottom). It also expects us to apply a voltage with resistors on the A and B terminals. Instead of connecting the 5v line directly through some resistors towards our terminals, we’re also able to use the internal pull-up resistors of our board. The ESP32 has pullup resistors available on almost all GPIO pins. Luckily this lets us connect the A + B terminals directly to an open GPIO pin.
We could connect 3 ground wires for the inner encoder, outer encoder, and switch. But just soldering these 3 pins together (see the connection diagram below) will cut down our outgoing wires from 8 to 6.
In the end, I’ve connected my double rotary encoder like this:
- A-left → 32
- B-left → 33
- A-right → 25
- B-right → 5
And the three ground pins to ground.
KY-40 / HW-40 rotary encoder
Last but not least, we’ve got a single rotary encoder to connect. For this, I’ve gone with a regular HW-40 encoder. These are the same as the well-known KY-40 encoders but have a shorter shaft. Luckily for us, these usually come pre-mounted on a small PCB that marks each pin. The only thing left is to connect these to our ESP32.
- GND → GND
- 5 V→ 5V
- SW → to any open GPIO pin (I went with 12)
- DT → to any open GPIO pin (I went with 14)
- CLK → to any open GPIO pin (I went with 27)
Headers, connectors and crimping
This step is completely optional, but I wanted to create something serviceable. If, for some reason, a component dies, I don’t want to spend hours resoldering everything, organizing wires, or, god forbid, replace the ESP32. I’ve picked up a crimping tool kit that lets me create custom connectors.
This way, I can replace the ESP32 in under a minute with a hot-swap. The modular encoders have already saved my life. One of my dual rotary encoders died (definitely due to my mishandling), and the only thing that I had to do was resolder the component on the proofing board, plug the connector back in, and I was good to go.
I’d never seen the added value something as simple as this brings to the table, but once you start using these puppies, you’ll never want to go back.