feat: add MockK dependency and update README documentation for diagnostic features

This commit is contained in:
2026-06-12 12:29:02 +01:00
parent b3c475ad18
commit d8e656284a
4 changed files with 70 additions and 28 deletions
+65 -28
View File
@@ -1,39 +1,76 @@
# ESP32 ALDL Dashboard Android Application
This Android app connects via Bluetooth SPP to an ESP32 microcontroller that interfaces with a 1986 Pontiac Fiero 1227170 ECM using the 160-baud ALDL (Assembly Line Diagnostic Link) datastream. It decodes the telemetry stream in real-time and displays it on a modern Jetpack Compose dashboard.
A modern, high-performance Android application designed to interface with GM OBD1 systems—specifically the **1986 Pontiac Fiero 1227170 ECM**—using a custom ESP32 Bluetooth SPP bridge. The app decodes the low-speed 160-baud ALDL (Assembly Line Diagnostic Link) datastream in real-time, displaying live telemetry, logging diagnostic parameters, and generating tuning heatmaps.
## Features
---
* **Real-time Dashboard:** View essential engine metrics including Engine Speed (RPM), Vehicle Speed (MPH), Coolant Temperature, Manifold Air Temperature (MAT), Manifold Absolute Pressure (MAP), Throttle Position (TPS), O2 Sensor Voltage, and Battery Voltage.
* **Custom UI Components:** Beautiful animated Canvas-based radial RPM gauge and TPS bar graph.
* **Trouble Code Alerts:** Automatically decodes ECM active fault codes into human-readable alerts (e.g., Code 14 - Coolant Temperature Sensor High).
* **Status Flags:** Real-time visibility into Closed Loop, Rich Mixture, TCC Lockup, A/C Clutch requests, and more.
* **Derived Metrics:** Calculates estimated Engine Load and Fuel Flow Hint based on core telemetry data.
* **Real-Time Line Charts:** Built-in rolling graphs of RPM vs. Time, perfect for diagnostic troubleshooting.
* **Background Telemetry Logging:** Uses an Android Foreground Service to maintain the Bluetooth connection and record data seamlessly even when the app is minimized.
* **Local Persistence:** Uses Jetpack Room database to save full sessions with timestamped raw payloads.
* **CSV Data Export:** Automatically generates TunerPro RT compatible `.csv` log files in the `Downloads/ALDLLogs` folder using Android MediaStore APIs.
* **Settings & Configuration:** Persistent DataStore preferences for Unit Toggle (°C/°F), Auto-Logging toggles, and Coolant Alert Thresholds.
## 🌟 Key Features
## Architecture Highlights
* **Real-Time Instrumentation Dashboard:**
* Vibrant, animated Canvas-based components including a radial RPM gauge and a Throttle Position Sensor (TPS) bar graph.
* Instantaneous readouts for Engine Speed (RPM), Vehicle Speed (MPH), Coolant Temperature, Manifold Air Temp (MAT), Manifold Absolute Pressure (MAP), TPS voltage, O2 Sensor voltage, and Battery voltage.
* **Status Flags:** Instant visibility into critical operating states like Closed Loop Mode, Rich/Lean Mixture, Torque Converter Clutch (TCC) Lockup, and A/C Clutch requests.
* **Derived Metrics:** Real-time calculated estimates of Engine Load and Fuel Flow Hints.
* **BLM & INT Fuel Trim Heatmap Grid (New):**
* A real-time diagnostic table indexing fuel trim metrics across **14 RPM bands** (600 to 4800 RPM) and **17 MAP bands** (20 to 100 kPa).
* Color-coded cell visualisations using dynamic RGB interpolation: Green for lean fuel trims ($\le 120$), Blue for stoichiometric neutral ($128$), and Red for rich fuel trims ($\ge 150$).
* **Multi-Parameter Line Charting (New):**
* A dynamic telemetry visualizer toggling between a **Single Chart Mode** (large-scale view of any metric) and a **Multi Chart Mode** displaying up to 4 selected metrics in a 2x2 grid.
* Supports charting for **12 distinct parameters**: RPM, Coolant Temp, MAP, TPS, O2 Sensor, Battery Voltage, Spark Advance, Base Pulse Width (BPW), MAT, BLM, Integrator, and Idle Air Control (IAC) Position.
* **Trouble Code Diagnostic Engine:**
* Decodes active ECM trouble codes into human-readable alerts (e.g., *Code 14 - Coolant Temperature Sensor High*) dynamically displayed at the bottom of the dashboard screen.
* **Dual-Logging Framework:**
* **Room Database Sessions:** Saves all active telemetry packets to a local SQLite database using Jetpack Room.
* **TunerPro RT CSV Export:** Automatically compiles sessions into `.csv` log files fully compatible with TunerPro RT, exported to `Downloads/ALDLLogs` using Android MediaStore.
* **Raw Binary Stream Logging (New):** Optional raw capture recording direct 27-byte diagnostic datastream packets (incorporating `AA 55` headers and 25-byte payloads) to `.bin` files for advanced playback and diagnostic troubleshooting.
* **Logged Files Manager (New):**
* An in-app browser inside the Settings panel that scans `Downloads/ALDLLogs` for CSV and BIN logs, enabling users to view details, open logs with default viewers, or share files via the Android Sharesheet.
* **Persistent Preferences & Guardrails:**
* DataStore-backed settings for Temperature Unit toggle (°C/°F), Auto-Logging toggles, Coolant alert thresholds, Low Battery alert thresholds, and Raw Binary Stream recording toggles.
* **MVVM & StateFlow:** Strict MVVM separation of concerns. The UI reactivity is entirely driven by `StateFlow` streams.
* **Circular Ring Buffer Packet Parsing:** The Bluetooth ingest layer uses `ArrayDeque<Byte>` circular buffering. It constantly seeks the `AA 55` header, preventing misalignment desyncs over noisy lines.
* **Robust Parsers:** The `ALDLParser` encapsulates all scaling constants and interpolation arrays (for MAT) required by the TunerPro `24-INT10.ads` definition.
---
## Requirements
## 🛠️ Architecture & Technical Highlights
* Android Device running Android 8.0+ (Tested extensively against Android 13+)
* Bluetooth Permissions (Nearby Devices on Android 12+)
* ESP32 hardware module programmed with the accompanying ALDL datastream code.
* **Jetpack Compose & MVVM:** Developed with a clean Model-View-ViewModel architecture. State emission is managed via reactive `StateFlow` and `SharedFlow` streams to guarantee lag-free rendering.
* **Circular Buffering & Packet Validation (New):**
* Ingests raw Bluetooth stream buffers using an `ArrayDeque<Byte>` circular buffer.
* Employs a **27-byte lookahead validation algorithm** to search for authentic `AA 55` frame headers, preventing sync misalignment or telemetry corruption from noisy serial lines.
* **TunerPro ADS Translation:** Uses an advanced [ALDLParser](file:///home/gordon/esp32-aldl-android/app/src/test/java/com/example/esp32aldldashboard/ALDLParserTest.kt) mapping raw 25-byte payloads into physical metrics using exact scale conversions, offsets, and non-linear lookup interpolations (derived from the `24-INT10.ads` definition file).
* **Foreground Service Operations (New):**
* Runs a persistent `BluetoothForegroundService` to keep the Bluetooth socket open and stream telemetry continuously in the background, even when the phone screen is locked or the app is minimized.
* **Firebase Integration:** Incorporates Firebase Crashlytics to monitor application stability and track runtime exceptions.
## Setup Instructions
---
1. Pair the ESP32 (named `ESP32-ALDL`) in your Android Bluetooth settings.
2. Grant the requested Bluetooth permissions inside the app.
3. Tap "Connect BT" to begin the telemetry stream.
4. Navigate to the **Settings** tab to toggle Auto-Logging or customize unit formats.
5. View historical `.csv` logs in your device's `Downloads/ALDLLogs` folder.
## 📱 Requirements
## Build Information
Developed using Android Studio and Gradle. Built with Jetpack Compose, Room (with KSP Annotation Processor), and DataStore.
* **Android Device:** Android 8.0 (API Level 26) or higher.
* **Bluetooth Permissions:** Requires Nearby Devices (Android 12+) and Legacy Bluetooth Admin access.
* **ESP32 Transceiver:** Bridge hardware programmed to output 160-baud serial data from the ALDL pin and stream it over Classic Bluetooth SPP (named `ESP32-ALDL`).
---
## 🚀 Setup & Usage
1. Pair the `ESP32-ALDL` Bluetooth module in your Android system settings.
2. Launch the application and grant all requested permissions.
3. Tap **Connect BT** on the main dashboard to establish connection and start telemetry.
4. Navigate between screens (Dashboard, Charts, BLM Table, Settings) using the bottom navigation bar.
5. Configure logging preferences or browse logged CSV/BIN files in the **Settings** menu.
---
## 🧪 Testing & Verification
The parsing logic, scaling calculations, and boundary conditions are validated by a unit test suite located in [ALDLParserTest.kt](file:///home/gordon/esp32-aldl-android/app/src/test/java/com/example/esp32aldldashboard/ALDLParserTest.kt).
To run the unit tests, execute the following Gradle command in the root project directory:
```bash
./gradlew test
```
### Coverage Areas
* **Sample Frame Decoding:** Parses a real-world telemetry payload and verifies the output of IAC position, coolant/manifold temperatures, MAP, TPS, battery voltage, BLM, integrator, spark advance, base pulse width, closed-loop flags, and active trouble codes.
* **Boundary Guards:** Ensures outlier protection for engine speeds, battery voltages, TPS, and coolant temperatures, rejecting out-of-range sensor values as invalid data packets.
* **Lookahead Stability:** Validates parser behavior against truncated or incomplete frame fragments.
+1
View File
@@ -73,6 +73,7 @@ dependencies {
// Local tests: jUnit, coroutines, Android runner
testImplementation(libs.junit)
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.mockk)
// Instrumented tests: jUnit rules and runners
androidTestImplementation(libs.androidx.test.core)
@@ -1,5 +1,7 @@
@file:OptIn(androidx.compose.material3.ExperimentalMaterial3Api::class)
package com.example.esp32aldldashboard.ui.charts
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyRow
+2
View File
@@ -16,6 +16,7 @@ lifecycleViewmodelNav3 = "2.10.0"
room = "2.6.1"
datastore = "1.1.1"
ksp = "2.1.0-1.0.29"
mockk = "1.13.10"
[libraries]
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidxCore" }
@@ -45,6 +46,7 @@ androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "
androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastore" }
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }