Introduction: Wifi Enabled OLED ESP32 Car Gauges

Introductions first…

I build car gauges as a sort of on again and off again hobby. See and for two more recent examples. I especially like ones that blend in with the original parts of the car. So, why is this one different and what inspired me to build it. The answer is two things:

1) ESP32 - I wanted to try out the new kid on the block chip, especially since the arduino-based toolchain for it is fairly mature. One of the interesting things that the ESP32 enables is IOT with its built in wifi and bluetooth capabilities. The community has written multiple libraries to make this somewhat straightforward (webservers, AP’s, wifi clients, mDNS, etc, etc.).

2) Cheap OLED screens - Back in 2007 I made a gauge using a TFT that sat in the place of the clock on a GD (2004-2007) WRX. TFT come in various flavors. Some work better at night, some work better in the day, etc. But none of them work in all conditions. I didn’t realize the error of my ways until one of the gauges I used was useless during a forum member’s sunny track day. Enter OLED, which are awesome for automotive applications. They are not too bright at night and (more importantly) are visible in most sunlight conditions.

This is a two for one instructable as I wrote everything for two common car gauges, oil pressure and turbo pressure. Both are essentially the same thing: a small form factor gauge with an animate analog-look OLED display with discrete numbers and maximums displayed. Both also function as wifi AP’s and webservers. When one connects to them via a computer or cell phone a moving EKG stype chart is viewable (this is the somewhat innovative part).


HELTEC ESP32 module - get the wifi variant

Oil Pressure specific parts:

  • Oil Pressure sensor - I used an automter 5222 Oil pressure sensor hookup parts - this varies by car and location of install. Please consult service manuals, forums, mechnics, etc. and do this correctly so there are no oil leaks.

Boost gauge specific parts:

  • Air pressure sensor (only if you wish to make a boost gauge) -
  • Air hose
  • T fittings

Libraries I used that were indispensable:

Smoothiecharts - Excellent and lightweight live updating charts. Very customizable and does not rely on referencing a js library somewhere else on the internet. This allows for a “local-IOT” type setup and the whole library fit in single string for the web server statement in code!

ESPAsyncWebServer - does what it says on the box and does it well

ThingPulse OLED graphics library (sometimes call the squix library) - - very efficient and straightforward graphics for the ESP chips. Allowed me to do some lazy programming and still get convincing animations.


soldering iron - used to make long cable runs for sensors, install headers on board, shrink shrink wrap, etc.

screwdriver/sockets/other car tools - necessary to install sensors on car

double sided tape - to install gauges in housings and install housing in car (hot glue and other things might work, but I prefer the 3M double sided exterior trim tape. It holds well and can be pulled off without damaging things.)

scissors - for tape and cutting tubing and zip ties

zip ties - for holding things together, bundling wires under dash and in engine compartment, holding sensors in place, etc.

Step 1: Code First/Hardware Second

Code can be downloaded here:

Oil Pressure -

Boost Pressure -

Boost Pressure with faces instead of analog look gauges -

Graphics code:
The ThingPulse library is so very efficient that you can draw xbms right on top of one another and get convincing results!

