Closed sorgelig closed 3 years ago
Inside VSCode, in PlatformIO main page, click "Import Arduino Project", select "Espressif ESP32 Dev Module" as the dev board and select the repo folder. Toolchain will be downloaded and you'll be ready for building and flashing it.
I will improve instructions in the README. Let me know if you still have questions.
stupid question, but how to compile and upload to module?
Yes, it's not very intuitive, but after you have the project imported and opened, there should be a small toolbar in the lower left corner with the options to build and upload:
Success! Thanks for guiding. I'm using this board: https://www.amazon.com/gp/product/B082216QGR I didn't connect anything to it yet. Just uploaded the firmware and MiSTer found it.
There are some questions on usage: Probably need some button to initiate pairing even if it's paired. Not sure if NimBLE supports pairing with several hosts, so any available paired host will be connected. I found it's useful if i want to switch between 2 MiSTer's without re-pairing. There are 2 LEDs on board - probably they use other GPIO than your board but anyway it's good to have LED which will indicate BLE state: solid - connected, slow blink - searching for host/connecting, fast blinking - pairing mode.
My pleasure!
When turning on, it will be in pairing mode and led blinking (it depends on the GPIO your board uses for the LED). After paired, solid led. I think it supports pairing to multiple devices, but I've never tried it. Maybe by calling NimBLEDevice::startAdvertising();
at the end of the onConnect callback will do it? Let me know!
gpio 22 on my board is LED. So now it blinks. And it already supports multi-host pair! No need to change anything. This is great!
Now i will study the code interacting with HID. I will remove second joystick and will see how it will support SNES NTT gamepad. This is one of gamepads i want to convert to wireless. I'm not sure how much current ESP32 code is tweaked for sleep mode.. I think module should go to low power mode when no buttons are pressed for some time, then go to deep sleep after additional timeout.
Awesome!
Please let me know if you figure how sleeping works and how does it affect (?) latency so I can add it to the current code.
As for the HID reports, this full map to a PS1/PS2 controller will give you an idea of every bit of it:
// D-Pad HAT
ble_p1_data[4] = digital_dir_lookup[p1->d_up << 3 | p1->d_down << 2 | p1->d_left << 1 |
p1->d_right];
// Digital buttons
p1->start ? bitSet(ble_p1_data[5], 5) : bitClear(ble_p1_data[5], 5);
p1->r3 ? bitSet(ble_p1_data[5], 7) : bitClear(ble_p1_data[5], 7);
p1->l3 ? bitSet(ble_p1_data[5], 6) : bitClear(ble_p1_data[5], 6);
p1->select ? bitSet(ble_p1_data[5], 4) : bitClear(ble_p1_data[5], 4);
p1->square ? bitSet(ble_p1_data[4], 7) : bitClear(ble_p1_data[4], 7);
p1->cross ? bitSet(ble_p1_data[4], 6) : bitClear(ble_p1_data[4], 6);
p1->circle ? bitSet(ble_p1_data[4], 5) : bitClear(ble_p1_data[4], 5);
p1->triangle ? bitSet(ble_p1_data[4], 4) : bitClear(ble_p1_data[4], 4);
p1->r1 ? bitSet(ble_p1_data[5], 3) : bitClear(ble_p1_data[5], 3);
p1->l1 ? bitSet(ble_p1_data[5], 2) : bitClear(ble_p1_data[5], 2);
p1->r2 ? bitSet(ble_p1_data[5], 3) : bitClear(ble_p1_data[5], 1);
p1->l2 ? bitSet(ble_p1_data[5], 2) : bitClear(ble_p1_data[5], 0);
// Analog Axis
ble_p1_data[2] = p1->l_x;
ble_p1_data[3] = p1->l_y;
ble_p1_data[1] = p1->r_x;
ble_p1_data[0] = p1->r_y;
with full power on as of now, it draws 80ma. I think it's quite high consumption. I'm waiting for another board which is supposed to be tuned for low power consumption, so will measure there to see if it's different. there is another problem SNES gamepad uses 5V. Schematic is pretty simple - just 3 shifting registers.. Interesting if they will work on 2.5-3.3v power supply.
SNES pads are tolerant and work pretty well with 3v3. Never tried a NTT though. I wonder if there's some special instruction that could be added to the main loop when there are no button changes that could lower consumption? I didn't personally look into this, but I would say there's something that could help in that sense without putting the uC in deep hibernation.
NTT is pretty much the same as normal SNES gamepad with only additional ~15 buttons, so it uses additional shift register(s). It easy to detect that no buttons are pressed within some time, then put into lower state (i don't know if there is such state when BT is still working). Buttons can be scanned by slower speed. If button press is detected then go out from low power mode immediately and work normally. So if even latency happens then only by first button press which is fine. Timeout can be for example 30seconds. Usually with active play any button gets pressed withing this time. It may also depend on specific board. It's important that USB-Serial chip stay unpowered if no USB connected. Power led probably should be deslodered. BT activity LED should be a low light and low powered. Many boards tend to use high powered bright leds.
may be this info can be useful: https://github.com/espressif/esp-idf/issues/947#issuecomment-500312453
TinyPICO has similar consumption 73-76ma
After playing with ULP and deep sleep modes i could achieve at least deep sleep mode after timeout with (BT off of course) with 170 uA. ESP32 wakes up an connect on any button press on SNES NTT gamepad which allows to use ESP32 on battery without power switch. Light Sleep mode with BT enabled requires additional external xtal 32768 (which isn't a problem) and specially compiled ESP32 libs which isn't easy..
Hey, thanks for sharing your findings! For the software part, maybe is that a good idea to open a PR for the NimBLE Arduino library with the changes for allowing light sleep?
from link above, changes are inside ESP BSP, not in NimBLE. All required options are inside BSP, so it's up to configuration before compilation.
And since ULP compiler integration exists only for Arduino IDE, i moved the project there.
Installing vscode + platformio instruction can be found on PlatformIO site, but rest one like ESP32 and Arduino integration is unclear.