Become a leader in the IoT community!

New DevHeads get a 320-point leaderboard boost when joining the DevHeads IoT Integration Community. In addition to learning and advising, active community leaders are rewarded with community recognition and free tech stuff. Start your Legendary Collaboration now!

Step 1 of 5

CREATE YOUR PROFILE *Required

OR
Step 2 of 5

WHAT BRINGS YOU TO DEVHEADS? *Choose 1 or more

Collaboration & Work 🤝
Learn & Grow 📚
Contribute Experience & Expertise 🔧
Step 3 of 5

WHAT'S YOUR INTEREST OR EXPERTISE? *Choose 1 or more

Hardware & Design 💡
Embedded Software 💻
Edge Networking
Step 4 of 5

Personalize your profile

Step 5 of 5

Read & agree to our COMMUNITY RULES

  1. We want this server to be a welcoming space! Treat everyone with respect. Absolutely no harassment, witch hunting, sexism, racism, or hate speech will be tolerated.
  2. If you see something against the rules or something that makes you feel unsafe, let staff know by messaging @admin in the "support-tickets" tab in the Live DevChat menu.
  3. No age-restricted, obscene or NSFW content. This includes text, images, or links featuring nudity, sex, hard violence, or other graphically disturbing content.
  4. No spam. This includes DMing fellow members.
  5. You must be over the age of 18 years old to participate in our community.
  6. Our community uses Answer Overflow to index content on the web. By posting in this channel your messages will be indexed on the worldwide web to help others find answers.
  7. You agree to our Terms of Service (https://www.devheads.io/terms-of-service/) and Privacy Policy (https://www.devheads.io/privacy-policy)
By clicking "Finish", you have read and agreed to the our Terms of Service and Privacy Policy.

How to convert relative cursor movement to absolute position for BLE HID using Zephyr?

Hey @MCU, MPU & Firmware @Helper Guys, i have a slight logic problem,
So i built a BLE HID device using zephyr which tags input from a console and send BLE HID packets to the connected device
All well and good…for now
The problem arises here, where the HID report is based of the relative position of the cursor, but my client requires a way to give it through Absolute position of a device(Main eg: phone)

Could anyone help how we can give absolute movement from relative movement(Even external(PC based) code implementation is Okay)

My HID report is

0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */
0x09, 0x02, /* Usage (Mouse) */
0xA1, 0x01, /* Collection (Application) */
0x85, 0x01, /* Report Id (1) */
0x09, 0x01, /* Usage (Pointer) */
0xA1, 0x00, /* Collection (Physical) */
0x05, 0x09, /* Usage Page (Button) */
0x19, 0x01, /* Usage Minimum (0x01) */
0x29, 0x03, /* Usage Maximum (0x03) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x95, 0x03, /* Report Count (3) */
0x75, 0x01, /* Report Size (1) */
0x81, 0x02, /* Input (Data,Var,Abs,No Wrap,Linear,…) */
0x95, 0x01, /* Report Count (1) */
0x75, 0x05, /* Report Size (5) */
0x81, 0x03, /* Input (Const,Var,Abs,No Wrap,Linear,…) */
0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */
0x09, 0x30, /* Usage (X) */
0x09, 0x31, /* Usage (Y) */
0x15, 0x81, /* Logical Minimum (129) */
0x25, 0x7F, /* Logical Maximum (127) */
0x75, 0x08, /* Report Size (8) */
0x95, 0x02, /* Report Count (2) */
0x81, 0x06, /* Input (Data,Var,Rel,No Wrap,Linear,…) */ {I have tried 0x81, 0x02 for Abs but it didnt register in my phone as a HID device for some reason}
0xC0, /* End Collection */
0xC0, /* End Collection */

  1. Nayel#0000

    which software are you using

  2. melta101#0000

    The RTOS i am using is Zephyr

  3. melta101#0000

    Any help and clarifications needed are welcome!

  4. Nayel#0000

    To convert relative movement to absolute positioning for your BLE HID device, you’ll need to make a few changes to both your HID report descriptor and your firmware implementation. Here’s how you can approach this:
    Modify the HID report descriptor:
    Change the X and Y input fields to absolute positioning by modifying these lines:

  5. Nayel#0000

    This changes the X and Y fields to 16-bit absolute values with a range of 0-32767.
    Update your firmware implementation:
    You’ll need to maintain the current cursor position in your device’s memory. When you receive input from the console, instead of sending relative movement, you’ll send the new absolute position.
    Here’s a basic example of how you might implement this in your firmware:

  6. Nayel#0000

    “`
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #define SCREEN_WIDTH 32768
    #define SCREEN_HEIGHT 32768

    struct hid_report {
    uint8_t buttons;
    uint16_t x;
    uint16_t y;
    } __packed;

    static struct hid_report report = {0};

    void update_cursor_position(int16_t dx, int16_t dy) {
    // Update absolute position based on relative movement
    report.x = MIN(MAX(report.x + dx, 0), SCREEN_WIDTH – 1);
    report.y = MIN(MAX(report.y + dy, 0), SCREEN_HEIGHT – 1);

    // Send the updated report
    bt_gatt_notify(NULL, &hid_svc.attrs[2], &report, sizeof(report));
    }

    void set_cursor_position(uint16_t x, uint16_t y) {
    report.x = MIN(x, SCREEN_WIDTH – 1);
    report.y = MIN(y, SCREEN_HEIGHT – 1);

    // Send the updated report
    bt_gatt_notify(NULL, &hid_svc.attrs[2], &report, sizeof(report));
    }
    “`
    In this example, update_cursor_position takes relative movement as input and updates the absolute position, while set_cursor_position allows you to set the absolute position directly.
    Handling phone compatibility:
    If your phone isn’t recognizing the device with absolute positioning, you might need to add a physical (x, y) min/max to your descriptor:
    “`
    0x35, 0x00, // Physical Minimum (0)
    0x46, 0xFF, 0x7F, // Physical Maximum (32767)
    “`
    Add these lines just before the Logical Minimum and Maximum in your descriptor.
    Calibration:
    You’ll need to implement a calibration process to map the phone’s screen dimensions to your 0-32767 range. This could involve having the user touch specific points on the screen and adjusting your coordinates accordingly.

  7. Nayel#0000

    I’m really not an expert but it should help

  8. melta101#0000

    Interesting!
    Lemme implement this n let yk furthur
    Thanks for your time mate!

  9. melta101#0000

    I have a few doubts
    if we are setting this HID report to abs, why should we implement the below functions, as they seems to be converting relative to abs
    BTW,
    I have tried HID format change
    but after getting connected, it doesnt seem to move the cursor

  10. Nayel#0000

    Absolute vs. Relative Positioning:
    If you’ve set up your HID report for absolute positioning, you’re correct that you shouldn’t need to convert from relative to absolute movements. The functions I provided earlier were indeed more suited for a hybrid approach, which isn’t necessary if you’re fully committed to absolute positioning.

  11. Nayel#0000

    for the cursor : you have to ensure your HID report is being sent correctly with the new format.
    and then Verify that the absolute values you’re sending are within the range you specified in the descriptor (0 to 32767 in the example).
    note that Some devices might expect different ranges or additional information in the HID report for absolute positioning.

  12. Nayel#0000

    “`struct hid_report {
    uint8_t buttons;
    uint16_t x;
    uint16_t y;
    } __packed;

    static struct hid_report report = {0};

    void set_cursor_position(uint16_t x, uint16_t y) {
    report.x = x;
    report.y = y;

    // Send the updated report
    bt_gatt_notify(NULL, &hid_svc.attrs[2], &report, sizeof(report));
    }“`

  13. melta101#0000

    Hmm,
    Still the same
    Connects but doesnt send the mouse commands

  14. Nayel#0000

    Hmmm… weird

CONTRIBUTE TO THIS THREAD

Browse other Product Reviews tagged

Leaderboard

RANKED BY XP

All time
  • 1.
    Avatar
    @Nayel115
    1620 XP
  • 2.
    Avatar
    @UcGee
    650 XP
  • 3.
    Avatar
    @melta101
    600 XP
  • 4.
    Avatar
    @lifegochi
    250 XP
  • 5.
    Avatar
    @Youuce
    180 XP
  • 6.
    Avatar
    @hemalchevli
    170 XP