π Smart Proximity-Based Car Access Control using iPhone BLE
An advanced ESP32-based keyless entry system that automatically detects iPhone presence and controls car door locks. The system dynamically learns iPhone Identity Resolution Keys (IRKs) through BLE pairing and stores them persistently for reliable proximity detection.
- π Dynamic IRK Learning: No hardcoded device IDs - learns iPhone IRKs through secure BLE pairing
- π± iPhone Native Integration: Appears as fitness tracker in iPhone Bluetooth settings
- πΎ Persistent Storage: Supports up to 10 devices stored in EEPROM
- π Secure Authentication: Uses iPhone's BLE Identity Resolution Keys for device verification
- π Automotive Ready: Robust proximity detection with hysteresis filtering
- π Auto-Recovery: Smart restart logic prevents BLE stack issues
- π‘ Advanced BLE Stack: Handles complex server-to-scanner mode transitions
- π Watchdog Protection: Hardware watchdog prevents system lockups
Power On β Check EEPROM β No devices found β 30s Pairing Window
- ESP32 advertises as "ESPKV7 Tracker" (fitness device)
- iPhone connects via Bluetooth settings
- System extracts iPhone's IRK during secure pairing
- IRK stored in EEPROM with auto-generated device name
- System restarts for clean BLE initialization
- Now, you can "forget" the device in iOS and remove it (your iOS Device will be identified via the extracted IRK)
Power On β Load devices β 30s pairing window β Auto-restart β Keyless mode
- Continuous BLE scanning for known iPhone RPA (Resolvable Private Address)
- AES-128 encryption verification using stored IRKs
- Hysteresis filtering prevents false triggers from weak signals
- Automatic unlock when iPhone approaches (RSSI > -80dBm)
- Automatic lock when iPhone leaves (10s timeout + stabilization)
- ESP32 Development Board (ESP32-D0WD-V3 recommended)
- 3x NPN Transistors (2N2222 or BC547)
- 3x 1kΞ© Resistors (for transistor base protection)
- Car Key Fob (to be modified)
- OBD2-to-USB-C Cable (for permanent power supply)
- Jumper Wires and breadboard/perfboard
- Pin 2: Built-in LED (no external LED needed)
- Pin 23: Key power control (through transistor)
- Pin 19: Lock signal (through transistor)
- Pin 18: Unlock signal (through transistor)
- Open Key Fob: Carefully remove the case (usually clips or small screws)
- Locate Button Contacts: Find the lock and unlock button contact points
- Identify Power Rails: Locate VCC (+3V) and GND on the key fob PCB
ESP32 Pin 23 β 1kΞ© Resistor β Transistor Q1 Base
Transistor Q1 Collector β Key Fob VCC
Transistor Q1 Emitter β GND
ESP32 Pin 19 β 1kΞ© Resistor β Transistor Q2 Base
Transistor Q2 Collector β Key Fob Lock Button
Transistor Q2 Emitter β Key Fob GND
ESP32 Pin 18 β 1kΞ© Resistor β Transistor Q3 Base
Transistor Q3 Collector β Key Fob Unlock Button
Transistor Q3 Emitter β Key Fob GND
Key Fob Power Control (Pin 23):
ESP32 Pin 23 ββ[1kΞ©]βββ¬ββ Base (B)
β
ββββ΄βββ
β Q1 β 2N2222
Key Fob VCC βββββββββ€ C β
β E β
Key Fob GND βββββββββ΄ββββββ
Lock Button Control (Pin 19):
ESP32 Pin 19 ββ[1kΞ©]βββ¬ββ Base (B)
β
ββββ΄βββ
β Q2 β 2N2222
Lock Button βββββββββ€ C β
β E β
Key Fob GND βββββββββ΄ββββββ
Unlock Button Control (Pin 18):
ESP32 Pin 18 ββ[1kΞ©]βββ¬ββ Base (B)
β
ββββ΄βββ
β Q3 β 2N2222
Unlock Button βββββββ€ C β
β E β
Key Fob GND βββββββββ΄ββββββ
- Prepare Transistors: Connect 1kΞ© resistor to each transistor base
- Power Control: Connect Q1 collector to key fob VCC, emitter to GND
- Lock Control: Connect Q2 collector to lock button, emitter to key fob GND
- Unlock Control: Connect Q3 collector to unlock button, emitter to key fob GND
- ESP32 Connections: Connect resistor ends to ESP32 pins 23, 19, 18
- Test: Use multimeter to verify connections before powering on
For permanent installation in your car, power the ESP32 through the OBD2 port:
- β Always Available: OBD2 provides constant 12V power (even when car is off)
- β Easy Installation: No need to tap into car wiring
- β Removable: Can be unplugged if needed
- β Standard Location: OBD2 port is accessible in all modern cars
You need an OBD2-to-USB-C cable that provides 5V output for ESP32:
π Find OBD2-to-USB-C cables on Google Shopping
Car OBD2 Port β OBD2-to-USB-C Cable β ESP32 USB-C Port
- Voltage: Ensure cable outputs 5V (not 12V) to avoid damaging ESP32
- Current: Cable should support at least 500mA for ESP32 operation
- Continuous Power: Most OBD2 ports provide power even when car is off
- Location: Mount ESP32 near OBD2 port (usually under dashboard)
Easiest method - no software installation required:
- Download firmware: ESP32_Keyless_v7_Complete.bin
- Open Web Flasher: ESP Tool Online
- Connect ESP32 via USB cable
- Click "Connect" and select your ESP32's COM port
- Add firmware file and IMPORTANT: set offset to
0x0(zero!) - Flash the firmware
- Done! ESP32 is ready to use
π¨ Critical: Always use offset 0x0 (not 0x10000)! This complete image includes bootloader, partitions, and application.
For code modifications and development:
- PlatformIO installed
- ESP32 development environment configured
git clone https://github.com/crazyhoesl/ESPKeylessCar
cd ESPKeylessCar
pio run --target upload
pio device monitorlib_deps =
h2zero/NimBLE-Arduino@^1.4.0
ESP32 BLE Arduino
EEPROM#define MAX_DEVICES 10 // Maximum stored devices
#define PAIRING_TIMEOUT_MS 30000 // 30-second pairing windowconst int RSSI_THRESHOLD = -80; // ~15-20m detection range
const unsigned long PROXIMITY_TIMEOUT = 10000; // 10s timeout
const int WEAK_SIGNAL_THRESHOLD = 3; // Hysteresis filteringconst int LED_PIN = 2; // Built-in ESP32 LED
const int KEY_POWER_PIN = 23; // Key fob power control (via transistor)
const int LOCK_BUTTON_PIN = 19; // Lock signal (via transistor)
const int UNLOCK_BUTTON_PIN = 18; // Unlock signal (via transistor)- Power on ESP32 - wait for "ESPKV7 Tracker" to appear
- Open iPhone Settings β Bluetooth
- Connect to "ESPKV7 Tracker" (appears as fitness device)
- Enter PIN: 123456 when prompted
- Wait for automatic restart - system switches to keyless mode
- Done! Your iPhone is now learned and will be detected automatically
- Slow blink (1s): Pairing mode - waiting for connection
- Fast blink (200ms): Device connected - pairing in progress
- 3x short blinks: Device successfully added
- 2x long blinks: Maximum device limit reached
- 5x very fast blinks: Pairing error
- Solid on: iPhone detected nearby (keyless mode)
- Off: No iPhones detected
π΅ ESP32 Dynamic Keyless System v7
π Reset reason: 1
β
Found 2 known devices
π± Go to iPhone Settings > Bluetooth and look for 'ESPKV7 Tracker'
π IRK successfully extracted and saved!
π± Device_01 detected (RSSI: -41)
π Welcome! Activating unlock sequence...
The system uses iPhone's BLE privacy features for secure device identification:
- RPA Verification: Validates Resolvable Private Addresses
- IRK Cryptography: AES-128 encryption with stored Identity Resolution Keys
- Byte-Order Handling: Corrects ESP32 BLE stack byte reversal
- Address Rotation: Works with iPhone's automatic address randomization
// Core Components
- Dynamic IRK extraction and storage
- Dual-mode BLE (Server for pairing, Scanner for detection)
- Automotive-grade proximity algorithms
- Reset-reason based state management
- Hardware watchdog integration- Hysteresis Filtering: Prevents false triggers from signal fluctuations
- Multi-device Support: Handles multiple iPhones simultaneously
- Graceful Degradation: Continues operation if one device fails
- Memory Management: Efficient EEPROM usage with wear leveling
- Power Management: Optimized for automotive 12V systems
- β IRK-based Authentication: Uses Apple's BLE security framework
- β Fixed PIN: Prevents unauthorized device addition (PIN: 123456)
- β Physical Access Required: Device pairing requires physical presence
- β No Cloud Dependencies: Fully offline operation
β οΈ Production Hardening: Consider additional security for personal or commercial use
"BLE scan parameter error 259"
- Fixed by auto-restart mechanism
- Caused by ESP32 BLE stack mode transitions
"iPhone not detected"
- Check RSSI threshold (-80dBm default)
- Verify IRK extraction during pairing
- Ensure iPhone Bluetooth is enabled
"Pairing fails"
- Use exactly PIN: 123456
- Restart ESP32 if pairing window expired
- Check for BLE interference
"Endless restart loop"
- Fixed by reset-reason detection
- Power cycle ESP32 to reset state
- Detection Range: ~2-5 meters (adjustable via RSSI threshold)
- Response Time: <3 seconds from approach to unlock
- Power Consumption: ~80mA during scanning, ~120mA during pairing
- Memory Usage: 87% Flash, 12% RAM (ESP32-D0WD-V3)
- Supported Devices: Up to 10 iPhones simultaneously
Contributions welcome! Please read our contributing guidelines and submit pull requests for:
- Additional smartphone support (Android BLE)
- Enhanced security features
- Power optimization
- UI improvements
- Documentation updates
This project is licensed under the MIT License - see the LICENSE file for details.
- Claude AI (Anthropic) - Essential development assistance, code architecture, and comprehensive documentation
- ESP32 BLE Arduino library contributors
- Apple's BLE privacy specification
- Automotive security best practices
- Open source community feedback
- Special thanks to: Christian for the discussions during the build, which helped a lot! The podcast bitsundso.de #958 for the idea to achieve this with Claude Code. Also a big thanks for the inspiration from the YouTube channel community of Spiel und Zeug! And finally to my beautiful and smart partner β€οΈ, for supporting me during the hours I've spent and especially for your tears of joy when I had the breakthrough after weeks of failure during the IRK calculations.