The gauge images actually came from an open source graphics repository ( The artist Iconic, CY (

I used gimp to generate 20 different frames with the needle pointing to each tick mark. The smiley face Icons are by NOVITA ASTRI, ID and are here:

Then I converted these all into const uint8_t arrays using this technique (hint: if the colors are inverted when you display them, just invert the colors on the original):

Live animation code is pretty straightforward:

  • Get reading from sensor
  • Scale reading (I made it 1 to 1 for positive boost values and only move the needle when it is in boost not when it is in vacuum)
  • Draw xbm and then put down number characters for everything else.
  • rinse and repeat

Sensor code:
I am reusing sensor code I’ve used for these two sensors for a few other projects. I did add some averaging to get away from jumpy sensors. This includes reading each "reading" being an average of 5 readings.

Boost code (sensor gives an analog val from 0-5 volts which the ADC turns into steps from 0-1024):

<pre>int getBoost() {<br>  float rboost = ((analogRead(36) + analogRead(36) + analogRead(36) + analogRead(36) + analogRead(36))/5);
  //float ResultPSI = (rboost*(.00488)/(.022)+20)/6.89 - atmo; //leave of the /6.89 for kpa
  float ResultPSI = (((rboost / 4095) + 0.04) / 0.004) * 0.145 - atmo; //by 0.145 to calc psi //4096 values on esp32
  /*rBoost = rBoost + 1 ;
    if (rBoost >= 20) {
    rBoost = 0;
  return (ResultPSI);

Oil pressure code (the sensor varies its resistance based on the pressure it senses so a voltage divider is required to turn this into a voltage from 0-5v see: the bottom) for more information):

int getOilPSI() {<br>  float psival = ((analogRead(36) + analogRead(36) + analogRead(36) + analogRead(36) + analogRead(36))/5);
  psival = -0.0601*psival + 177.04 - 14.5;
  return psival;

Web Server and AP functionality:
AP functionality is fairly simple - instantiate and AP object with the ESSID you want to broadcast and the password and you are good to go.

const char *ssid = "boost_gauge_ap";<br>const char *password = "password";
WiFi.softAP(ssid, password);

It even has a DHCP server so you don’t have to worry about that. By default it’s IP is (no idea why, that’s just what the chose).
The webserver bit is a little trickier and required a bit of research. Basically you want an async webserver so it can get live updating data. Luckily there is a library for that. I am not a javascript developer, so I tinkered with a bunch of charting and graphing libraries until I stumbled on smoothie charts. Most other charting libraries are written such that they inherit all kinds of code from other libraries from across the web that are dynamically loaded when a page is rendered. I wanted this to work independent of the internet so this was a big find. Second it had to be small enough that it fit on an arduino and as you can see in the code it fits in a single char array.

Webserver declarations:<br>
#include AsyncTCP.h
#include ESPAsyncWebServer.h<br>
AsyncWebServer server(80); //instantiate it and pick port (80 is standard for http)
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/html", "...  			//the webpage + the smoothiecharts library in a huge char array
    server.on("/val", HTTP_GET, [](AsyncWebServerRequest *request){ //the first page actually calls this very small page that just returns the value
    request->send(200, "text/html", Sboost);

Step 2: Hardware and Wiring

Pictured in the gallery are the two sensors I use. The big gold colored one is an Autometer 2242 oil pressure sensor. The body and thread of this sensor is ground and the terminal is the reading in resistance.

Autometer will provide you a curve of resistance to pressure or resistance to temperature for any of their sensors. I have converted this to voltage using a voltage divider (see wiring diagram).

The MPX4250AP air pressure sensor has three live pins and several unused pins. They are V in, ground, and sensor output. It outputs a 0-5v reading that can be read by the microcontroller (or in the case of this mcu 0-3 volts. So, the sensor reading is scaled down using a voltage divider.). The spec sheet for it can be found here:

There are several issues in scaling down from 5v to 3v logic. In my case I used the voltage divider for simplicity and I had the parts around my workbench. You will introduce a little bit of error into the readings based on the possible error of the additional components (the two resistors). This could make your readings 10% off in some cases. I can live with this. If you can't you may wish to use an opamp and resistors or a logic level converter (available from various electronics vendors. Sparkfun has one here: I may switch to it as I get high readings sometimes on this gauge (in fact I have shown this product on my wiring diagram).

I powered the ESP32's via USB. This included wiring a direct charger like this one: to the car and then using a USB hub to split it out. You can see that I used right angle usb cables to ensure everything work in a small area (

Other photos show places I cut holes or ran wire. Every car will be different. Use caution, knives and scissors are sharp, electricity can be dangerous so please disconnect the battery before wiring things up.

Step 3: 3D Printed Housing

I have used several 3D printed housings for this.

You are welcome to copy and modify these to fit your needs. None of them are perfect and they all will require a bit of adjusting.

Some notes:

  • I finished mine with plastidip; it is the preferred method of the lazy.
  • Sanding plastics does make fine particulate that isn't good for you, use an appropriate mask.
  • I used PETG for my housings. ABS is also good. PLA will warp in the hot sun on a dashboard.

IoT Challenge

Second Prize in the
IoT Challenge