When your car throws mysterious error codes, why not build a tool to investigate it yourself?
This is a simple Arduino-based oscilloscope designed to read and visualize the fuel tank pressure sensor (FTPS) data from a car’s EVAP system. The goal: monitor pressure changes in real time using the Arduino IDE’s Serial Plotter and figure out if the sensor is causing the issue, without buying expensive diagnostics tools.
My car (a MINI Cooper) was showing EVAP related check engine codes, and I needed to figure out whether the fuel tank pressure sensor was the cause. Instead of blindly replacing parts or investing in an automotive scan tool, I took a more hands-on route.
Using an Arduino, I tapped into the sensor’s signal wire to:
- Read analog voltage values
- Convert those voltages to pressure readings
- Plot the data live while the engine runs
The EVAP (Evaporative Emissions Control) system captures fuel vapor from the tank and routes it into the engine for combustion improving efficiency and reducing emissions. When there’s a leak or fault, the ECU sets a trouble code.
I dove into forums and found the usual suspects: gas cap, purge valve, etc.
- ✅ Replaced the gas cap — still getting the code.
- ✅ Swapped the purge valve — no improvement.
Eventually, I focused on the fuel tank pressure sensor — a more expensive part. I didn’t want to replace it without confirming it was the issue. So, I reverse engineered a test.
The FTPS had three wires, which typically means:
VDD – Power (usually 5V)
GND – Ground
SIG – Signal (analog voltage output)
The idea: tap into the signal line while the engine is running and monitor live voltage. If the readings are unstable, it might confirm the sensor is faulty.
Before testing in the car, I started with a clean bench test to get baseline data.
![]() |
![]() |
I removed the sensor, soldered a few wires to the connector, and connected it to an Arduino. With no datasheet available, I used trial and error to figure out what worked — and to my surprise, I got clean, stable voltage output.
✅ Success: The sensor seems to function correctly off the car.
![]() |
![]() |
![]() |
![]() |
To get real-world data, I reinstalled the sensor and tapped into the signal wire without cutting it — just a shallow scrape to expose some copper and soldered a lead to it.
With the Arduino hooked back up, I was ready to log data while the engine ran.
Here’s the code I used to collect and plot the sensor data. It reads an analog voltage, converts it to pressure (assuming a -10 to +10 kPa range), and sends it to the Serial Plotter.
const int ftpsPin = A0; // Analog pin connected to sensor signal
void setup() {
Serial.begin(115200); // High baud rate for smoother plotting
Serial.println("Start"); // Helps Serial Plotter initialize
}
void loop() {
int sensorValue = analogRead(ftpsPin);
// Convert analog reading (0-1023) to voltage (0-5V)
float voltage = sensorValue * (5.0 / 1023.0);
// Convert voltage to pressure in kPa (-10 to +10 range, example)
float pressure = ((voltage - 0.5) / 4.0) * 20 - 10;
// Output values for Serial Plotter
Serial.print("Voltage: ");
Serial.print(voltage);
Serial.print(" Pressure: ");
Serial.println(pressure);
delay(100); // Small delay for smoother graph
}
This is what the Serial Plotter showed while the engine was running. The voltage and pressure readings were unstable enough to make me confident that the sensor wasn't working correctly.
This was a quick and effective project, but there’s always room to improve:
⚡ Electrical Noise: Cars generate tons of interference. My test setup didn’t filter any of it. A small capacitor between signal and ground could have helped smooth out the readings.
🧲 Ground Loop: I didn’t tie the Arduino’s ground to the car’s ground. That could have introduced noise too.
📐 Enclosure & Vibration Isolation: The Arduino was bouncing around a bit in the engine bay — not ideal. Still, it worked well enough to identify the issue.
In the end, this DIY oscilloscope confirmed that the FTPS was misbehaving under load. It’s fun to think about reverse-engineering a replacement, but these sensors are rugged and complex — not something I’d want to replicate for a weekend project.
So: I bought a new sensor, installed it, and cleared the code. Problem solved.