147 lines
5.9 KiB
Markdown
147 lines
5.9 KiB
Markdown
# Build and deploy
|
|
|
|
Target: Windows, Arduino IDE 2.x, board package **esp32-bluepad32 4.1.0**,
|
|
original ESP32 (WROOM/WROVER). S3/C3/C6/H2 have no Bluetooth Classic, so a PS4
|
|
pad will not pair with them.
|
|
|
|
## 1. Install the board package
|
|
|
|
Preferences -> Additional board manager URLs, add:
|
|
|
|
```
|
|
https://raw.githubusercontent.com/ricardoquesada/esp32-arduino-lib-builder/master/bluepad32_files/package_esp32_bluepad32_index.json
|
|
```
|
|
|
|
Boards Manager -> install **esp32_bluepad32**. Then Tools -> Board ->
|
|
**esp32_bluepad32** -> ESP32 Dev Module.
|
|
|
|
Picking the board out of the normal `esp32` package is what gives you
|
|
`fatal error: Bluepad32.h: No such file or directory`. Bluepad32 is a
|
|
replacement board package, not a Library Manager entry, and adding it as a ZIP
|
|
library will not work.
|
|
|
|
Do **not** install Legoino or NimBLE-Arduino. If either ends up in the build you
|
|
are back to two Bluetooth host stacks fighting over one radio, which is the
|
|
whole problem this project exists to avoid.
|
|
|
|
## 2. Put the BTstack headers on the include path
|
|
|
|
Package 4.1.0 ships the BTstack and Bluepad32 headers under
|
|
`tools\sdk\<mcu>\include\`, but does not add them to the compiler's include
|
|
path. Without this step you get:
|
|
|
|
```
|
|
fatal error: btstack.h: No such file or directory
|
|
```
|
|
|
|
4.1.0 is built on the arduino-esp32 **2.x** layout, so there is no
|
|
`flags\includes` file to edit (that only exists on core 3.x). The include paths
|
|
live in `compiler.cpreprocessor.flags` in `platform.txt`. Rather than edit that
|
|
file, drop a `platform.local.txt` beside it — Arduino reads it as an override,
|
|
the original stays untouched, and rolling back is deleting one file.
|
|
|
|
In PowerShell:
|
|
|
|
```powershell
|
|
$plat = "$env:LOCALAPPDATA\Arduino15\packages\esp32-bluepad32\hardware\esp32\4.1.0"
|
|
|
|
$flags = 'compiler.cpreprocessor.flags={compiler.cpreprocessor.flags.{build.mcu}} ' +
|
|
'"-I{compiler.sdk.path}/{build.memory_type}/include" ' +
|
|
'"-I{compiler.sdk.path}/include/btstack/src" ' +
|
|
'"-I{compiler.sdk.path}/include/btstack/include" ' +
|
|
'"-I{compiler.sdk.path}/include/btstack/platform/freertos" ' +
|
|
'"-I{compiler.sdk.path}/include/bluepad32/include"'
|
|
|
|
$flags | Out-File "$plat\platform.local.txt" -Encoding ascii
|
|
Get-Content "$plat\platform.local.txt"
|
|
```
|
|
|
|
It has to be a **single line**. The `Get-Content` at the end is there to confirm
|
|
it did not wrap.
|
|
|
|
The first two tokens restate what `platform.txt` already had — the override
|
|
replaces the whole value, so they have to be repeated. `{compiler.sdk.path}`
|
|
resolves to `tools\sdk\<mcu>`, so these entries work for every MCU in the
|
|
package, not just esp32.
|
|
|
|
What each added path is for:
|
|
|
|
| Path | Provides |
|
|
| --- | --- |
|
|
| `btstack/src` | `btstack.h`, `gatt_client.h`, `btstack_run_loop.h` |
|
|
| `btstack/include` | `btstack_config.h` — separate directory, and BTstack includes it from `btstack.h`, so missing it gives you a confusing second error right after fixing the first |
|
|
| `btstack/platform/freertos` | the ESP32 run loop implementation |
|
|
| `bluepad32/include` | `uni.h`, if you later want the `uni_bt_allowlist` API |
|
|
|
|
Duplicate `-I` flags are harmless, so it does not matter if
|
|
`bluepad32/include` was already covered.
|
|
|
|
Two things to know about this edit:
|
|
|
|
* A Bluepad32 package update **wipes it**. Keep a copy of `platform.local.txt`
|
|
somewhere outside `Arduino15` — there is one in `docs/` here.
|
|
* A malformed value breaks compilation for *every* ESP32 sketch on the machine,
|
|
not just this one. If things go strange, delete the file.
|
|
|
|
## 3. Board settings
|
|
|
|
* Board: ESP32 Dev Module (under esp32_bluepad32)
|
|
* Partition Scheme: **Huge APP (3MB No OTA/1MB SPIFFS)**. BTstack with both
|
|
transports plus the GATT client does not fit the default partition table.
|
|
* Upload speed 921600 is fine; drop to 115200 if uploads fail.
|
|
|
|
## 4. Before flashing
|
|
|
|
After creating `platform.local.txt`, fully quit the Arduino IDE — closing the
|
|
sketch window is not enough, it has to re-read the platform — and clear the
|
|
build cache:
|
|
|
|
```powershell
|
|
Remove-Item "$env:LOCALAPPDATA\Temp\arduino\sketches\*" -Recurse -Force -ErrorAction SilentlyContinue
|
|
```
|
|
|
|
Then set your two hub addresses in `HUB_ADDR_STR` at the top of the sketch and
|
|
compile.
|
|
|
|
## 5. First run
|
|
|
|
1. Power both hubs and press their green buttons so they are advertising.
|
|
2. Flash, open Serial Monitor at 115200.
|
|
3. Expect `Connecting hubs, then opening for the gamepad`. Each hub's LED goes
|
|
green as it is claimed.
|
|
4. Once both are up you get `Hubs up - put the PS4 pad in pairing mode`. Hold
|
|
SHARE + PS on the controller until the light bar flashes.
|
|
5. Onboard LED on GPIO2 goes solid when the pad and both hubs are all connected.
|
|
|
|
The order matters and is deliberate: gamepad discovery stays off until the hubs
|
|
are connected, so Bluepad32's inquiry and LE scan are not running at the same
|
|
time as our LE create-connection.
|
|
|
|
## Troubleshooting
|
|
|
|
**A missing header from `btstack/3rd-party`.** Add another `-I` line for that
|
|
directory and redo step 4.
|
|
|
|
**Hubs never connect, no LE connection-complete in the log.** In order of
|
|
likelihood: the hubs went back to sleep (they time out after a couple of minutes
|
|
— press the buttons again); the addresses are wrong; or the address type is
|
|
wrong. For the last one, switch `HUB_ADDR_TYPE` to `BD_ADDR_TYPE_LE_RANDOM`.
|
|
|
|
**One hub connects, the other never does.** Expected if the first one is stuck
|
|
mid-discovery. `serviceHubConnections()` only runs one at a time by design;
|
|
check `gActive` is being released.
|
|
|
|
**Motors stutter, or a hub drops off after a few seconds.** Commands are going
|
|
out faster than the hub can absorb. Raise `MOTOR_MIN_GAP_MS`.
|
|
|
|
**Random crashes at unrelated places.** Almost certainly a BTstack call added to
|
|
`loop()`. BTstack is not thread-safe and `loop()` is not the BTstack thread —
|
|
see the header comment in the sketch.
|
|
|
|
Turn on verbose BTstack logging before guessing at any of it. Nearly every
|
|
failure mode here surfaces as a specific HCI event you can read.
|
|
|
|
---
|
|
|
|
Created by: Jess Rogerson (yelling commands at Claude.AI)
|