Skip to content

Can't Reconnect paired device after power cycling device #2

Closed

Description

@Fedack

When I attempt to reconnect a keyboard that's already been paired with Windows 10, I get this:
Started advertising
Central connected: 0
Central disconnected

Connecting for the first time seems to be fine, but as soon as I do a reset, it doesn't work.

Activity

  1. Heerkog commented on Sep 17, 2021

    @Heerkog
    Owner

    This is odd. You're mentioning a reset. Is this a full power cycle on the keyboard? If so, the Bluetooth might require pairing again.

    Note that this package does not (yet?) support Bluetooth bonding.

  2. Fedack commented on Sep 17, 2021

    @Fedack
    Author
  3. Heerkog commented on Sep 17, 2021

    @Heerkog
    Owner

    I'm assuming you are using my keyboard example and that you're calling d.stop() before calling d.start() for the second time.

    The way this simple keyboard example works is that in the init, it calls self.keyboard.start(), where keyboard is the device from the package. When you call d.stop(), it calls self.keyboard.stop(), which stops all Bluetooth services. When you then call d.start(), it never calls self.keyboard.start() again. If you want this start/stop behavior, I suggest implementing a d.restart() method that first calls self.keyboard.start() and then calls the d.start() loop.

    I hope this solves the issue!

  4. Fedack commented on Sep 17, 2021

    @Fedack
    Author

    The issue I am experiencing is where I reset the device (by pressing the button or unplugging) then it tries to start again but doesn't succeed in reconnecting to Windows.

  5. Heerkog commented on Sep 17, 2021

    @Heerkog
    Owner

    Ok, thanks. I think this is an issue where (somehow) Windows doesn't recognize the device as the same one that was paired earlier. I'm unsure why this is happening. It could be the lack of bonding, but I'm unsure. It could also be another Bluetooth issue. I would need to look into this, but can't promise quick results. As a temporary solution, you could consider starting/stopping the device and putting the device in some deep sleep mode instead of fully power cycling.

  6. Fedack commented on Sep 17, 2021

    @Fedack
    Author

    Thank you for your answers, I'll try to fiddle with it. Hopefully you figure it out.

  7. changed the title [-]Can't Reconnect[/-] [+]Can't Reconnect paired device after power cycle[/+] on Sep 17, 2021
  8. changed the title [-]Can't Reconnect paired device after power cycle[/-] [+]Can't Reconnect paired device after power cycling device[/+] on Sep 17, 2021
  9. Heerkog commented on Sep 22, 2021

    @Heerkog
    Owner

    I have been able to replicate your issue. The issue appears when the bluetooth device is restarted either through a hardware reset or by the software calling stop(), creating a new device, and calling start() for the newly created device.

    The issue is indeed a pairing/bonding issue. as confirmed through this MicroPython issue.

    I have pushed a new version of the package, for which bonding and secure pairing can be enabled, that should work. I say should, because the ESP32 implementation of MicroPython does NOT support this behavior (as confirmed in the linked issue). I own only ESP32 devices and, therefore, can't test properly. Calling methods related to bonding, or secure pairing, on an ESP32 will result in errors. In case your hardware is not an ESP32 device, you may try the code from my latest push and call set_bonding(True) and set_le_secure(True) before calling start() from the package. Please do let me know about the results! In case your device is also an ESP32 device, it seems we will both have to wait until the behavior is supported in a future MicroPython build (if ever).

  10. Fedack commented on Sep 22, 2021

    @Fedack
    Author
  11. Heerkog commented on Sep 22, 2021

    @Heerkog
    Owner

    The MicroPython Bluetooth documentation notes the following under the Pairing and bonding section:

    This is currently only supported when using the NimBLE stack on STM32 and Unix (not ESP32).

    This is all I know.

  12. Fedack commented on Sep 22, 2021

    @Fedack
    Author
  13. jd3096-mpy commented on Jul 26, 2022

    @jd3096-mpy

    Now esp32 micropython supported Pairing and bonding section,I have tested,it worked.
    But esp32 is still can't auto reconnect paired device after power cycling device.
    How to make it work?

  14. Heerkog commented on Jul 26, 2022

    @Heerkog
    Owner

    Now esp32 micropython supported Pairing and bonding section,I have tested,it worked.

    Do you have a source for this information? The documentation still says it's not supported for ESP32.

    But esp32 is still can't auto reconnect paired device after power cycling device. How to make it work?

    Call mouse.set_bonding(True) before mouse.start().

  15. jd3096-mpy commented on Jul 26, 2022

    @jd3096-mpy

    Now esp32 micropython supported Pairing and bonding section,I have tested,it worked.

    Do you have a source for this information? The documentation still says it's not supported for ESP32.

    But esp32 is still can't auto reconnect paired device after power cycling device. How to make it work?

    Call mouse.set_bonding(True) before mouse.start().

    Thanks here is link
    micropython/micropython#7008

  16. 7 remaining items

  17. jd3096-mpy commented on Aug 6, 2024

    @jd3096-mpy

    @Fedack @jd3096-mpy

    I have just pushed a version which allows bonding, solving this issue. Note that it requires MicroPython 1.20+ (tested with 1.23).

    Thanks a lot.
    I test with MicroPython 1.23, it works.

  18. wenwen19115 commented on Sep 4, 2024

    @wenwen19115

    This issue occurs again on MicroPython version 1.24, and the Bluetooth that has been paired before cannot be connected after restarting. Steps: Restart ESP32 and run the keyboard_example.py to print the following data:
    Server created
    get secret: 2 0 None
    get secret: 10 0 b'irk'
    set secret: (10, b'irk') b'\xb0\xd4\xa5|7R\xfd\xef\xa8\x0f\xf3\x9b\xafN\xc3\x08'
    BLE on
    Registering services
    Writing service characteristics
    h_mod = 16 h_ser = 18 h_fwr = 20 h_hwr = 22 h_swr = 24 h_man = 26 h_pnp = 28
    h_bat = 31
    Writing device information service characteristics
    Writing battery service characteristics
    Writing hid service characteristics
    Advertiser created: Keyboard with services: [UUID(0x1812)]
    Server started
    Started advertising
    Central connected: 0
    get secret: 1 0 b'\x00\x16\xa7\xebR\xd2\xd4'
    Central disconnected: 0
    Started advertising
    Central connected: 0
    get secret: 1 0 b'\x00\x16\xa7\xebR\xd2\xd4'
    Central disconnected: 0
    Started advertising
    Central connected: 0
    get secret: 1 0 b'\x00\x16\xa7\xebR\xd2\xd4'
    Central disconnected: 0
    Started advertising
    Central connected: 0
    get secret: 1 0 b'\x00\x16\xa7\xebR\xd2\xd4'
    Central disconnected: 0

  19. Heerkog commented on Sep 4, 2024

    @Heerkog
    Owner

    I've pushed a new version that hopefully fixes the issue.

  20. wenwen19115 commented on Sep 4, 2024

    @wenwen19115

    image
    Hello, there is a grammatical error here, a comma is missing. Also, after I added it, I didn't get an error, but I still can't connect to the paired device.
    Line 938 (h_info, h_hid, _, self.h_rep, _, h_d1, self.h_repout, _ h_d2, h_proto) = handles[2]

  21. Heerkog commented on Sep 4, 2024

    @Heerkog
    Owner

    Can you try with this earlier version?

  22. wenwen19115 commented on Sep 4, 2024

    @wenwen19115

    image
    I tried the version you gave and still have the same problem. I wonder if this has something to do with my micropython version, which is 1.24
    image

  23. Heerkog commented on Sep 4, 2024

    @Heerkog
    Owner

    Could be. I can confirm it works perfectly with version 1.23. Could you try that?

  24. wenwen19115 commented on Sep 4, 2024

    @wenwen19115

    I'll give it a try,thank you!

  25. ctshh commented on Jun 17, 2025

    @ctshh

    I have tried this under Micropython 1.25.0 and, as per your above comments, 1.23.0 (I'm trying to build a BLE interface for my morse key, for a morse-learning app).

    The main micropython script typing the [ and ] characters on a german keyboard layout
    The version of your library I use, as of today the current one
    The keys.json that is saved on the esp after the first connect

    Connections, disconnects and re-connects from the phone to the esp32 work fine as long as the main script is not interrupted, multiple times, all good. As soon as I stop the script and re-start it, or powercycle and start the script, a connection with the same phone does not work. As for the phone, it's an iPhone 13 running iOS 18.5.
    Connections to "real" keyboards, aka. typie-typie things, work fine, as do other BLE peripherals.

    Is there a way to check if the keys.json is read and used after stopping and re-starting the script?

    Maybe this helps in a way, and hopefully I'm not exposing any data in the keys.json I shouldn't have. Thank you for your work on this library so far, I appreciate it!
    If I can help out with more debug info (I'm afraid, only from the esp side, thank you very much Apple...), please let me know.

  26. ThomasAtBBTF commented on Jul 27, 2025

    @ThomasAtBBTF

    Connections, disconnects, and re-connects from the phone to the ESP32 work fine as long as the main script is not interrupted multiple times, all good. As soon as I stop the script and restart it, or power cycle and start the script, a connection with the same phone does not work. As for the phone, it's an iPhone 13 running iOS 18.5. Connections to "real" keyboards, aka typie-typie things, work fine, as do other BLE peripherals.

    I had the same problem, and I figured out that data written to the filesystem on an ESP32S3 does not "survive" a reset or power cycle.
    To fix this, I store the data in:

    import esp32
    # --- nvs paths ---
    nvsname = "keys.json"
    nvsdata = esp32.NVS(nvsname)
    def save_data_to_nvs(key, value):
        print("-" * 20)
        value_bytes = value.encode('utf-8')
        value_size = len(value_bytes)
        print(f"save_data_to_nvs under key:{key} value_size:{value_size} bytes for {value}")
        max_size = 1024
        try:
            nvsdata.set_i32(key+"_max", max_size)
        except Exception as e:
            print(f"Error setting max_size: {e} into key:{key+"_max"} as {max_size}")
        if value_size > max_size:
            print(f"value_size > max_size {value_size} > {max_size}")
            value_size += 1024
            nvsdata.set_i32(key+"_max", value_size)
            print(f"saving {key+"_max"} as {value_size}")
        nvsdata.set_blob(key+"_data", value_bytes)
        print(f"Data saved to {key+"_data"} as {value_bytes}.")
        print("-" * 20)
    
    
    def load_data_from_nvs(key) -> str:
        print("-" * 20)
        value_str = ""
        print(f"load_data_from_nvs under key:{key}")
        max_size = 1024
        try:
            max_size = nvsdata.get_i32(key + "_max") + 1024
        except Exception as e:
            print(f"Error loading max size: {e}")
        value_bytes = bytearray(max_size)
        print(f"using max_size of {max_size} bytes")
        try:
            bytes_read = nvsdata.get_blob(key+"_data", value_bytes)
            print(f"read {bytes_read} bytes")
            if bytes_read > 0:
                value_str = value_bytes[:bytes_read].decode('utf-8')
                print(f"String retrieved: '{value_str}'")
            else:
                print("Blob found, but it contained no data.")
        except Exception as e:
            print(f"Error: {e} key:{key+"_data"}")
        print("-" * 20)
        return value_str
     
    

    I made it so "complicated" because I have no idea how big the secret data can become....
    Using the file system does not seem to be a good choice for ESP32 boards.

    Note: I ran into problems with too-long key names.
    Try to use keys not longer than five characters.

  27. Heerkog commented on Jul 28, 2025

    @Heerkog
    Owner

    @ThomasAtBBTF
    Should there not be a commit?

  28. ThomasAtBBTF commented on Jul 28, 2025

    @ThomasAtBBTF

    I am not sure...
    I worked a lot on your project and also changed a lot for my project / product ...
    I am not so familiar in working in GitHub and drive a project further.
    I will send you a PM so we can discuss the best way to move on.

  29. Heerkog commented on Jul 29, 2025

    @Heerkog
    Owner

    @ThomasAtBBTF I have updated the code with the keyboard input report fix and optional NVS storage.

    Please use before calling start:

    from hid_keystores import NVSKeyStore
    
    ks = NVSKeyStore()
    self.keyboard.set_keystore(ks)
    

    Thank you very much for your work!

  30. Heerkog commented on Aug 5, 2025

    @Heerkog
    Owner

    @ThomasAtBBTF Have you been able to try the new version?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions