Skip to content

Conversation

@Sighery
Copy link

@Sighery Sighery commented Feb 7, 2026

This allows for getting the raw SpO2, PPG and accelerometer data from the ring. Tested on a Colmi R02.

I'm no C dev so feel free to change my struct definitions/sample code to make it more idiomatic if needed 👍

@Sighery Sighery force-pushed the main branch 2 times, most recently from b4392bc to 4ae3056 Compare February 7, 2026 18:15
@Puxtril
Copy link
Owner

Puxtril commented Feb 8, 2026

Thanks for submitting this! All the C syntax looks good to me. And the decode examples are a nice addition.

I'm tempted to list all 4 SPO2 values as big endian 16-bit integers (Seems like that would be the case), but I cannot find that request in the decompiled QRing app so I can't confirm that's the case. Are you able to confirm?

@Sighery
Copy link
Author

Sighery commented Feb 9, 2026

Hey, so, I'm not using the Android app at all. That's why I was interested in hearing how you reversed all these commands, because maybe I could find more stuff that would be useful to me. I used your website + the other repo I link in the PR as reference code for my project. Which is remote page turns on Kindles using the ring through Bluetooth for gestures. I can confirm that I am getting this data and parsing it on the Kindle:

There is some weird thing going on with the SpO2 and PPG data, so far in my short few tests I've done now (I honestly wasn't even parsing it before because I'm only interested in accelerometer data), the data itself seems stuck. But I've also noticed a similar thing with the accelerometer data a few times, where it wouldn't change no matter how much I moved the ring, but would after I reconnected. My guess is there's just something with my parsing code and/or Kindle Bluetooth stack which is not great (I also had to reverse that). But overall I can confirm the command exists, and it returns data after you request that command.

My project and relevant (Go) code is open source. Here is my parsing logic. Here some tests I've written with the data and expected parse result (honestly still not 100% sure I've implemented the parsing correctly, I still struggle with big-endian/little-endian and bit shift operations in my head). And here the relevant bit from the main function that enables/disables the raw sensors and signs up for notifications. Sadly there is no easy way to run/share this since Kindles use a super old kernel so it requires a whole annoying C toolchain to build anything, and then you need one of these devices since there's no public emulators (I'm sure Amazon have an internal one, but nothing the community has access to/has developed).

That being said, you should be able to get the data on your Colmi R03 as well with the bit of Python code from the reference repo, or really any BLE tool out there. As long as you get the packet response once you sign up for the notifications, you can pass that result into any bit of code on any language to do the bit shift calculations.

This allows for getting the raw SpO2, PPG and accelerometer data from
the ring. Tested on a Colmi R02.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants